[clang] [HLSL][LongVec] Add more intrinsic support (PR #222043)

Farzon Lotfi via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 8 11:59:31 PDT 2026


https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/222043

>From 836361fd661e00af8aa65dae9853122c22e4020f Mon Sep 17 00:00:00 2001
From: Farzon Lotfi <farzonlotfi at microsoft.com>
Date: Thu, 3 Sep 2026 16:59:07 -0400
Subject: [PATCH 1/2] [HLSL][LongVec] Add more intrinsic support

resolves #220699
resolves #220655
resolves #220639
resolves #220638
resolves #220614
---
 clang/include/clang/Basic/HLSLIntrinsics.td   |  5 +++++
 clang/test/CodeGenHLSL/builtins/asdouble.hlsl | 12 ++++++++++++
 clang/test/CodeGenHLSL/builtins/ddx.hlsl      |  7 +++++++
 clang/test/CodeGenHLSL/builtins/ddy.hlsl      |  7 +++++++
 clang/test/CodeGenHLSL/builtins/ldexp.hlsl    |  6 ++++++
 clang/test/CodeGenHLSL/builtins/mad.hlsl      |  7 +++++++
 6 files changed, 44 insertions(+)

diff --git a/clang/include/clang/Basic/HLSLIntrinsics.td b/clang/include/clang/Basic/HLSLIntrinsics.td
index ecf7c3df31fe8..21c0960b6fa23 100644
--- a/clang/include/clang/Basic/HLSLIntrinsics.td
+++ b/clang/include/clang/Basic/HLSLIntrinsics.td
@@ -427,6 +427,7 @@ def hlsl_asdouble : HLSLTwoArgBuiltin<"asdouble", "__builtin_hlsl_asdouble"> {
 }];
   let ReturnType = VaryingShape<DoubleTy>;
   let VaryingTypes = [UIntTy];
+  let VaryingLongVector = 1;
   let VaryingMatDims = [];
 }
 
@@ -600,6 +601,7 @@ the screen-space x-coordinate.
 }];
   let ParamNames = ["input"];
   let VaryingTypes = [HalfTy, FloatTy];
+  let VaryingLongVector = 1;
   let VaryingMatDims = [];
 }
 
@@ -649,6 +651,7 @@ the screen-space y-coordinate.
 }];
   let ParamNames = ["input"];
   let VaryingTypes = [HalfTy, FloatTy];
+  let VaryingLongVector = 1;
   let VaryingMatDims = [];
 }
 
@@ -1141,6 +1144,7 @@ This function uses the following formula: X * 2^Exp
   let VaryingTypes = [HalfTy, FloatTy];
   let VaryingScalar = 1;
   let VaryingVecSizes = [2, 3, 4];
+  let VaryingLongVector = 1;
   let VaryingMatDims = [];
 }
 
@@ -1264,6 +1268,7 @@ def hlsl_mad : HLSLThreeArgBuiltin<"mad", "__builtin_hlsl_mad"> {
 }];
   let VaryingTypes = AllNumericTypes;
   let VaryingMatDims = [];
+   let VaryingLongVector = 1;
 }
 
 // Returns the greater of X and Y.
diff --git a/clang/test/CodeGenHLSL/builtins/asdouble.hlsl b/clang/test/CodeGenHLSL/builtins/asdouble.hlsl
index e73f9ad35ebe2..2753b416d7440 100644
--- a/clang/test/CodeGenHLSL/builtins/asdouble.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/asdouble.hlsl
@@ -35,3 +35,15 @@ double3 test_vuint(uint3 low, uint3 high) {
 }
 
 // CHECK-DXIL: declare <3 x double> @llvm.dx.asdouble.v3i32
