https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/222043
>From 4ee922688f5a015961d6b928648be6195bc80fc1 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi <[email protected]> Date: Thu, 3 Sep 2026 16:59:07 -0400 Subject: [PATCH 1/5] [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 dede60edddffcf6f22bd53c1f90e70eedbc70951 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi <[email protected]> Date: Tue, 8 Sep 2026 14:56:08 -0400 Subject: [PATCH 2/5] 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@-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@-1 {{call to 'ldexp' is ambiguous}} - // expected-note@hlsl/hlsl_inline_intrinsics_gen.inc:* 4 {{candidate function}} -} >From 44ff277aa60f3571460f9f0a60abb97ef5232af0 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi <[email protected]> Date: Tue, 15 Sep 2026 11:48:10 -0400 Subject: [PATCH 3/5] update mad to have check labels --- clang/test/CodeGenHLSL/builtins/mad.hlsl | 40 +++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/clang/test/CodeGenHLSL/builtins/mad.hlsl b/clang/test/CodeGenHLSL/builtins/mad.hlsl index 8ee6d3aac2185..f7ea6232856e6 100644 --- a/clang/test/CodeGenHLSL/builtins/mad.hlsl +++ b/clang/test/CodeGenHLSL/builtins/mad.hlsl @@ -15,48 +15,57 @@ // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF,SPIR_CHECK #ifdef __HLSL_ENABLE_16_BIT + +// CHECK-LABEL: test_mad_uint16_t // DXIL_NATIVE_HALF: %dx.umad = call i16 @llvm.dx.umad.i16(i16 %[[#]], i16 %[[#]], i16 %[[#]]) // DXIL_NATIVE_HALF: ret i16 %dx.umad // SPIR_NATIVE_HALF: mul nuw i16 %{{.*}}, %{{.*}} // SPIR_NATIVE_HALF: add nuw i16 %{{.*}}, %{{.*}} uint16_t test_mad_uint16_t(uint16_t p0, uint16_t p1, uint16_t p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_uint16_t2 // DXIL_NATIVE_HALF: %dx.umad = call <2 x i16> @llvm.dx.umad.v2i16(<2 x i16> %[[#]], <2 x i16> %[[#]], <2 x i16> %[[#]]) // DXIL_NATIVE_HALF: ret <2 x i16> %dx.umad // SPIR_NATIVE_HALF: mul nuw <2 x i16> %{{.*}}, %{{.*}} // SPIR_NATIVE_HALF: add nuw <2 x i16> %{{.*}}, %{{.*}} uint16_t2 test_mad_uint16_t2(uint16_t2 p0, uint16_t2 p1, uint16_t2 p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_uint16_t3 // DXIL_NATIVE_HALF: %dx.umad = call <3 x i16> @llvm.dx.umad.v3i16(<3 x i16> %[[#]], <3 x i16> %[[#]], <3 x i16> %[[#]]) // DXIL_NATIVE_HALF: ret <3 x i16> %dx.umad // SPIR_NATIVE_HALF: mul nuw <3 x i16> %{{.*}}, %{{.*}} // SPIR_NATIVE_HALF: add nuw <3 x i16> %{{.*}}, %{{.*}} uint16_t3 test_mad_uint16_t3(uint16_t3 p0, uint16_t3 p1, uint16_t3 p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_uint16_t4 // DXIL_NATIVE_HALF: %dx.umad = call <4 x i16> @llvm.dx.umad.v4i16(<4 x i16> %[[#]], <4 x i16> %[[#]], <4 x i16> %[[#]]) // DXIL_NATIVE_HALF: ret <4 x i16> %dx.umad // SPIR_NATIVE_HALF: mul nuw <4 x i16> %{{.*}}, %{{.*}} // SPIR_NATIVE_HALF: add nuw <4 x i16> %{{.*}}, %{{.*}} uint16_t4 test_mad_uint16_t4(uint16_t4 p0, uint16_t4 p1, uint16_t4 p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_int16_t // DXIL_NATIVE_HALF: %dx.imad = call i16 @llvm.dx.imad.i16(i16 %[[#]], i16 %[[#]], i16 %[[#]]) // DXIL_NATIVE_HALF: ret i16 %dx.imad // SPIR_NATIVE_HALF: mul nsw i16 %{{.*}}, %{{.*}} // SPIR_NATIVE_HALF: add nsw i16 %{{.*}}, %{{.*}} int16_t test_mad_int16_t(int16_t p0, int16_t p1, int16_t p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_int16_t2 // DXIL_NATIVE_HALF: %dx.imad = call <2 x i16> @llvm.dx.imad.v2i16(<2 x i16> %[[#]], <2 x i16> %[[#]], <2 x i16> %[[#]]) // DXIL_NATIVE_HALF: ret <2 x i16> %dx.imad // SPIR_NATIVE_HALF: mul nsw <2 x i16> %{{.*}}, %{{.*}} // SPIR_NATIVE_HALF: add nsw <2 x i16> %{{.*}}, %{{.*}} int16_t2 test_mad_int16_t2(int16_t2 p0, int16_t2 p1, int16_t2 p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_int16_t3 // DXIL_NATIVE_HALF: %dx.imad = call <3 x i16> @llvm.dx.imad.v3i16(<3 x i16> %[[#]], <3 x i16> %[[#]], <3 x i16> %[[#]]) // DXIL_NATIVE_HALF: ret <3 x i16> %dx.imad // SPIR_NATIVE_HALF: mul nsw <3 x i16> %{{.*}}, %{{.*}} // SPIR_NATIVE_HALF: add nsw <3 x i16> %{{.*}}, %{{.*}} int16_t3 test_mad_int16_t3(int16_t3 p0, int16_t3 p1, int16_t3 p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_int16_t4 // DXIL_NATIVE_HALF: %dx.imad = call <4 x i16> @llvm.dx.imad.v4i16(<4 x i16> %[[#]], <4 x i16> %[[#]], <4 x i16> %[[#]]) // DXIL_NATIVE_HALF: ret <4 x i16> %dx.imad // SPIR_NATIVE_HALF: mul nsw <4 x i16> %{{.*}}, %{{.*}} @@ -64,6 +73,7 @@ int16_t3 test_mad_int16_t3(int16_t3 p0, int16_t3 p1, int16_t3 p2) { return mad(p int16_t4 test_mad_int16_t4(int16_t4 p0, int16_t4 p1, int16_t4 p2) { return mad(p0, p1, p2); } #endif // __HLSL_ENABLE_16_BIT +// CHECK-LABEL: test_mad_half // NATIVE_HALF: %[[p0:.*]] = load half, ptr %p0.addr // NATIVE_HALF: %[[p1:.*]] = load half, ptr %p1.addr // NATIVE_HALF: %[[p2:.*]] = load half, ptr %p2.addr @@ -76,6 +86,7 @@ int16_t4 test_mad_int16_t4(int16_t4 p0, int16_t4 p1, int16_t4 p2) { return mad(p // NO_HALF: ret float %hlsl.fmad half test_mad_half(half p0, half p1, half p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_half2 // NATIVE_HALF: %[[p0:.*]] = load <2 x half>, ptr %p0.addr // NATIVE_HALF: %[[p1:.*]] = load <2 x half>, ptr %p1.addr // NATIVE_HALF: %[[p2:.*]] = load <2 x half>, ptr %p2.addr @@ -88,6 +99,7 @@ half test_mad_half(half p0, half p1, half p2) { return mad(p0, p1, p2); } // NO_HALF: ret <2 x float> %hlsl.fmad half2 test_mad_half2(half2 p0, half2 p1, half2 p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_half3 // NATIVE_HALF: %[[p0:.*]] = load <3 x half>, ptr %p0.addr // NATIVE_HALF: %[[p1:.*]] = load <3 x half>, ptr %p1.addr // NATIVE_HALF: %[[p2:.*]] = load <3 x half>, ptr %p2.addr @@ -100,6 +112,7 @@ half2 test_mad_half2(half2 p0, half2 p1, half2 p2) { return mad(p0, p1, p2); } // NO_HALF: ret <3 x float> %hlsl.fmad half3 test_mad_half3(half3 p0, half3 p1, half3 p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_half4 // NATIVE_HALF: %[[p0:.*]] = load <4 x half>, ptr %p0.addr // NATIVE_HALF: %[[p1:.*]] = load <4 x half>, ptr %p1.addr // NATIVE_HALF: %[[p2:.*]] = load <4 x half>, ptr %p2.addr @@ -112,6 +125,7 @@ half3 test_mad_half3(half3 p0, half3 p1, half3 p2) { return mad(p0, p1, p2); } // NO_HALF: ret <4 x float> %hlsl.fmad half4 test_mad_half4(half4 p0, half4 p1, half4 p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_float // CHECK: %[[p0:.*]] = load float, ptr %p0.addr // CHECK: %[[p1:.*]] = load float, ptr %p1.addr // CHECK: %[[p2:.*]] = load float, ptr %p2.addr @@ -119,6 +133,7 @@ half4 test_mad_half4(half4 p0, half4 p1, half4 p2) { return mad(p0, p1, p2); } // CHECK: ret float %hlsl.fmad float test_mad_float(float p0, float p1, float p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_float2 // CHECK: %[[p0:.*]] = load <2 x float>, ptr %p0.addr // CHECK: %[[p1:.*]] = load <2 x float>, ptr %p1.addr // CHECK: %[[p2:.*]] = load <2 x float>, ptr %p2.addr @@ -126,6 +141,7 @@ float test_mad_float(float p0, float p1, float p2) { return mad(p0, p1, p2); } // CHECK: ret <2 x float> %hlsl.fmad float2 test_mad_float2(float2 p0, float2 p1, float2 p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_float3 // CHECK: %[[p0:.*]] = load <3 x float>, ptr %p0.addr // CHECK: %[[p1:.*]] = load <3 x float>, ptr %p1.addr // CHECK: %[[p2:.*]] = load <3 x float>, ptr %p2.addr @@ -133,6 +149,7 @@ float2 test_mad_float2(float2 p0, float2 p1, float2 p2) { return mad(p0, p1, p2) // CHECK: ret <3 x float> %hlsl.fmad float3 test_mad_float3(float3 p0, float3 p1, float3 p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_float4 // CHECK: %[[p0:.*]] = load <4 x float>, ptr %p0.addr // CHECK: %[[p1:.*]] = load <4 x float>, ptr %p1.addr // CHECK: %[[p2:.*]] = load <4 x float>, ptr %p2.addr @@ -140,6 +157,7 @@ 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-LABEL: test_mad_float5 // 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 @@ -147,6 +165,7 @@ float4 test_mad_float4(float4 p0, float4 p1, float4 p2) { return mad(p0, p1, 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-LABEL: test_mad_double // CHECK: %[[p0:.*]] = load double, ptr %p0.addr // CHECK: %[[p1:.*]] = load double, ptr %p1.addr // CHECK: %[[p2:.*]] = load double, ptr %p2.addr @@ -154,6 +173,7 @@ vector<float, 5> test_mad_float5(vector<float, 5> p0, vector<float, 5> p1, vecto // CHECK: ret double %hlsl.fmad double test_mad_double(double p0, double p1, double p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_double2 // CHECK: %[[p0:.*]] = load <2 x double>, ptr %p0.addr // CHECK: %[[p1:.*]] = load <2 x double>, ptr %p1.addr // CHECK: %[[p2:.*]] = load <2 x double>, ptr %p2.addr @@ -161,6 +181,7 @@ double test_mad_double(double p0, double p1, double p2) { return mad(p0, p1, p2) // CHECK: ret <2 x double> %hlsl.fmad double2 test_mad_double2(double2 p0, double2 p1, double2 p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_double3 // CHECK: %[[p0:.*]] = load <3 x double>, ptr %p0.addr // CHECK: %[[p1:.*]] = load <3 x double>, ptr %p1.addr // CHECK: %[[p2:.*]] = load <3 x double>, ptr %p2.addr @@ -168,6 +189,7 @@ double2 test_mad_double2(double2 p0, double2 p1, double2 p2) { return mad(p0, p1 // CHECK: ret <3 x double> %hlsl.fmad double3 test_mad_double3(double3 p0, double3 p1, double3 p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_double4 // CHECK: %[[p0:.*]] = load <4 x double>, ptr %p0.addr // CHECK: %[[p1:.*]] = load <4 x double>, ptr %p1.addr // CHECK: %[[p2:.*]] = load <4 x double>, ptr %p2.addr @@ -175,96 +197,112 @@ double3 test_mad_double3(double3 p0, double3 p1, double3 p2) { return mad(p0, p1 // CHECK: ret <4 x double> %hlsl.fmad double4 test_mad_double4(double4 p0, double4 p1, double4 p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_int // DXIL_CHECK: %dx.imad = call i32 @llvm.dx.imad.i32(i32 %[[#]], i32 %[[#]], i32 %[[#]]) // DXIL_CHECK: ret i32 %dx.imad // SPIR_CHECK: mul nsw i32 %{{.*}}, %{{.*}} // SPIR_CHECK: add nsw i32 %{{.*}}, %{{.*}} int test_mad_int(int p0, int p1, int p2) { return mad(p0, p1, p2); } - + +// CHECK-LABEL: test_mad_int2 // DXIL_CHECK: %dx.imad = call <2 x i32> @llvm.dx.imad.v2i32(<2 x i32> %[[#]], <2 x i32> %[[#]], <2 x i32> %[[#]]) // DXIL_CHECK: ret <2 x i32> %dx.imad // SPIR_CHECK: mul nsw <2 x i32> %{{.*}}, %{{.*}} // SPIR_CHECK: add nsw <2 x i32> %{{.*}}, %{{.*}} int2 test_mad_int2(int2 p0, int2 p1, int2 p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_int3 // DXIL_CHECK: %dx.imad = call <3 x i32> @llvm.dx.imad.v3i32(<3 x i32> %[[#]], <3 x i32> %[[#]], <3 x i32> %[[#]]) // DXIL_CHECK: ret <3 x i32> %dx.imad // SPIR_CHECK: mul nsw <3 x i32> %{{.*}}, %{{.*}} // SPIR_CHECK: add nsw <3 x i32> %{{.*}}, %{{.*}} int3 test_mad_int3(int3 p0, int3 p1, int3 p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_int4 // DXIL_CHECK: %dx.imad = call <4 x i32> @llvm.dx.imad.v4i32(<4 x i32> %[[#]], <4 x i32> %[[#]], <4 x i32> %[[#]]) // DXIL_CHECK: ret <4 x i32> %dx.imad // SPIR_CHECK: mul nsw <4 x i32> %{{.*}}, %{{.*}} // SPIR_CHECK: add nsw <4 x i32> %{{.*}}, %{{.*}} int4 test_mad_int4(int4 p0, int4 p1, int4 p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_int64_t // DXIL_CHECK: %dx.imad = call i64 @llvm.dx.imad.i64(i64 %[[#]], i64 %[[#]], i64 %[[#]]) // DXIL_CHECK: ret i64 %dx.imad // SPIR_CHECK: mul nsw i64 %{{.*}}, %{{.*}} // SPIR_CHECK: add nsw i64 %{{.*}}, %{{.*}} int64_t test_mad_int64_t(int64_t p0, int64_t p1, int64_t p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_int64_t2 // DXIL_CHECK: %dx.imad = call <2 x i64> @llvm.dx.imad.v2i64(<2 x i64> %[[#]], <2 x i64> %[[#]], <2 x i64> %[[#]]) // DXIL_CHECK: ret <2 x i64> %dx.imad // SPIR_CHECK: mul nsw <2 x i64> %{{.*}}, %{{.*}} // SPIR_CHECK: add nsw <2 x i64> %{{.*}}, %{{.*}} int64_t2 test_mad_int64_t2(int64_t2 p0, int64_t2 p1, int64_t2 p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_int64_t3 // DXIL_CHECK: %dx.imad = call <3 x i64> @llvm.dx.imad.v3i64(<3 x i64> %[[#]], <3 x i64> %[[#]], <3 x i64> %[[#]]) // DXIL_CHECK: ret <3 x i64> %dx.imad // SPIR_CHECK: mul nsw <3 x i64> %{{.*}}, %{{.*}} // SPIR_CHECK: add nsw <3 x i64> %{{.*}}, %{{.*}} int64_t3 test_mad_int64_t3(int64_t3 p0, int64_t3 p1, int64_t3 p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_int64_t4 // DXIL_CHECK: %dx.imad = call <4 x i64> @llvm.dx.imad.v4i64(<4 x i64> %[[#]], <4 x i64> %[[#]], <4 x i64> %[[#]]) // DXIL_CHECK: ret <4 x i64> %dx.imad // SPIR_CHECK: mul nsw <4 x i64> %{{.*}}, %{{.*}} // SPIR_CHECK: add nsw <4 x i64> %{{.*}}, %{{.*}} int64_t4 test_mad_int64_t4(int64_t4 p0, int64_t4 p1, int64_t4 p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_uint // DXIL_CHECK: %dx.umad = call i32 @llvm.dx.umad.i32(i32 %[[#]], i32 %[[#]], i32 %[[#]]) // DXIL_CHECK: ret i32 %dx.umad // SPIR_CHECK: mul nuw i32 %{{.*}}, %{{.*}} // SPIR_CHECK: add nuw i32 %{{.*}}, %{{.*}} uint test_mad_uint(uint p0, uint p1, uint p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_uint2 // DXIL_CHECK: %dx.umad = call <2 x i32> @llvm.dx.umad.v2i32(<2 x i32> %[[#]], <2 x i32> %[[#]], <2 x i32> %[[#]]) // DXIL_CHECK: ret <2 x i32> %dx.umad // SPIR_CHECK: mul nuw <2 x i32> %{{.*}}, %{{.*}} // SPIR_CHECK: add nuw <2 x i32> %{{.*}}, %{{.*}} uint2 test_mad_uint2(uint2 p0, uint2 p1, uint2 p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_uint3 // DXIL_CHECK: %dx.umad = call <3 x i32> @llvm.dx.umad.v3i32(<3 x i32> %[[#]], <3 x i32> %[[#]], <3 x i32> %[[#]]) // DXIL_CHECK: ret <3 x i32> %dx.umad // SPIR_CHECK: mul nuw <3 x i32> %{{.*}}, %{{.*}} // SPIR_CHECK: add nuw <3 x i32> %{{.*}}, %{{.*}} uint3 test_mad_uint3(uint3 p0, uint3 p1, uint3 p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_uint4 // DXIL_CHECK: %dx.umad = call <4 x i32> @llvm.dx.umad.v4i32(<4 x i32> %[[#]], <4 x i32> %[[#]], <4 x i32> %[[#]]) // DXIL_CHECK: ret <4 x i32> %dx.umad // SPIR_CHECK: mul nuw <4 x i32> %{{.*}}, %{{.*}} // SPIR_CHECK: add nuw <4 x i32> %{{.*}}, %{{.*}} uint4 test_mad_uint4(uint4 p0, uint4 p1, uint4 p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_uint64_t // DXIL_CHECK: %dx.umad = call i64 @llvm.dx.umad.i64(i64 %[[#]], i64 %[[#]], i64 %[[#]]) // DXIL_CHECK: ret i64 %dx.umad // SPIR_CHECK: mul nuw i64 %{{.*}}, %{{.*}} // SPIR_CHECK: add nuw i64 %{{.*}}, %{{.*}} uint64_t test_mad_uint64_t(uint64_t p0, uint64_t p1, uint64_t p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_uint64_t2 // DXIL_CHECK: %dx.umad = call <2 x i64> @llvm.dx.umad.v2i64(<2 x i64> %[[#]], <2 x i64> %[[#]], <2 x i64> %[[#]]) // DXIL_CHECK: ret <2 x i64> %dx.umad // SPIR_CHECK: mul nuw <2 x i64> %{{.*}}, %{{.*}} // SPIR_CHECK: add nuw <2 x i64> %{{.*}}, %{{.*}} uint64_t2 test_mad_uint64_t2(uint64_t2 p0, uint64_t2 p1, uint64_t2 p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_uint64_t3 // DXIL_CHECK: %dx.umad = call <3 x i64> @llvm.dx.umad.v3i64(<3 x i64> %[[#]], <3 x i64> %[[#]], <3 x i64> %[[#]]) // DXIL_CHECK: ret <3 x i64> %dx.umad // SPIR_CHECK: mul nuw <3 x i64> %{{.*}}, %{{.*}} // SPIR_CHECK: add nuw <3 x i64> %{{.*}}, %{{.*}} uint64_t3 test_mad_uint64_t3(uint64_t3 p0, uint64_t3 p1, uint64_t3 p2) { return mad(p0, p1, p2); } +// CHECK-LABEL: test_mad_uint64_t4 // DXIL_CHECK: %dx.umad = call <4 x i64> @llvm.dx.umad.v4i64(<4 x i64> %[[#]], <4 x i64> %[[#]], <4 x i64> %[[#]]) // DXIL_CHECK: ret <4 x i64> %dx.umad // SPIR_CHECK: mul nuw <4 x i64> %{{.*}}, %{{.*}} >From 7c58bc082a09024cd59ac1b3857d41e94e03cbd6 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi <[email protected]> Date: Tue, 15 Sep 2026 15:57:26 -0400 Subject: [PATCH 4/5] add labels as per pr request --- clang/test/CodeGenHLSL/builtins/mad.hlsl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/clang/test/CodeGenHLSL/builtins/mad.hlsl b/clang/test/CodeGenHLSL/builtins/mad.hlsl index f7ea6232856e6..e45fb0bc20383 100644 --- a/clang/test/CodeGenHLSL/builtins/mad.hlsl +++ b/clang/test/CodeGenHLSL/builtins/mad.hlsl @@ -16,56 +16,56 @@ #ifdef __HLSL_ENABLE_16_BIT -// CHECK-LABEL: test_mad_uint16_t +// NATIVE_HALF-LABEL: test_mad_uint16_t // DXIL_NATIVE_HALF: %dx.umad = call i16 @llvm.dx.umad.i16(i16 %[[#]], i16 %[[#]], i16 %[[#]]) // DXIL_NATIVE_HALF: ret i16 %dx.umad // SPIR_NATIVE_HALF: mul nuw i16 %{{.*}}, %{{.*}} // SPIR_NATIVE_HALF: add nuw i16 %{{.*}}, %{{.*}} uint16_t test_mad_uint16_t(uint16_t p0, uint16_t p1, uint16_t p2) { return mad(p0, p1, p2); } -// CHECK-LABEL: test_mad_uint16_t2 +// NATIVE_HALF-LABEL: test_mad_uint16_t2 // DXIL_NATIVE_HALF: %dx.umad = call <2 x i16> @llvm.dx.umad.v2i16(<2 x i16> %[[#]], <2 x i16> %[[#]], <2 x i16> %[[#]]) // DXIL_NATIVE_HALF: ret <2 x i16> %dx.umad // SPIR_NATIVE_HALF: mul nuw <2 x i16> %{{.*}}, %{{.*}} // SPIR_NATIVE_HALF: add nuw <2 x i16> %{{.*}}, %{{.*}} uint16_t2 test_mad_uint16_t2(uint16_t2 p0, uint16_t2 p1, uint16_t2 p2) { return mad(p0, p1, p2); } -// CHECK-LABEL: test_mad_uint16_t3 +// NATIVE_HALF-LABEL: test_mad_uint16_t3 // DXIL_NATIVE_HALF: %dx.umad = call <3 x i16> @llvm.dx.umad.v3i16(<3 x i16> %[[#]], <3 x i16> %[[#]], <3 x i16> %[[#]]) // DXIL_NATIVE_HALF: ret <3 x i16> %dx.umad // SPIR_NATIVE_HALF: mul nuw <3 x i16> %{{.*}}, %{{.*}} // SPIR_NATIVE_HALF: add nuw <3 x i16> %{{.*}}, %{{.*}} uint16_t3 test_mad_uint16_t3(uint16_t3 p0, uint16_t3 p1, uint16_t3 p2) { return mad(p0, p1, p2); } -// CHECK-LABEL: test_mad_uint16_t4 +// NATIVE_HALF-LABEL: test_mad_uint16_t4 // DXIL_NATIVE_HALF: %dx.umad = call <4 x i16> @llvm.dx.umad.v4i16(<4 x i16> %[[#]], <4 x i16> %[[#]], <4 x i16> %[[#]]) // DXIL_NATIVE_HALF: ret <4 x i16> %dx.umad // SPIR_NATIVE_HALF: mul nuw <4 x i16> %{{.*}}, %{{.*}} // SPIR_NATIVE_HALF: add nuw <4 x i16> %{{.*}}, %{{.*}} uint16_t4 test_mad_uint16_t4(uint16_t4 p0, uint16_t4 p1, uint16_t4 p2) { return mad(p0, p1, p2); } -// CHECK-LABEL: test_mad_int16_t +// NATIVE_HALF-LABEL: test_mad_int16_t // DXIL_NATIVE_HALF: %dx.imad = call i16 @llvm.dx.imad.i16(i16 %[[#]], i16 %[[#]], i16 %[[#]]) // DXIL_NATIVE_HALF: ret i16 %dx.imad // SPIR_NATIVE_HALF: mul nsw i16 %{{.*}}, %{{.*}} // SPIR_NATIVE_HALF: add nsw i16 %{{.*}}, %{{.*}} int16_t test_mad_int16_t(int16_t p0, int16_t p1, int16_t p2) { return mad(p0, p1, p2); } -// CHECK-LABEL: test_mad_int16_t2 +// NATIVE_HALF-LABEL: test_mad_int16_t2 // DXIL_NATIVE_HALF: %dx.imad = call <2 x i16> @llvm.dx.imad.v2i16(<2 x i16> %[[#]], <2 x i16> %[[#]], <2 x i16> %[[#]]) // DXIL_NATIVE_HALF: ret <2 x i16> %dx.imad // SPIR_NATIVE_HALF: mul nsw <2 x i16> %{{.*}}, %{{.*}} // SPIR_NATIVE_HALF: add nsw <2 x i16> %{{.*}}, %{{.*}} int16_t2 test_mad_int16_t2(int16_t2 p0, int16_t2 p1, int16_t2 p2) { return mad(p0, p1, p2); } -// CHECK-LABEL: test_mad_int16_t3 +// NATIVE_HALF-LABEL: test_mad_int16_t3 // DXIL_NATIVE_HALF: %dx.imad = call <3 x i16> @llvm.dx.imad.v3i16(<3 x i16> %[[#]], <3 x i16> %[[#]], <3 x i16> %[[#]]) // DXIL_NATIVE_HALF: ret <3 x i16> %dx.imad // SPIR_NATIVE_HALF: mul nsw <3 x i16> %{{.*}}, %{{.*}} // SPIR_NATIVE_HALF: add nsw <3 x i16> %{{.*}}, %{{.*}} int16_t3 test_mad_int16_t3(int16_t3 p0, int16_t3 p1, int16_t3 p2) { return mad(p0, p1, p2); } -// CHECK-LABEL: test_mad_int16_t4 +// NATIVE_HALF-LABEL: test_mad_int16_t4 // DXIL_NATIVE_HALF: %dx.imad = call <4 x i16> @llvm.dx.imad.v4i16(<4 x i16> %[[#]], <4 x i16> %[[#]], <4 x i16> %[[#]]) // DXIL_NATIVE_HALF: ret <4 x i16> %dx.imad // SPIR_NATIVE_HALF: mul nsw <4 x i16> %{{.*}}, %{{.*}} >From 544b3bcc69ba08bde938126d669748299eb2efdc Mon Sep 17 00:00:00 2001 From: Farzon Lotfi <[email protected]> Date: Tue, 15 Sep 2026 16:07:29 -0400 Subject: [PATCH 5/5] make asdouble tests varify inputs --- clang/test/CodeGenHLSL/builtins/asdouble.hlsl | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/clang/test/CodeGenHLSL/builtins/asdouble.hlsl b/clang/test/CodeGenHLSL/builtins/asdouble.hlsl index 2753b416d7440..a509571cd8f54 100644 --- a/clang/test/CodeGenHLSL/builtins/asdouble.hlsl +++ b/clang/test/CodeGenHLSL/builtins/asdouble.hlsl @@ -7,42 +7,57 @@ // Test lowering of asdouble expansion to shuffle/bitcast and splat when required -// CHECK-LABEL: test_uint +// CHECK-LABEL: define {{.*}}test_uint +// CHECK-SAME: (i32 noundef %[[LOW_ARG:[^,]+]], i32 noundef %[[HIGH_ARG:[^)]+]]) double test_uint(uint low, uint high) { - // CHECK-SPV: %[[LOW_INSERT:.*]] = insertelement <1 x i32> + // CHECK: store i32 %[[LOW_ARG]], ptr %[[LOW_ADDR:.*]], align 4 + // CHECK: store i32 %[[HIGH_ARG]], ptr %[[HIGH_ADDR:.*]], align 4 + // CHECK: %[[LOW:.*]] = load i32, ptr %[[LOW_ADDR]], align 4 + // CHECK: %[[HIGH:.*]] = load i32, ptr %[[HIGH_ADDR]], align 4 + // CHECK-SPV: %[[LOW_INSERT:.*]] = insertelement <1 x i32> poison, i32 %[[LOW]], i64 0 // CHECK-SPV: %[[LOW_SHUFFLE:.*]] = shufflevector <1 x i32> %[[LOW_INSERT]], {{.*}} zeroinitializer - // CHECK-SPV: %[[HIGH_INSERT:.*]] = insertelement <1 x i32> + // CHECK-SPV: %[[HIGH_INSERT:.*]] = insertelement <1 x i32> poison, i32 %[[HIGH]], i64 0 // CHECK-SPV: %[[HIGH_SHUFFLE:.*]] = shufflevector <1 x i32> %[[HIGH_INSERT]], {{.*}} zeroinitializer // CHECK-SPV: %[[SHUFFLE0:.*]] = shufflevector <1 x i32> %[[LOW_SHUFFLE]], <1 x i32> %[[HIGH_SHUFFLE]], // CHECK-SPV-SAME: {{.*}} <i32 0, i32 1> // CHECK-SPV: bitcast <2 x i32> %[[SHUFFLE0]] to double - // CHECK-DXIL: call reassoc nnan ninf nsz arcp afn double @llvm.dx.asdouble.i32 + // CHECK-DXIL: call reassoc nnan ninf nsz arcp afn double @llvm.dx.asdouble.i32(i32 %[[LOW]], i32 %[[HIGH]]) return asdouble(low, high); } // CHECK-DXIL: declare double @llvm.dx.asdouble.i32 -// CHECK-LABEL: test_vuint +// CHECK-LABEL: define {{.*}}test_vuint +// CHECK-SAME: (<3 x i32> noundef %[[V3_LOW_ARG:[^,]+]], <3 x i32> noundef %[[V3_HIGH_ARG:[^)]+]]) double3 test_vuint(uint3 low, uint3 high) { - // CHECK-SPV: %[[SHUFFLE1:.*]] = shufflevector + // CHECK: store <3 x i32> %[[V3_LOW_ARG]], ptr %[[V3_LOW_ADDR:.*]], align 4 + // CHECK: store <3 x i32> %[[V3_HIGH_ARG]], ptr %[[V3_HIGH_ADDR:.*]], align 4 + // CHECK: %[[V3_LOW:.*]] = load <3 x i32>, ptr %[[V3_LOW_ADDR]], align 4 + // CHECK: %[[V3_HIGH:.*]] = load <3 x i32>, ptr %[[V3_HIGH_ADDR]], align 4 + // CHECK-SPV: %[[SHUFFLE1:.*]] = shufflevector <3 x i32> %[[V3_LOW]], <3 x i32> %[[V3_HIGH]], // CHECK-SPV-SAME: {{.*}} <i32 0, i32 3, i32 1, i32 4, i32 2, i32 5> // CHECK-SPV: bitcast <6 x i32> %[[SHUFFLE1]] to <3 x double> - // CHECK-DXIL: call reassoc nnan ninf nsz arcp afn <3 x double> @llvm.dx.asdouble.v3i32 + // CHECK-DXIL: call reassoc nnan ninf nsz arcp afn <3 x double> @llvm.dx.asdouble.v3i32(<3 x i32> %[[V3_LOW]], <3 x i32> %[[V3_HIGH]]) return asdouble(low, high); } // CHECK-DXIL: declare <3 x double> @llvm.dx.asdouble.v3i32 -// CHECK-LABEL: test_vuint5 +// CHECK-LABEL: define {{.*}}test_vuint5 +// CHECK-SAME: (<5 x i32> noundef %[[V5_LOW_ARG:[^,]+]], <5 x i32> noundef %[[V5_HIGH_ARG:[^)]+]]) vector<double, 5> test_vuint5(vector<uint, 5> low, vector<uint, 5> high) { - // CHECK-SPV: %[[SHUFFLE2:.*]] = shufflevector + // CHECK: store <5 x i32> %[[V5_LOW_ARG]], ptr %[[V5_LOW_ADDR:.*]], align 4 + // CHECK: store <5 x i32> %[[V5_HIGH_ARG]], ptr %[[V5_HIGH_ADDR:.*]], align 4 + // CHECK: %[[V5_LOW:.*]] = load <5 x i32>, ptr %[[V5_LOW_ADDR]], align 4 + // CHECK: %[[V5_HIGH:.*]] = load <5 x i32>, ptr %[[V5_HIGH_ADDR]], align 4 + // CHECK-SPV: %[[SHUFFLE2:.*]] = shufflevector <5 x i32> %[[V5_LOW]], <5 x i32> %[[V5_HIGH]], // 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 + // CHECK-DXIL: call reassoc nnan ninf nsz arcp afn <5 x double> @llvm.dx.asdouble.v5i32(<5 x i32> %[[V5_LOW]], <5 x i32> %[[V5_HIGH]]) return asdouble(low, high); } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
