[clang] [llvm] [hlsl][dxil][spirv] Add `fma` function (PR #185304)

via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 9 22:58:58 PDT 2026


================
@@ -0,0 +1,151 @@
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -DTEST_DXIL \
+// RUN:   -fmatrix-memory-layout=row-major -emit-llvm -disable-llvm-passes -o - | \
+// RUN:   FileCheck %s --check-prefixes=CHECK,DXIL_CHECK -DTARGET=dx
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN:   spirv-unknown-vulkan-compute %s -DTEST_SPIRV \
+// RUN:   -fmatrix-memory-layout=row-major -emit-llvm -disable-llvm-passes -o - | \
+// RUN:   FileCheck %s --check-prefixes=CHECK,SPIRV_CHECK -DTARGET=spv
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN:   spirv-unknown-vulkan-compute %s -DTEST_SPIRV_HALF -fnative-half-type \
+// RUN:   -fmatrix-memory-layout=row-major -emit-llvm -disable-llvm-passes -o - | \
+// RUN:   FileCheck %s --check-prefix=SPIRV_HALF_CHECK
+
+// CHECK-LABEL: define {{.*}} double @{{.*}}fma_double{{.*}}(
+// CHECK: %[[P0:.*]] = load double, ptr %{{.*}}, align 8
+// CHECK: %[[P1:.*]] = load double, ptr %{{.*}}, align 8
+// CHECK: %[[P2:.*]] = load double, ptr %{{.*}}, align 8
+// CHECK: %{{dx|spv}}.fma = call reassoc nnan ninf nsz arcp afn double @llvm.[[TARGET]].fma.f64(double %[[P0]], double %[[P1]], double %[[P2]])
+// CHECK: ret double %{{dx|spv}}.fma
+double dxil_fma_double(double a, double b, double c) { return fma(a, b, c); }
+
+// CHECK-LABEL: define {{.*}} <2 x double> @{{.*}}fma_double2{{.*}}(
+// CHECK: %[[P0:.*]] = load <2 x double>, ptr %{{.*}}, align 16
+// CHECK: %[[P1:.*]] = load <2 x double>, ptr %{{.*}}, align 16
+// CHECK: %[[P2:.*]] = load <2 x double>, ptr %{{.*}}, align 16
+// CHECK: %{{dx|spv}}.fma = call reassoc nnan ninf nsz arcp afn <2 x double> @llvm.[[TARGET]].fma.v2f64(<2 x double> %[[P0]], <2 x double> %[[P1]], <2 x double> %[[P2]])
+// CHECK: ret <2 x double> %{{dx|spv}}.fma
+double2 dxil_fma_double2(double2 a, double2 b, double2 c) { return fma(a, b, c); }
+
+// CHECK-LABEL: define {{.*}} <3 x double> @{{.*}}fma_double3{{.*}}(
+// CHECK: %[[P0:.*]] = load <3 x double>, ptr %{{.*}}, align 32
+// CHECK: %[[P1:.*]] = load <3 x double>, ptr %{{.*}}, align 32
+// CHECK: %[[P2:.*]] = load <3 x double>, ptr %{{.*}}, align 32
+// CHECK: %{{dx|spv}}.fma = call reassoc nnan ninf nsz arcp afn <3 x double> @llvm.[[TARGET]].fma.v3f64(<3 x double> %[[P0]], <3 x double> %[[P1]], <3 x double> %[[P2]])
+// CHECK: ret <3 x double> %{{dx|spv}}.fma
+double3 dxil_fma_double3(double3 a, double3 b, double3 c) { return fma(a, b, c); }
+
+// CHECK-LABEL: define {{.*}} <4 x double> @{{.*}}fma_double4{{.*}}(
+// CHECK: %[[P0:.*]] = load <4 x double>, ptr %{{.*}}, align 32
+// CHECK: %[[P1:.*]] = load <4 x double>, ptr %{{.*}}, align 32
+// CHECK: %[[P2:.*]] = load <4 x double>, ptr %{{.*}}, align 32
+// CHECK: %{{dx|spv}}.fma = call reassoc nnan ninf nsz arcp afn <4 x double> @llvm.[[TARGET]].fma.v4f64(<4 x double> %[[P0]], <4 x double> %[[P1]], <4 x double> %[[P2]])
+// CHECK: ret <4 x double> %{{dx|spv}}.fma
+double4 dxil_fma_double4(double4 a, double4 b, double4 c) { return fma(a, b, c); }
+
+#ifdef TEST_DXIL
+
+// DXIL_CHECK-LABEL: define {{.*}} <4 x double> @{{.*}}dxil_fma_double1x4{{.*}}(
+// DXIL_CHECK: %dx.fma = call reassoc nnan ninf nsz arcp afn <4 x double> @llvm.dx.fma.v4f64(
+// DXIL_CHECK: ret <4 x double> %dx.fma
+double1x4 dxil_fma_double1x4(double1x4 a, double1x4 b, double1x4 c) { return fma(a, b, c); }
----------------
NeKon69 wrote:

Well yes but isn't it just llvm specific trick that it treats matrices as vectors in this case?

I'm not really experienced with llvm nor spirv, but I want to understand where I'm wrong here..

https://github.com/llvm/llvm-project/pull/185304


More information about the cfe-commits mailing list