+
+// CHECK-LABEL: test_vuint5
+vector<double, 5> test_vuint5(vector<uint, 5> low, vector<uint, 5> high) {
+  // CHECK-SPV:      %[[SHUFFLE2:.*]] = shufflevector
+  // CHECK-SPV-SAME: {{.*}} <i32 0, i32 5, i32 1, i32 6, i32 2, i32 7, i32 3, i32 8, i32 4, i32 9>
+  // CHECK-SPV:      bitcast <10 x i32> %[[SHUFFLE2]] to <5 x double>
+
+  // CHECK-DXIL: call reassoc nnan ninf nsz arcp afn <5 x double> @llvm.dx.asdouble.v5i32
+  return asdouble(low, high);
+}
+
+// CHECK-DXIL: declare <5 x double> @llvm.dx.asdouble.v5i32
diff --git a/clang/test/CodeGenHLSL/builtins/ddx.hlsl b/clang/test/CodeGenHLSL/builtins/ddx.hlsl
index e673e1985dd60..7ec896ee27851 100644
--- a/clang/test/CodeGenHLSL/builtins/ddx.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/ddx.hlsl
@@ -60,3 +60,10 @@ float3 test_f32_ddx3(float3 val) {
 float4 test_f32_ddx4(float4 val) {
     return ddx(val);
 }
+
+// CHECK-LABEL: define {{.*}} <5 x float> @_ZN4hlsl8__detail8ddx_impl
+// CHECK: %[[VAR]] = call {{.*}} <5 x float> @llvm.[[CALL]].v5f32(<5 x float> %{{.*}})
+// CHECK: ret <5 x float> %[[VAR]]
+vector<float, 5> test_f32_ddx5(vector<float, 5> val) {
+    return ddx(val);
+}
diff --git a/clang/test/CodeGenHLSL/builtins/ddy.hlsl b/clang/test/CodeGenHLSL/builtins/ddy.hlsl
index 80d75ca7b22c3..d330d589e918b 100644
--- a/clang/test/CodeGenHLSL/builtins/ddy.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/ddy.hlsl
@@ -60,3 +60,10 @@ float3 test_f32_ddy3(float3 val) {
 float4 test_f32_ddy4(float4 val) {
     return ddy(val);
 }
+
+// CHECK-LABEL: define {{.*}} <5 x float> @_ZN4hlsl8__detail8ddy_impl
+// CHECK: %[[VAR]] = call {{.*}} <5 x float> @llvm.[[CALL]].v5f32(<5 x float> %{{.*}})
+// CHECK: ret <5 x float> %[[VAR]]
+vector<float, 5> test_f32_ddy5(vector<float, 5> val) {
+    return ddy(val);
+}
diff --git a/clang/test/CodeGenHLSL/builtins/ldexp.hlsl b/clang/test/CodeGenHLSL/builtins/ldexp.hlsl
index 2c0458d079027..170c635e99b61 100644
--- a/clang/test/CodeGenHLSL/builtins/ldexp.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/ldexp.hlsl
@@ -47,3 +47,9 @@ float3 test_ldexp_float3(float3 X, float3 Exp) { return ldexp(X, Exp); }
 // CHECK: [[MUL:%.*]] = fmul reassoc nnan ninf nsz arcp afn <4 x float> [[EXP2]], %{{.*}}
 // CHECK: ret <4 x float> [[MUL]]
 float4 test_ldexp_float4(float4 X, float4 Exp) { return ldexp(X, Exp); }
+
+// CHECK-LABEL: define linkonce_odr hidden noundef nofpclass(nan inf) <5 x float> @_ZN4hlsl5ldexp
+// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <5 x float> @llvm.exp2.v5f32(<5 x float> %{{.*}})
+// CHECK: [[MUL:%.*]] = fmul reassoc nnan ninf nsz arcp afn <5 x float> [[EXP2]], %{{.*}}
+// CHECK: ret <5 x float> [[MUL]]
+vector<float, 5> test_ldexp_float5(vector<float, 5> X, vector<float, 5> Exp) { return ldexp(X, Exp); }
diff --git a/clang/test/CodeGenHLSL/builtins/mad.hlsl b/clang/test/CodeGenHLSL/builtins/mad.hlsl
index d982ecba848e2..8ee6d3aac2185 100644
--- a/clang/test/CodeGenHLSL/builtins/mad.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/mad.hlsl
@@ -140,6 +140,13 @@ float3 test_mad_float3(float3 p0, float3 p1, float3 p2) { return mad(p0, p1, p2)
 // CHECK: ret <4 x float> %hlsl.fmad
 float4 test_mad_float4(float4 p0, float4 p1, float4 p2) { return mad(p0, p1, p2); }
 
+// CHECK: %[[p0:.*]] = load <5 x float>, ptr %p0.addr
+// CHECK: %[[p1:.*]] = load <5 x float>, ptr %p1.addr
+// CHECK: %[[p2:.*]] = load <5 x float>, ptr %p2.addr
+// CHECK: %hlsl.fmad = call reassoc nnan ninf nsz arcp afn <5 x float> @llvm.fmuladd.v5f32(<5 x float> %[[p0]], <5 x float> %[[p1]], <5 x float> %[[p2]])
+// CHECK: ret <5 x float> %hlsl.fmad
+vector<float, 5> test_mad_float5(vector<float, 5> p0, vector<float, 5> p1, vector<float, 5> p2) { return mad(p0, p1, p2); }
+
 // CHECK: %[[p0:.*]] = load double, ptr %p0.addr
 // CHECK: %[[p1:.*]] = load double, ptr %p1.addr
 // CHECK: %[[p2:.*]] = load double, ptr %p2.addr

>From c5a3150a366fcdd99fb59c51c927d2afbb9bfafc Mon Sep 17 00:00:00 2001
From: Farzon Lotfi <farzonlotfi at microsoft.com>
Date: Tue, 8 Sep 2026 14:56:08 -0400
Subject: [PATCH 2/2] add missing test change

---
 clang/test/SemaHLSL/BuiltIns/ldexp-errors.hlsl | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/clang/test/SemaHLSL/BuiltIns/ldexp-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/ldexp-errors.hlsl
index ce15550d7884b..e269918d85938 100644
--- a/clang/test/SemaHLSL/BuiltIns/ldexp-errors.hlsl
+++ b/clang/test/SemaHLSL/BuiltIns/ldexp-errors.hlsl
@@ -16,11 +16,3 @@ float1 test_vec1_inputs(float1 p0, float1 p1) {
   return ldexp(p0, p1);
   // expected-warning at -1 2 {{implicit conversion turns vector to scalar: 'float1' (aka 'vector<float, 1>') to 'float'}}
 }
-
-typedef float float5 __attribute__((ext_vector_type(5)));
-
-float5 test_vec5_inputs(float5 p0, float5 p1) {
-  return ldexp(p0, p1);
-  // expected-error at -1  {{call to 'ldexp' is ambiguous}}
-  // expected-note at hlsl/hlsl_inline_intrinsics_gen.inc:* 4 {{candidate function}}
-}



More information about the cfe-commits mailing list