diff options
Diffstat (limited to 'clang/test/CodeGenHLSL')
58 files changed, 2621 insertions, 481 deletions
diff --git a/clang/test/CodeGenHLSL/ArrayAssignable.hlsl b/clang/test/CodeGenHLSL/ArrayAssignable.hlsl index aaa486e..d1bfc6d 100644 --- a/clang/test/CodeGenHLSL/ArrayAssignable.hlsl +++ b/clang/test/CodeGenHLSL/ArrayAssignable.hlsl @@ -5,18 +5,19 @@ struct S { float f; }; -// CHECK: [[CBLayout:%.*]] = type <{ [2 x float], [2 x <4 x i32>], [2 x [2 x i32]], [1 x target("dx.Layout", %S, 8, 0, 4)] }> -// CHECK: @CBArrays.cb = global target("dx.CBuffer", target("dx.Layout", [[CBLayout]], 136, 0, 32, 64, 128)) -// CHECK: @c1 = external hidden addrspace(2) global [2 x float], align 4 +// CHECK: [[CBLayout:%.*]] = type <{ <{ [1 x <{ float, target("dx.Padding", 12) }>], float }>, target("dx.Padding", 12), [2 x <4 x i32>], <{ [1 x <{ <{ [1 x <{ i32, target("dx.Padding", 12) }>], i32 }>, target("dx.Padding", 12) }>], <{ [1 x <{ i32, target("dx.Padding", 12) }>], i32 }> }>, target("dx.Padding", 12), <{ [1 x <{ %S, target("dx.Padding", 8) }>], %S }> }> + +// CHECK: @CBArrays.cb = global target("dx.CBuffer", [[CBLayout]]) +// CHECK: @c1 = external hidden addrspace(2) global <{ [1 x <{ float, target("dx.Padding", 12) }>], float }>, align 4 // CHECK: @c2 = external hidden addrspace(2) global [2 x <4 x i32>], align 16 -// CHECK: @c3 = external hidden addrspace(2) global [2 x [2 x i32]], align 4 -// CHECK: @c4 = external hidden addrspace(2) global [1 x target("dx.Layout", %S, 8, 0, 4)], align 1 +// CHECK: @c3 = external hidden addrspace(2) global <{ [1 x <{ <{ [1 x <{ i32, target("dx.Padding", 12) }>], i32 }>, target("dx.Padding", 12) }>], <{ [1 x <{ i32, target("dx.Padding", 12) }>], i32 }> }>, align 4 +// CHECK: @c4 = external hidden addrspace(2) global <{ [1 x <{ %S, target("dx.Padding", 8) }>], %S }>, align 1 cbuffer CBArrays : register(b0) { float c1[2]; int4 c2[2]; int c3[2][2]; - S c4[1]; + S c4[2]; } // CHECK-LABEL: define hidden void {{.*}}arr_assign1 @@ -140,40 +141,71 @@ void arr_assign7() { // CHECK-LABEL: define hidden void {{.*}}arr_assign8 // CHECK: [[C:%.*]] = alloca [2 x float], align 4 -// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[C]], ptr align 4 {{.*}}, i32 8, i1 false) -// CHECK-NEXT: call void @llvm.memcpy.p0.p2.i32(ptr align 4 [[C]], ptr addrspace(2) align 4 @c1, i32 8, i1 false) +// CHECK-NEXT: [[V0:%.*]] = getelementptr inbounds [2 x float], ptr [[C]], i32 0 +// CHECK-NEXT: [[L0:%.*]] = load float, ptr addrspace(2) @c1, align 4 +// CHECK-NEXT: store float [[L0]], ptr [[V0]], align 4 +// CHECK-NEXT: [[V1:%.*]] = getelementptr inbounds [2 x float], ptr [[C]], i32 0, i32 1 +// CHECK-NEXT: [[L1:%.*]] = load float, ptr addrspace(2) getelementptr inbounds (<{ [1 x <{ float, target("dx.Padding", 12) }>], float }>, ptr addrspace(2) @c1, i32 0, i32 1), align 4 +// CHECK-NEXT: store float [[L1]], ptr [[V1]], align 4 // CHECK-NEXT: ret void void arr_assign8() { - float C[2] = {1.0, 2.0}; + float C[2]; C = c1; } +// TODO: We should be able to just memcpy here. +// See https://github.com/llvm/wg-hlsl/issues/351 +// // CHECK-LABEL: define hidden void {{.*}}arr_assign9 // CHECK: [[C:%.*]] = alloca [2 x <4 x i32>], align 16 -// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 16 [[C]], ptr align 16 {{.*}}, i32 32, i1 false) -// CHECK-NEXT: call void @llvm.memcpy.p0.p2.i32(ptr align 16 [[C]], ptr addrspace(2) align 16 @c2, i32 32, i1 false) +// CHECK-NEXT: [[V0:%.*]] = getelementptr inbounds [2 x <4 x i32>], ptr [[C]], i32 0 +// CHECK-NEXT: [[L0:%.*]] = load <4 x i32>, ptr addrspace(2) @c2, align 16 +// CHECK-NEXT: store <4 x i32> [[L0]], ptr [[V0]], align 16 +// CHECK-NEXT: [[V1:%.*]] = getelementptr inbounds [2 x <4 x i32>], ptr [[C]], i32 0, i32 1 +// CHECK-NEXT: [[L1:%.*]] = load <4 x i32>, ptr addrspace(2) getelementptr inbounds ([2 x <4 x i32>], ptr addrspace(2) @c2, i32 0, i32 1), align 16 +// CHECK-NEXT: store <4 x i32> [[L1]], ptr [[V1]], align 16 // CHECK-NEXT: ret void void arr_assign9() { - int4 C[2] = {1,2,3,4,5,6,7,8}; + int4 C[2]; C = c2; } // CHECK-LABEL: define hidden void {{.*}}arr_assign10 // CHECK: [[C:%.*]] = alloca [2 x [2 x i32]], align 4 -// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[C]], ptr align 4 {{.*}}, i32 16, i1 false) -// CHECK-NEXT: call void @llvm.memcpy.p0.p2.i32(ptr align 4 [[C]], ptr addrspace(2) align 4 @c3, i32 16, i1 false) +// CHECK-NEXT: [[V0:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[C]], i32 0, i32 0, i32 0 +// CHECK-NEXT: [[L0:%.*]] = load i32, ptr addrspace(2) @c3, align 4 +// CHECK-NEXT: store i32 [[L0]], ptr [[V0]], align 4 +// CHECK-NEXT: [[V1:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[C]], i32 0, i32 0, i32 1 +// CHECK-NEXT: [[L1:%.*]] = load i32, ptr addrspace(2) getelementptr inbounds (<{ [1 x <{ <{ [1 x <{ i32, target("dx.Padding", 12) }>], i32 }>, target("dx.Padding", 12) }>], <{ [1 x <{ i32, target("dx.Padding", 12) }>], i32 }> }>, ptr addrspace(2) @c3, i32 0, i32 0, i32 0, i32 0, i32 1), align 4 +// CHECK-NEXT: store i32 [[L1]], ptr [[V1]], align 4 +// CHECK-NEXT: [[V2:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[C]], i32 0, i32 1, i32 0 +// CHECK-NEXT: [[L2:%.*]] = load i32, ptr addrspace(2) getelementptr inbounds (<{ [1 x <{ <{ [1 x <{ i32, target("dx.Padding", 12) }>], i32 }>, target("dx.Padding", 12) }>], <{ [1 x <{ i32, target("dx.Padding", 12) }>], i32 }> }>, ptr addrspace(2) @c3, i32 0, i32 1, i32 0, i32 0, i32 0), align 4 +// CHECK-NEXT: store i32 [[L2]], ptr [[V2]], align 4 +// CHECK-NEXT: [[V3:%.*]] = getelementptr inbounds [2 x [2 x i32]], ptr [[C]], i32 0, i32 1, i32 1 +// CHECK-NEXT: [[L3:%.*]] = load i32, ptr addrspace(2) getelementptr inbounds (<{ [1 x <{ <{ [1 x <{ i32, target("dx.Padding", 12) }>], i32 }>, target("dx.Padding", 12) }>], <{ [1 x <{ i32, target("dx.Padding", 12) }>], i32 }> }>, ptr addrspace(2) @c3, i32 0, i32 1, i32 1), align 4 +// CHECK-NEXT: store i32 [[L3]], ptr [[V3]], align 4 // CHECK-NEXT: ret void void arr_assign10() { - int C[2][2] = {1,2,3,4}; + int C[2][2]; C = c3; } // CHECK-LABEL: define hidden void {{.*}}arr_assign11 -// CHECK: [[C:%.*]] = alloca [1 x %struct.S], align 1 -// CHECK: call void @llvm.memcpy.p0.p2.i32(ptr align 1 [[C]], ptr addrspace(2) align 1 @c4, i32 8, i1 false) +// CHECK: [[C:%.*]] = alloca [2 x %struct.S], align 1 +// CHECK-NEXT: [[V0:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[C]], i32 0, i32 0, i32 0 +// CHECK-NEXT: [[L0:%.*]] = load i32, ptr addrspace(2) @c4, align 4 +// CHECK-NEXT: store i32 [[L0]], ptr [[V0]], align 4 +// CHECK-NEXT: [[V1:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[C]], i32 0, i32 0, i32 1 +// CHECK-NEXT: [[L1:%.*]] = load float, ptr addrspace(2) getelementptr inbounds (<{ [1 x <{ %S, target("dx.Padding", 8) }>], %S }>, ptr addrspace(2) @c4, i32 0, i32 0, i32 0, i32 0, i32 1), align 4 +// CHECK-NEXT: store float [[L1]], ptr [[V1]], align 4 +// CHECK-NEXT: [[V2:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[C]], i32 0, i32 1, i32 0 +// CHECK-NEXT: [[L2:%.*]] = load i32, ptr addrspace(2) getelementptr inbounds (<{ [1 x <{ %S, target("dx.Padding", 8) }>], %S }>, ptr addrspace(2) @c4, i32 0, i32 1, i32 0), align 4 +// CHECK-NEXT: store i32 [[L2]], ptr [[V2]], align 4 +// CHECK-NEXT: [[V3:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[C]], i32 0, i32 1, i32 1 +// CHECK-NEXT: [[L3:%.*]] = load float, ptr addrspace(2) getelementptr inbounds (<{ [1 x <{ %S, target("dx.Padding", 8) }>], %S }>, ptr addrspace(2) @c4, i32 0, i32 1, i32 1), align 4 +// CHECK-NEXT: store float [[L3]], ptr [[V3]], align 4 // CHECK-NEXT: ret void void arr_assign11() { - S s = {1, 2.0}; - S C[1] = {s}; + S C[2]; C = c4; } diff --git a/clang/test/CodeGenHLSL/BasicFeatures/MatrixConstructor.hlsl b/clang/test/CodeGenHLSL/BasicFeatures/MatrixConstructor.hlsl new file mode 100644 index 0000000..a7c0101 --- /dev/null +++ b/clang/test/CodeGenHLSL/BasicFeatures/MatrixConstructor.hlsl @@ -0,0 +1,95 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6 +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -disable-llvm-passes -emit-llvm -finclude-default-header -o - %s | FileCheck %s + +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <6 x float> @_Z5case1v( +// CHECK-SAME: ) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret <6 x float> <float 0.000000e+00, float 2.000000e+00, float 4.000000e+00, float 1.000000e+00, float 3.000000e+00, float 5.000000e+00> +// +float3x2 case1() { + // vec[0] = 0 + // vec[1] = 2 + // vec[2] = 4 + // vec[3] = 1 + // vec[4] = 3 + // vec[5] = 5 + return float3x2(0, 1, + 2, 3, + 4, 5); +} + + +RWStructuredBuffer<float> In; + +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <6 x float> @_Z5case2v( +// CHECK-SAME: ) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[CALL:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN4hlsl18RWStructuredBufferIfEixEj(ptr noundef nonnull align 4 dereferenceable(8) @_ZL2In, i32 noundef 0) #[[ATTR3:[0-9]+]] +// CHECK-NEXT: [[CALL1:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN4hlsl18RWStructuredBufferIfEixEj(ptr noundef nonnull align 4 dereferenceable(8) @_ZL2In, i32 noundef 1) #[[ATTR3]] +// CHECK-NEXT: [[CALL2:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN4hlsl18RWStructuredBufferIfEixEj(ptr noundef nonnull align 4 dereferenceable(8) @_ZL2In, i32 noundef 2) #[[ATTR3]] +// CHECK-NEXT: [[CALL3:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN4hlsl18RWStructuredBufferIfEixEj(ptr noundef nonnull align 4 dereferenceable(8) @_ZL2In, i32 noundef 3) #[[ATTR3]] +// CHECK-NEXT: [[CALL4:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN4hlsl18RWStructuredBufferIfEixEj(ptr noundef nonnull align 4 dereferenceable(8) @_ZL2In, i32 noundef 4) #[[ATTR3]] +// CHECK-NEXT: [[CALL5:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN4hlsl18RWStructuredBufferIfEixEj(ptr noundef nonnull align 4 dereferenceable(8) @_ZL2In, i32 noundef 5) #[[ATTR3]] +// CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[CALL]], align 4 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <6 x float> poison, float [[TMP0]], i32 0 +// CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[CALL2]], align 4 +// CHECK-NEXT: [[VECINIT6:%.*]] = insertelement <6 x float> [[VECINIT]], float [[TMP1]], i32 1 +// CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[CALL4]], align 4 +// CHECK-NEXT: [[VECINIT7:%.*]] = insertelement <6 x float> [[VECINIT6]], float [[TMP2]], i32 2 +// CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[CALL1]], align 4 +// CHECK-NEXT: [[VECINIT8:%.*]] = insertelement <6 x float> [[VECINIT7]], float [[TMP3]], i32 3 +// CHECK-NEXT: [[TMP4:%.*]] = load float, ptr [[CALL3]], align 4 +// CHECK-NEXT: [[VECINIT9:%.*]] = insertelement <6 x float> [[VECINIT8]], float [[TMP4]], i32 4 +// CHECK-NEXT: [[TMP5:%.*]] = load float, ptr [[CALL5]], align 4 +// CHECK-NEXT: [[VECINIT10:%.*]] = insertelement <6 x float> [[VECINIT9]], float [[TMP5]], i32 5 +// CHECK-NEXT: ret <6 x float> [[VECINIT10]] +// +float3x2 case2() { + // vec[0] = Call + // vec[1] = Call2 + // vec[2] = Call4 + // vec[3] = Call1 + // vec[4] = Call3 + // vec[5] = Call5 + return float3x2(In[0], In[1], + In[2], In[3], + In[4], In[5]); +} + + +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <6 x float> @_Z5case3Dv3_fS_( +// CHECK-SAME: <3 x float> noundef nofpclass(nan inf) [[A:%.*]], <3 x float> noundef nofpclass(nan inf) [[B:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca <3 x float>, align 16 +// CHECK-NEXT: [[B_ADDR:%.*]] = alloca <3 x float>, align 16 +// CHECK-NEXT: store <3 x float> [[A]], ptr [[A_ADDR]], align 16 +// CHECK-NEXT: store <3 x float> [[B]], ptr [[B_ADDR]], align 16 +// CHECK-NEXT: [[TMP0:%.*]] = load <3 x float>, ptr [[A_ADDR]], align 16 +// CHECK-NEXT: [[VECEXT:%.*]] = extractelement <3 x float> [[TMP0]], i64 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <6 x float> poison, float [[VECEXT]], i32 0 +// CHECK-NEXT: [[TMP1:%.*]] = load <3 x float>, ptr [[A_ADDR]], align 16 +// CHECK-NEXT: [[VECEXT1:%.*]] = extractelement <3 x float> [[TMP1]], i64 2 +// CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <6 x float> [[VECINIT]], float [[VECEXT1]], i32 1 +// CHECK-NEXT: [[TMP2:%.*]] = load <3 x float>, ptr [[B_ADDR]], align 16 +// CHECK-NEXT: [[VECEXT3:%.*]] = extractelement <3 x float> [[TMP2]], i64 1 +// CHECK-NEXT: [[VECINIT4:%.*]] = insertelement <6 x float> [[VECINIT2]], float [[VECEXT3]], i32 2 +// CHECK-NEXT: [[TMP3:%.*]] = load <3 x float>, ptr [[A_ADDR]], align 16 +// CHECK-NEXT: [[VECEXT5:%.*]] = extractelement <3 x float> [[TMP3]], i64 1 +// CHECK-NEXT: [[VECINIT6:%.*]] = insertelement <6 x float> [[VECINIT4]], float [[VECEXT5]], i32 3 +// CHECK-NEXT: [[TMP4:%.*]] = load <3 x float>, ptr [[B_ADDR]], align 16 +// CHECK-NEXT: [[VECEXT7:%.*]] = extractelement <3 x float> [[TMP4]], i64 0 +// CHECK-NEXT: [[VECINIT8:%.*]] = insertelement <6 x float> [[VECINIT6]], float [[VECEXT7]], i32 4 +// CHECK-NEXT: [[TMP5:%.*]] = load <3 x float>, ptr [[B_ADDR]], align 16 +// CHECK-NEXT: [[VECEXT9:%.*]] = extractelement <3 x float> [[TMP5]], i64 2 +// CHECK-NEXT: [[VECINIT10:%.*]] = insertelement <6 x float> [[VECINIT8]], float [[VECEXT9]], i32 5 +// CHECK-NEXT: ret <6 x float> [[VECINIT10]] +// +float3x2 case3(float3 a, float3 b) { + // vec[0] = A[0] + // vec[1] = A[2] + // vec[2] = B[1] + // vec[3] = A[1] + // vec[4] = B[0] + // vec[5] = B[2] + return float3x2(a,b); +} diff --git a/clang/test/CodeGenHLSL/BasicFeatures/MatrixElementTypeCast.hlsl b/clang/test/CodeGenHLSL/BasicFeatures/MatrixElementTypeCast.hlsl new file mode 100644 index 0000000..3bd7636 --- /dev/null +++ b/clang/test/CodeGenHLSL/BasicFeatures/MatrixElementTypeCast.hlsl @@ -0,0 +1,219 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6 +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -disable-llvm-passes -fnative-half-type -fnative-int16-type -o - %s | FileCheck %s + + +// CHECK-LABEL: define hidden noundef <6 x i32> @_Z22elementwise_type_cast0u11matrix_typeILm3ELm2EfE( +// CHECK-SAME: <6 x float> noundef nofpclass(nan inf) [[F32:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[F32_ADDR:%.*]] = alloca [6 x float], align 4 +// CHECK-NEXT: [[I32:%.*]] = alloca [6 x i32], align 4 +// CHECK-NEXT: store <6 x float> [[F32]], ptr [[F32_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load <6 x float>, ptr [[F32_ADDR]], align 4 +// CHECK-NEXT: [[CONV:%.*]] = fptosi <6 x float> [[TMP0]] to <6 x i32> +// CHECK-NEXT: store <6 x i32> [[CONV]], ptr [[I32]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load <6 x i32>, ptr [[I32]], align 4 +// CHECK-NEXT: ret <6 x i32> [[TMP1]] +// +int3x2 elementwise_type_cast0(float3x2 f32) { + int3x2 i32 = (int3x2)f32; + return i32; +} + +// CHECK-LABEL: define hidden noundef <6 x i32> @_Z22elementwise_type_cast1u11matrix_typeILm3ELm2EsE( +// CHECK-SAME: <6 x i16> noundef [[I16_32:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[I16_32_ADDR:%.*]] = alloca [6 x i16], align 2 +// CHECK-NEXT: [[I32:%.*]] = alloca [6 x i32], align 4 +// CHECK-NEXT: store <6 x i16> [[I16_32]], ptr [[I16_32_ADDR]], align 2 +// CHECK-NEXT: [[TMP0:%.*]] = load <6 x i16>, ptr [[I16_32_ADDR]], align 2 +// CHECK-NEXT: [[CONV:%.*]] = sext <6 x i16> [[TMP0]] to <6 x i32> +// CHECK-NEXT: store <6 x i32> [[CONV]], ptr [[I32]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load <6 x i32>, ptr [[I32]], align 4 +// CHECK-NEXT: ret <6 x i32> [[TMP1]] +// +int3x2 elementwise_type_cast1(int16_t3x2 i16_32) { + int3x2 i32 = (int3x2)i16_32; + return i32; +} + +// CHECK-LABEL: define hidden noundef <6 x i32> @_Z22elementwise_type_cast2u11matrix_typeILm3ELm2ElE( +// CHECK-SAME: <6 x i64> noundef [[I64_32:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[I64_32_ADDR:%.*]] = alloca [6 x i64], align 8 +// CHECK-NEXT: [[I32:%.*]] = alloca [6 x i32], align 4 +// CHECK-NEXT: store <6 x i64> [[I64_32]], ptr [[I64_32_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load <6 x i64>, ptr [[I64_32_ADDR]], align 8 +// CHECK-NEXT: [[CONV:%.*]] = trunc <6 x i64> [[TMP0]] to <6 x i32> +// CHECK-NEXT: store <6 x i32> [[CONV]], ptr [[I32]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load <6 x i32>, ptr [[I32]], align 4 +// CHECK-NEXT: ret <6 x i32> [[TMP1]] +// +int3x2 elementwise_type_cast2(int64_t3x2 i64_32) { + int3x2 i32 = (int3x2)i64_32; + return i32; +} + +// CHECK-LABEL: define hidden noundef <6 x i16> @_Z22elementwise_type_cast3u11matrix_typeILm2ELm3EDhE( +// CHECK-SAME: <6 x half> noundef nofpclass(nan inf) [[H23:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[H23_ADDR:%.*]] = alloca [6 x half], align 2 +// CHECK-NEXT: [[I23:%.*]] = alloca [6 x i16], align 2 +// CHECK-NEXT: store <6 x half> [[H23]], ptr [[H23_ADDR]], align 2 +// CHECK-NEXT: [[TMP0:%.*]] = load <6 x half>, ptr [[H23_ADDR]], align 2 +// CHECK-NEXT: [[CONV:%.*]] = fptosi <6 x half> [[TMP0]] to <6 x i16> +// CHECK-NEXT: store <6 x i16> [[CONV]], ptr [[I23]], align 2 +// CHECK-NEXT: [[TMP1:%.*]] = load <6 x i16>, ptr [[I23]], align 2 +// CHECK-NEXT: ret <6 x i16> [[TMP1]] +// +int16_t2x3 elementwise_type_cast3(half2x3 h23) { + int16_t2x3 i23 = (int16_t2x3)h23; + return i23; +} + +// CHECK-LABEL: define hidden noundef <6 x i32> @_Z22elementwise_type_cast4u11matrix_typeILm3ELm2EdE( +// CHECK-SAME: <6 x double> noundef nofpclass(nan inf) [[D32:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[D32_ADDR:%.*]] = alloca [6 x double], align 8 +// CHECK-NEXT: [[I32:%.*]] = alloca [6 x i32], align 4 +// CHECK-NEXT: store <6 x double> [[D32]], ptr [[D32_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load <6 x double>, ptr [[D32_ADDR]], align 8 +// CHECK-NEXT: [[CONV:%.*]] = fptosi <6 x double> [[TMP0]] to <6 x i32> +// CHECK-NEXT: store <6 x i32> [[CONV]], ptr [[I32]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load <6 x i32>, ptr [[I32]], align 4 +// CHECK-NEXT: ret <6 x i32> [[TMP1]] +// +int3x2 elementwise_type_cast4(double3x2 d32) { + int3x2 i32 = (int3x2)d32; + return i32; +} + +// CHECK-LABEL: define hidden void @_Z5call2v( +// CHECK-SAME: ) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[A:%.*]] = alloca [2 x [1 x i32]], align 4 +// CHECK-NEXT: [[B:%.*]] = alloca [2 x i32], align 4 +// CHECK-NEXT: [[AGG_TEMP:%.*]] = alloca [2 x [1 x i32]], align 4 +// CHECK-NEXT: [[FLATCAST_TMP:%.*]] = alloca <2 x i32>, align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 @__const._Z5call2v.A, i32 8, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[AGG_TEMP]], ptr align 4 [[A]], i32 8, i1 false) +// CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [2 x [1 x i32]], ptr [[AGG_TEMP]], i32 0, i32 0, i32 0 +// CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [2 x [1 x i32]], ptr [[AGG_TEMP]], i32 0, i32 1, i32 0 +// CHECK-NEXT: [[TMP0:%.*]] = load <2 x i32>, ptr [[FLATCAST_TMP]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[GEP]], align 4 +// CHECK-NEXT: [[TMP2:%.*]] = insertelement <2 x i32> [[TMP0]], i32 [[TMP1]], i64 0 +// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[GEP1]], align 4 +// CHECK-NEXT: [[TMP4:%.*]] = insertelement <2 x i32> [[TMP2]], i32 [[TMP3]], i64 1 +// CHECK-NEXT: store <2 x i32> [[TMP4]], ptr [[B]], align 4 +// CHECK-NEXT: ret void +// +void call2() { + int A[2][1] = {{1},{2}}; + int2x1 B = (int2x1)A; +} + +struct S { + int X; + float Y; +}; + +// CHECK-LABEL: define hidden void @_Z5call3v( +// CHECK-SAME: ) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[S:%.*]] = alloca [[STRUCT_S:%.*]], align 1 +// CHECK-NEXT: [[A:%.*]] = alloca [2 x i32], align 4 +// CHECK-NEXT: [[AGG_TEMP:%.*]] = alloca [[STRUCT_S]], align 1 +// CHECK-NEXT: [[FLATCAST_TMP:%.*]] = alloca <2 x i32>, align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[S]], ptr align 1 @__const._Z5call3v.s, i32 8, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[AGG_TEMP]], ptr align 1 [[S]], i32 8, i1 false) +// CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_TEMP]], i32 0, i32 0 +// CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_TEMP]], i32 0, i32 1 +// CHECK-NEXT: [[TMP0:%.*]] = load <2 x i32>, ptr [[FLATCAST_TMP]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[GEP]], align 4 +// CHECK-NEXT: [[TMP2:%.*]] = insertelement <2 x i32> [[TMP0]], i32 [[TMP1]], i64 0 +// CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[GEP1]], align 4 +// CHECK-NEXT: [[CONV:%.*]] = fptosi float [[TMP3]] to i32 +// CHECK-NEXT: [[TMP4:%.*]] = insertelement <2 x i32> [[TMP2]], i32 [[CONV]], i64 1 +// CHECK-NEXT: store <2 x i32> [[TMP4]], ptr [[A]], align 4 +// CHECK-NEXT: ret void +// +void call3() { + S s = {1, 2.0}; + int2x1 A = (int2x1)s; +} + +struct BFields { + double D; + int E: 15; + int : 8; + float F; +}; + +struct Derived : BFields { + int G; +}; + +// CHECK-LABEL: define hidden void @_Z5call47Derived( +// CHECK-SAME: ptr noundef byval([[STRUCT_DERIVED:%.*]]) align 1 [[D:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[A:%.*]] = alloca [4 x i32], align 4 +// CHECK-NEXT: [[AGG_TEMP:%.*]] = alloca [[STRUCT_DERIVED]], align 1 +// CHECK-NEXT: [[FLATCAST_TMP:%.*]] = alloca <4 x i32>, align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[AGG_TEMP]], ptr align 1 [[D]], i32 19, i1 false) +// CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [[STRUCT_DERIVED]], ptr [[AGG_TEMP]], i32 0, i32 0 +// CHECK-NEXT: [[E:%.*]] = getelementptr inbounds nuw [[STRUCT_BFIELDS:%.*]], ptr [[GEP]], i32 0, i32 1 +// CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [[STRUCT_DERIVED]], ptr [[AGG_TEMP]], i32 0, i32 0, i32 0 +// CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds [[STRUCT_DERIVED]], ptr [[AGG_TEMP]], i32 0, i32 0, i32 2 +// CHECK-NEXT: [[GEP3:%.*]] = getelementptr inbounds [[STRUCT_DERIVED]], ptr [[AGG_TEMP]], i32 0, i32 1 +// CHECK-NEXT: [[TMP0:%.*]] = load <4 x i32>, ptr [[FLATCAST_TMP]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load double, ptr [[GEP1]], align 8 +// CHECK-NEXT: [[CONV:%.*]] = fptosi double [[TMP1]] to i32 +// CHECK-NEXT: [[TMP2:%.*]] = insertelement <4 x i32> [[TMP0]], i32 [[CONV]], i64 0 +// CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[GEP2]], align 4 +// CHECK-NEXT: [[CONV4:%.*]] = fptosi float [[TMP3]] to i32 +// CHECK-NEXT: [[TMP4:%.*]] = insertelement <4 x i32> [[TMP2]], i32 [[CONV4]], i64 1 +// CHECK-NEXT: [[BF_LOAD:%.*]] = load i24, ptr [[E]], align 1 +// CHECK-NEXT: [[BF_SHL:%.*]] = shl i24 [[BF_LOAD]], 9 +// CHECK-NEXT: [[BF_ASHR:%.*]] = ashr i24 [[BF_SHL]], 9 +// CHECK-NEXT: [[BF_CAST:%.*]] = sext i24 [[BF_ASHR]] to i32 +// CHECK-NEXT: [[TMP5:%.*]] = insertelement <4 x i32> [[TMP4]], i32 [[BF_CAST]], i64 2 +// CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[GEP3]], align 4 +// CHECK-NEXT: [[TMP7:%.*]] = insertelement <4 x i32> [[TMP5]], i32 [[TMP6]], i64 3 +// CHECK-NEXT: store <4 x i32> [[TMP7]], ptr [[A]], align 4 +// CHECK-NEXT: ret void +// +void call4(Derived D) { + int2x2 A = (int2x2)D; +} + +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z5call5Dv4_f( +// CHECK-SAME: <4 x float> noundef nofpclass(nan inf) [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[V_ADDR:%.*]] = alloca <4 x float>, align 16 +// CHECK-NEXT: [[M:%.*]] = alloca [4 x float], align 4 +// CHECK-NEXT: [[HLSL_EWCAST_SRC:%.*]] = alloca <4 x float>, align 16 +// CHECK-NEXT: [[FLATCAST_TMP:%.*]] = alloca <4 x float>, align 4 +// CHECK-NEXT: store <4 x float> [[V]], ptr [[V_ADDR]], align 16 +// CHECK-NEXT: [[TMP0:%.*]] = load <4 x float>, ptr [[V_ADDR]], align 16 +// CHECK-NEXT: store <4 x float> [[TMP0]], ptr [[HLSL_EWCAST_SRC]], align 16 +// CHECK-NEXT: [[VECTOR_GEP:%.*]] = getelementptr inbounds <4 x float>, ptr [[HLSL_EWCAST_SRC]], i32 0 +// CHECK-NEXT: [[TMP1:%.*]] = load <4 x float>, ptr [[FLATCAST_TMP]], align 4 +// CHECK-NEXT: [[TMP2:%.*]] = load <4 x float>, ptr [[VECTOR_GEP]], align 16 +// CHECK-NEXT: [[VECEXT:%.*]] = extractelement <4 x float> [[TMP2]], i32 0 +// CHECK-NEXT: [[TMP3:%.*]] = insertelement <4 x float> [[TMP1]], float [[VECEXT]], i64 0 +// CHECK-NEXT: [[TMP4:%.*]] = load <4 x float>, ptr [[VECTOR_GEP]], align 16 +// CHECK-NEXT: [[VECEXT1:%.*]] = extractelement <4 x float> [[TMP4]], i32 2 +// CHECK-NEXT: [[TMP5:%.*]] = insertelement <4 x float> [[TMP3]], float [[VECEXT1]], i64 1 +// CHECK-NEXT: [[TMP6:%.*]] = load <4 x float>, ptr [[VECTOR_GEP]], align 16 +// CHECK-NEXT: [[VECEXT2:%.*]] = extractelement <4 x float> [[TMP6]], i32 1 +// CHECK-NEXT: [[TMP7:%.*]] = insertelement <4 x float> [[TMP5]], float [[VECEXT2]], i64 2 +// CHECK-NEXT: [[TMP8:%.*]] = load <4 x float>, ptr [[VECTOR_GEP]], align 16 +// CHECK-NEXT: [[VECEXT3:%.*]] = extractelement <4 x float> [[TMP8]], i32 3 +// CHECK-NEXT: [[TMP9:%.*]] = insertelement <4 x float> [[TMP7]], float [[VECEXT3]], i64 3 +// CHECK-NEXT: store <4 x float> [[TMP9]], ptr [[M]], align 4 +// CHECK-NEXT: [[TMP10:%.*]] = load <4 x float>, ptr [[M]], align 4 +// CHECK-NEXT: ret <4 x float> [[TMP10]] +// +float2x2 call5(float4 v) { + float2x2 m = (float2x2)v; + return m; +} diff --git a/clang/test/CodeGenHLSL/BasicFeatures/MatrixExplicitTruncation.hlsl b/clang/test/CodeGenHLSL/BasicFeatures/MatrixExplicitTruncation.hlsl new file mode 100644 index 0000000..f3c4bc4 --- /dev/null +++ b/clang/test/CodeGenHLSL/BasicFeatures/MatrixExplicitTruncation.hlsl @@ -0,0 +1,156 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6 +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.7-library -disable-llvm-passes -emit-llvm -finclude-default-header -o - %s | FileCheck %s + +// CHECK-LABEL: define hidden noundef <12 x i32> @_Z10trunc_castu11matrix_typeILm4ELm4EiE( +// CHECK-SAME: <16 x i32> noundef [[I44:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[I44_ADDR:%.*]] = alloca [16 x i32], align 4 +// CHECK-NEXT: [[I34:%.*]] = alloca [12 x i32], align 4 +// CHECK-NEXT: store <16 x i32> [[I44]], ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load <16 x i32>, ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TRUNC:%.*]] = shufflevector <16 x i32> [[TMP0]], <16 x i32> poison, <12 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11> +// CHECK-NEXT: store <12 x i32> [[TRUNC]], ptr [[I34]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load <12 x i32>, ptr [[I34]], align 4 +// CHECK-NEXT: ret <12 x i32> [[TMP1]] +// + int3x4 trunc_cast(int4x4 i44) { + int3x4 i34 = (int3x4)i44; + return i34; +} + +// CHECK-LABEL: define hidden noundef <12 x i32> @_Z11trunc_cast0u11matrix_typeILm4ELm4EiE( +// CHECK-SAME: <16 x i32> noundef [[I44:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[I44_ADDR:%.*]] = alloca [16 x i32], align 4 +// CHECK-NEXT: [[I43:%.*]] = alloca [12 x i32], align 4 +// CHECK-NEXT: store <16 x i32> [[I44]], ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load <16 x i32>, ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TRUNC:%.*]] = shufflevector <16 x i32> [[TMP0]], <16 x i32> poison, <12 x i32> <i32 0, i32 1, i32 2, i32 4, i32 5, i32 6, i32 8, i32 9, i32 10, i32 12, i32 13, i32 14> +// CHECK-NEXT: store <12 x i32> [[TRUNC]], ptr [[I43]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load <12 x i32>, ptr [[I43]], align 4 +// CHECK-NEXT: ret <12 x i32> [[TMP1]] +// + int4x3 trunc_cast0(int4x4 i44) { + int4x3 i43 = (int4x3)i44; + return i43; +} + +// CHECK-LABEL: define hidden noundef <9 x i32> @_Z11trunc_cast1u11matrix_typeILm4ELm4EiE( +// CHECK-SAME: <16 x i32> noundef [[I44:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[I44_ADDR:%.*]] = alloca [16 x i32], align 4 +// CHECK-NEXT: [[I33:%.*]] = alloca [9 x i32], align 4 +// CHECK-NEXT: store <16 x i32> [[I44]], ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load <16 x i32>, ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TRUNC:%.*]] = shufflevector <16 x i32> [[TMP0]], <16 x i32> poison, <9 x i32> <i32 0, i32 1, i32 2, i32 4, i32 5, i32 6, i32 8, i32 9, i32 10> +// CHECK-NEXT: store <9 x i32> [[TRUNC]], ptr [[I33]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load <9 x i32>, ptr [[I33]], align 4 +// CHECK-NEXT: ret <9 x i32> [[TMP1]] +// + int3x3 trunc_cast1(int4x4 i44) { + int3x3 i33 = (int3x3)i44; + return i33; +} + +// CHECK-LABEL: define hidden noundef <6 x i32> @_Z11trunc_cast2u11matrix_typeILm4ELm4EiE( +// CHECK-SAME: <16 x i32> noundef [[I44:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[I44_ADDR:%.*]] = alloca [16 x i32], align 4 +// CHECK-NEXT: [[I32:%.*]] = alloca [6 x i32], align 4 +// CHECK-NEXT: store <16 x i32> [[I44]], ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load <16 x i32>, ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TRUNC:%.*]] = shufflevector <16 x i32> [[TMP0]], <16 x i32> poison, <6 x i32> <i32 0, i32 1, i32 4, i32 5, i32 8, i32 9> +// CHECK-NEXT: store <6 x i32> [[TRUNC]], ptr [[I32]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load <6 x i32>, ptr [[I32]], align 4 +// CHECK-NEXT: ret <6 x i32> [[TMP1]] +// + int3x2 trunc_cast2(int4x4 i44) { + int3x2 i32 = (int3x2)i44; + return i32; +} + +// CHECK-LABEL: define hidden noundef <6 x i32> @_Z11trunc_cast3u11matrix_typeILm4ELm4EiE( +// CHECK-SAME: <16 x i32> noundef [[I44:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[I44_ADDR:%.*]] = alloca [16 x i32], align 4 +// CHECK-NEXT: [[I23:%.*]] = alloca [6 x i32], align 4 +// CHECK-NEXT: store <16 x i32> [[I44]], ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load <16 x i32>, ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TRUNC:%.*]] = shufflevector <16 x i32> [[TMP0]], <16 x i32> poison, <6 x i32> <i32 0, i32 1, i32 2, i32 4, i32 5, i32 6> +// CHECK-NEXT: store <6 x i32> [[TRUNC]], ptr [[I23]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load <6 x i32>, ptr [[I23]], align 4 +// CHECK-NEXT: ret <6 x i32> [[TMP1]] +// + int2x3 trunc_cast3(int4x4 i44) { + int2x3 i23 = (int2x3)i44; + return i23; +} + +// CHECK-LABEL: define hidden noundef <4 x i32> @_Z11trunc_cast4u11matrix_typeILm4ELm4EiE( +// CHECK-SAME: <16 x i32> noundef [[I44:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[I44_ADDR:%.*]] = alloca [16 x i32], align 4 +// CHECK-NEXT: [[I22:%.*]] = alloca [4 x i32], align 4 +// CHECK-NEXT: store <16 x i32> [[I44]], ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load <16 x i32>, ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TRUNC:%.*]] = shufflevector <16 x i32> [[TMP0]], <16 x i32> poison, <4 x i32> <i32 0, i32 1, i32 4, i32 5> +// CHECK-NEXT: store <4 x i32> [[TRUNC]], ptr [[I22]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr [[I22]], align 4 +// CHECK-NEXT: ret <4 x i32> [[TMP1]] +// + int2x2 trunc_cast4(int4x4 i44) { + int2x2 i22 = (int2x2)i44; + return i22; +} + +// CHECK-LABEL: define hidden noundef <2 x i32> @_Z11trunc_cast5u11matrix_typeILm4ELm4EiE( +// CHECK-SAME: <16 x i32> noundef [[I44:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[I44_ADDR:%.*]] = alloca [16 x i32], align 4 +// CHECK-NEXT: [[I21:%.*]] = alloca [2 x i32], align 4 +// CHECK-NEXT: store <16 x i32> [[I44]], ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load <16 x i32>, ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TRUNC:%.*]] = shufflevector <16 x i32> [[TMP0]], <16 x i32> poison, <2 x i32> <i32 0, i32 4> +// CHECK-NEXT: store <2 x i32> [[TRUNC]], ptr [[I21]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load <2 x i32>, ptr [[I21]], align 4 +// CHECK-NEXT: ret <2 x i32> [[TMP1]] +// + int2x1 trunc_cast5(int4x4 i44) { + int2x1 i21 = (int2x1)i44; + return i21; +} + +// CHECK-LABEL: define hidden noundef i32 @_Z11trunc_cast6u11matrix_typeILm4ELm4EiE( +// CHECK-SAME: <16 x i32> noundef [[I44:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[I44_ADDR:%.*]] = alloca [16 x i32], align 4 +// CHECK-NEXT: [[I1:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store <16 x i32> [[I44]], ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load <16 x i32>, ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[CAST_MTRUNC:%.*]] = extractelement <16 x i32> [[TMP0]], i32 0 +// CHECK-NEXT: store i32 [[CAST_MTRUNC]], ptr [[I1]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[I1]], align 4 +// CHECK-NEXT: ret i32 [[TMP1]] +// + int trunc_cast6(int4x4 i44) { + int i1 = (int)i44; + return i1; +} + +// CHECK-LABEL: define hidden noundef i32 @_Z16trunc_multi_castu11matrix_typeILm4ELm4EiE( +// CHECK-SAME: <16 x i32> noundef [[I44:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[I44_ADDR:%.*]] = alloca [16 x i32], align 4 +// CHECK-NEXT: [[I1:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store <16 x i32> [[I44]], ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load <16 x i32>, ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TRUNC:%.*]] = shufflevector <16 x i32> [[TMP0]], <16 x i32> poison, <12 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11> +// CHECK-NEXT: [[CAST_MTRUNC:%.*]] = extractelement <12 x i32> [[TRUNC]], i32 0 +// CHECK-NEXT: store i32 [[CAST_MTRUNC]], ptr [[I1]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[I1]], align 4 +// CHECK-NEXT: ret i32 [[TMP1]] +// + int trunc_multi_cast(int4x4 i44) { + int i1 = (int)(int3x4)i44; + return i1; +} diff --git a/clang/test/CodeGenHLSL/BasicFeatures/MatrixImplicitTruncation.hlsl b/clang/test/CodeGenHLSL/BasicFeatures/MatrixImplicitTruncation.hlsl new file mode 100644 index 0000000..e621f68 --- /dev/null +++ b/clang/test/CodeGenHLSL/BasicFeatures/MatrixImplicitTruncation.hlsl @@ -0,0 +1,138 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6 +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.7-library -disable-llvm-passes -emit-llvm -finclude-default-header -o - %s | FileCheck %s + +// CHECK-LABEL: define hidden noundef <12 x i32> @_Z10trunc_castu11matrix_typeILm4ELm4EiE( +// CHECK-SAME: <16 x i32> noundef [[I44:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[I44_ADDR:%.*]] = alloca [16 x i32], align 4 +// CHECK-NEXT: [[I34:%.*]] = alloca [12 x i32], align 4 +// CHECK-NEXT: store <16 x i32> [[I44]], ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load <16 x i32>, ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TRUNC:%.*]] = shufflevector <16 x i32> [[TMP0]], <16 x i32> poison, <12 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11> +// CHECK-NEXT: store <12 x i32> [[TRUNC]], ptr [[I34]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load <12 x i32>, ptr [[I34]], align 4 +// CHECK-NEXT: ret <12 x i32> [[TMP1]] +// + int3x4 trunc_cast(int4x4 i44) { + int3x4 i34 = i44; + return i34; +} + +// CHECK-LABEL: define hidden noundef <12 x i32> @_Z11trunc_cast0u11matrix_typeILm4ELm4EiE( +// CHECK-SAME: <16 x i32> noundef [[I44:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[I44_ADDR:%.*]] = alloca [16 x i32], align 4 +// CHECK-NEXT: [[I43:%.*]] = alloca [12 x i32], align 4 +// CHECK-NEXT: store <16 x i32> [[I44]], ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load <16 x i32>, ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TRUNC:%.*]] = shufflevector <16 x i32> [[TMP0]], <16 x i32> poison, <12 x i32> <i32 0, i32 1, i32 2, i32 4, i32 5, i32 6, i32 8, i32 9, i32 10, i32 12, i32 13, i32 14> +// CHECK-NEXT: store <12 x i32> [[TRUNC]], ptr [[I43]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load <12 x i32>, ptr [[I43]], align 4 +// CHECK-NEXT: ret <12 x i32> [[TMP1]] +// + int4x3 trunc_cast0(int4x4 i44) { + int4x3 i43 = i44; + return i43; +} + +// CHECK-LABEL: define hidden noundef <9 x i32> @_Z11trunc_cast1u11matrix_typeILm4ELm4EiE( +// CHECK-SAME: <16 x i32> noundef [[I44:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[I44_ADDR:%.*]] = alloca [16 x i32], align 4 +// CHECK-NEXT: [[I33:%.*]] = alloca [9 x i32], align 4 +// CHECK-NEXT: store <16 x i32> [[I44]], ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load <16 x i32>, ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TRUNC:%.*]] = shufflevector <16 x i32> [[TMP0]], <16 x i32> poison, <9 x i32> <i32 0, i32 1, i32 2, i32 4, i32 5, i32 6, i32 8, i32 9, i32 10> +// CHECK-NEXT: store <9 x i32> [[TRUNC]], ptr [[I33]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load <9 x i32>, ptr [[I33]], align 4 +// CHECK-NEXT: ret <9 x i32> [[TMP1]] +// + int3x3 trunc_cast1(int4x4 i44) { + int3x3 i33 = i44; + return i33; +} + +// CHECK-LABEL: define hidden noundef <6 x i32> @_Z11trunc_cast2u11matrix_typeILm4ELm4EiE( +// CHECK-SAME: <16 x i32> noundef [[I44:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[I44_ADDR:%.*]] = alloca [16 x i32], align 4 +// CHECK-NEXT: [[I32:%.*]] = alloca [6 x i32], align 4 +// CHECK-NEXT: store <16 x i32> [[I44]], ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load <16 x i32>, ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TRUNC:%.*]] = shufflevector <16 x i32> [[TMP0]], <16 x i32> poison, <6 x i32> <i32 0, i32 1, i32 4, i32 5, i32 8, i32 9> +// CHECK-NEXT: store <6 x i32> [[TRUNC]], ptr [[I32]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load <6 x i32>, ptr [[I32]], align 4 +// CHECK-NEXT: ret <6 x i32> [[TMP1]] +// + int3x2 trunc_cast2(int4x4 i44) { + int3x2 i32 = i44; + return i32; +} + +// CHECK-LABEL: define hidden noundef <6 x i32> @_Z11trunc_cast3u11matrix_typeILm4ELm4EiE( +// CHECK-SAME: <16 x i32> noundef [[I44:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[I44_ADDR:%.*]] = alloca [16 x i32], align 4 +// CHECK-NEXT: [[I23:%.*]] = alloca [6 x i32], align 4 +// CHECK-NEXT: store <16 x i32> [[I44]], ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load <16 x i32>, ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TRUNC:%.*]] = shufflevector <16 x i32> [[TMP0]], <16 x i32> poison, <6 x i32> <i32 0, i32 1, i32 2, i32 4, i32 5, i32 6> +// CHECK-NEXT: store <6 x i32> [[TRUNC]], ptr [[I23]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load <6 x i32>, ptr [[I23]], align 4 +// CHECK-NEXT: ret <6 x i32> [[TMP1]] +// + int2x3 trunc_cast3(int4x4 i44) { + int2x3 i23 = i44; + return i23; +} + +// CHECK-LABEL: define hidden noundef <4 x i32> @_Z11trunc_cast4u11matrix_typeILm4ELm4EiE( +// CHECK-SAME: <16 x i32> noundef [[I44:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[I44_ADDR:%.*]] = alloca [16 x i32], align 4 +// CHECK-NEXT: [[I22:%.*]] = alloca [4 x i32], align 4 +// CHECK-NEXT: store <16 x i32> [[I44]], ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load <16 x i32>, ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TRUNC:%.*]] = shufflevector <16 x i32> [[TMP0]], <16 x i32> poison, <4 x i32> <i32 0, i32 1, i32 4, i32 5> +// CHECK-NEXT: store <4 x i32> [[TRUNC]], ptr [[I22]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr [[I22]], align 4 +// CHECK-NEXT: ret <4 x i32> [[TMP1]] +// + int2x2 trunc_cast4(int4x4 i44) { + int2x2 i22 = i44; + return i22; +} + +// CHECK-LABEL: define hidden noundef <2 x i32> @_Z11trunc_cast5u11matrix_typeILm4ELm4EiE( +// CHECK-SAME: <16 x i32> noundef [[I44:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[I44_ADDR:%.*]] = alloca [16 x i32], align 4 +// CHECK-NEXT: [[I21:%.*]] = alloca [2 x i32], align 4 +// CHECK-NEXT: store <16 x i32> [[I44]], ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load <16 x i32>, ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TRUNC:%.*]] = shufflevector <16 x i32> [[TMP0]], <16 x i32> poison, <2 x i32> <i32 0, i32 4> +// CHECK-NEXT: store <2 x i32> [[TRUNC]], ptr [[I21]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load <2 x i32>, ptr [[I21]], align 4 +// CHECK-NEXT: ret <2 x i32> [[TMP1]] +// + int2x1 trunc_cast5(int4x4 i44) { + int2x1 i21 = i44; + return i21; +} + +// CHECK-LABEL: define hidden noundef i32 @_Z11trunc_cast6u11matrix_typeILm4ELm4EiE( +// CHECK-SAME: <16 x i32> noundef [[I44:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[I44_ADDR:%.*]] = alloca [16 x i32], align 4 +// CHECK-NEXT: [[I1:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store <16 x i32> [[I44]], ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load <16 x i32>, ptr [[I44_ADDR]], align 4 +// CHECK-NEXT: [[CAST_MTRUNC:%.*]] = extractelement <16 x i32> [[TMP0]], i32 0 +// CHECK-NEXT: store i32 [[CAST_MTRUNC]], ptr [[I1]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[I1]], align 4 +// CHECK-NEXT: ret i32 [[TMP1]] +// + int trunc_cast6(int4x4 i44) { + int i1 = i44; + return i1; +} diff --git a/clang/test/CodeGenHLSL/BasicFeatures/OutputArguments.hlsl b/clang/test/CodeGenHLSL/BasicFeatures/OutputArguments.hlsl index d0ba8f4..ec03804a 100644 --- a/clang/test/CodeGenHLSL/BasicFeatures/OutputArguments.hlsl +++ b/clang/test/CodeGenHLSL/BasicFeatures/OutputArguments.hlsl @@ -101,10 +101,16 @@ void funky(inout int3 X) { // Call the function with the temporary. // CHECK: call void {{.*}}funky{{.*}}(ptr noalias noundef nonnull align 16 dereferenceable(16) [[ArgTmp]]) -// Shuffle it back. +// Write it back. // CHECK: [[RetVal:%.*]] = load <3 x i32>, ptr [[ArgTmp]] -// CHECK: [[Vxyz:%.*]] = shufflevector <3 x i32> [[RetVal]], <3 x i32> poison, <3 x i32> <i32 2, i32 0, i32 1> -// CHECK: store <3 x i32> [[Vxyz]], ptr [[V]] +// CHECK: [[Src0:%.*]] = extractelement <3 x i32> [[RetVal]], i32 0 +// CHECK: [[PtrY:%.*]] = getelementptr <3 x i32>, ptr %V, i32 0, i32 1 +// CHECK: store i32 [[Src0]], ptr [[PtrY]], align 4 +// CHECK: [[Src1:%.*]] = extractelement <3 x i32> [[RetVal]], i32 1 +// CHECK: [[PtrZ:%.*]] = getelementptr <3 x i32>, ptr %V, i32 0, i32 2 +// CHECK: store i32 [[Src1]], ptr [[PtrZ]], align 4 +// CHECK: [[Src2:%.*]] = extractelement <3 x i32> [[RetVal]], i32 2 +// CHECK: store i32 [[Src2]], ptr %V, align 4 // OPT: ret <3 x i32> <i32 3, i32 1, i32 2> export int3 case4() { diff --git a/clang/test/CodeGenHLSL/BoolVector.hlsl b/clang/test/CodeGenHLSL/BoolVector.hlsl index d5054a5..6be90e8 100644 --- a/clang/test/CodeGenHLSL/BoolVector.hlsl +++ b/clang/test/CodeGenHLSL/BoolVector.hlsl @@ -69,9 +69,8 @@ bool fn4() { // CHECK-LABEL: define hidden void {{.*}}fn5{{.*}} // CHECK: [[Arr:%.*]] = alloca <2 x i32>, align 8 // CHECK-NEXT: store <2 x i32> splat (i32 1), ptr [[Arr]], align 8 -// CHECK-NEXT: [[L:%.*]] = load <2 x i32>, ptr [[Arr]], align 8 -// CHECK-NEXT: [[V:%.*]] = insertelement <2 x i32> [[L]], i32 0, i32 1 -// CHECK-NEXT: store <2 x i32> [[V]], ptr [[Arr]], align 8 +// CHECK-NEXT: [[Ptr:%.*]] = getelementptr <2 x i32>, ptr [[Arr]] +// CHECK-NEXT: store i32 0, ptr [[Ptr]], align 4 // CHECK-NEXT: ret void void fn5() { bool2 Arr = {true,true}; @@ -86,10 +85,9 @@ void fn5() { // CHECK-NEXT: [[Y:%.*]] = load i32, ptr [[V]], align 4 // CHECK-NEXT: [[LV:%.*]] = trunc i32 [[Y]] to i1 // CHECK-NEXT: [[BV:%.*]] = getelementptr inbounds nuw %struct.S, ptr [[S]], i32 0, i32 0 -// CHECK-NEXT: [[X:%.*]] = load <2 x i32>, ptr [[BV]], align 1 // CHECK-NEXT: [[Z:%.*]] = zext i1 [[LV]] to i32 -// CHECK-NEXT: [[VI:%.*]] = insertelement <2 x i32> [[X]], i32 [[Z]], i32 1 -// CHECK-NEXT: store <2 x i32> [[VI]], ptr [[BV]], align 1 +// CHECK-NEXT: [[Ptr:%.*]] = getelementptr <2 x i32>, ptr [[BV]], i32 0, i32 1 +// CHECK-NEXT: store i32 [[Z]], ptr [[Ptr]], align 4 // CHECK-NEXT: ret void void fn6() { bool V = false; @@ -101,9 +99,8 @@ void fn6() { // CHECK: [[Arr:%.*]] = alloca [2 x <2 x i32>], align 8 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 8 [[Arr]], ptr align 8 {{.*}}, i32 16, i1 false) // CHECK-NEXT: [[Idx:%.*]] = getelementptr inbounds [2 x <2 x i32>], ptr [[Arr]], i32 0, i32 0 -// CHECK-NEXT: [[X:%.*]] = load <2 x i32>, ptr [[Idx]], align 8 -// CHECK-NEXT: [[VI:%.*]] = insertelement <2 x i32> [[X]], i32 0, i32 1 -// CHECK-NEXT: store <2 x i32> [[VI]], ptr [[Idx]], align 8 +// CHECK-NEXT: %[[Ptr:.*]] = getelementptr <2 x i32>, ptr [[Idx]], i32 0, i32 1 +// CHECK-NEXT: store i32 0, ptr %[[Ptr]], align 4 // CHECK-NEXT: ret void void fn7() { bool2 Arr[2] = {{true,true}, {false,false}}; diff --git a/clang/test/CodeGenHLSL/GlobalConstructorFunction.hlsl b/clang/test/CodeGenHLSL/GlobalConstructorFunction.hlsl index b36682e..5553f8c 100644 --- a/clang/test/CodeGenHLSL/GlobalConstructorFunction.hlsl +++ b/clang/test/CodeGenHLSL/GlobalConstructorFunction.hlsl @@ -37,9 +37,8 @@ void main(unsigned GI : SV_GroupIndex) {} // INLINE-NEXT: alloca // INLINE-NEXT: store i32 12 // INLINE-NEXT: store i32 13 -// INLINE-NEXT: %[[HANDLE:.*]] = call target("dx.CBuffer", target("dx.Layout", %"__cblayout_$Globals", 4, 0)) -// INLINE-NEXT-SAME: @"llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_tdx.Layout_s___cblayout_$Globalss_4_0tt"(i32 0, i32 0, i32 1, i32 0, i1 false) -// INLINE-NEXT: store target("dx.CBuffer", target("dx.Layout", %"__cblayout_$Globals", 4, 0)) %[[HANDLE]], ptr @"$Globals.cb", align 4 +// INLINE-NEXT: %[[HANDLE:.*]] = call target("dx.CBuffer", %"__cblayout_$Globals") @"llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_$Globalsst"(i32 0, i32 0, i32 1, i32 0, ptr @"$Globals.str") +// INLINE-NEXT: store target("dx.CBuffer", %"__cblayout_$Globals") %[[HANDLE]], ptr @"$Globals.cb", align 4 // INLINE-NEXT: %0 = call i32 @llvm.dx.flattened.thread.id.in.group() // INLINE-NEXT: store i32 % // INLINE-NEXT: store i32 0 diff --git a/clang/test/CodeGenHLSL/builtins/ScalarSwizzles.hlsl b/clang/test/CodeGenHLSL/builtins/ScalarSwizzles.hlsl index 7804239..2705982 100644 --- a/clang/test/CodeGenHLSL/builtins/ScalarSwizzles.hlsl +++ b/clang/test/CodeGenHLSL/builtins/ScalarSwizzles.hlsl @@ -259,9 +259,8 @@ bool AssignBool(bool V) { // CHECK-NEXT: [[B:%.*]] = load i32, ptr [[VAddr]], align 4 // CHECK-NEXT: [[LV1:%.*]] = trunc i32 [[B]] to i1 // CHECK-NEXT: [[D:%.*]] = zext i1 [[LV1]] to i32 -// CHECK-NEXT: [[C:%.*]] = load <2 x i32>, ptr [[X]], align 8 -// CHECK-NEXT: [[E:%.*]] = insertelement <2 x i32> [[C]], i32 [[D]], i32 1 -// CHECK-NEXT: store <2 x i32> [[E]], ptr [[X]], align 8 +// CHECK-NEXT: [[C:%.*]] = getelementptr <2 x i32>, ptr [[X]], i32 0, i32 1 +// CHECK-NEXT: store i32 [[D]], ptr [[C]], align 4 // CHECK-NEXT: ret void void AssignBool2(bool V) { bool2 X = true.xx; @@ -277,10 +276,13 @@ void AssignBool2(bool V) { // CHECK-NEXT: [[Z:%.*]] = load <2 x i32>, ptr [[VAddr]], align 8 // CHECK-NEXT: [[LV:%.*]] = trunc <2 x i32> [[Z]] to <2 x i1> // CHECK-NEXT: [[B:%.*]] = zext <2 x i1> [[LV]] to <2 x i32> -// CHECK-NEXT: [[A:%.*]] = load <2 x i32>, ptr [[X]], align 8 -// CHECK-NEXT: [[C:%.*]] = shufflevector <2 x i32> [[B]], <2 x i32> poison, <2 x i32> <i32 0, i32 1> -// CHECK-NEXT: store <2 x i32> [[C]], ptr [[X]], align 8 +// CHECK-NEXT: [[V1:%.*]] = extractelement <2 x i32> [[B]], i32 0 +// CHECK-NEXT: store i32 [[V1]], ptr [[X]], align 4 +// CHECK-NEXT: [[V2:%.*]] = extractelement <2 x i32> [[B]], i32 1 +// CHECK-NEXT: [[X2:%.*]] = getelementptr <2 x i32>, ptr [[X]], i32 0, i32 1 +// CHECK-NEXT: store i32 [[V2]], ptr [[X2]], align 4 // CHECK-NEXT: ret void + void AssignBool3(bool2 V) { bool2 X = {true,true}; X.xy = V; @@ -313,10 +315,13 @@ bool2 AccessBools() { // CHECK-NEXT: [[L1:%.*]] = shufflevector <1 x i32> [[L0]], <1 x i32> poison, <3 x i32> zeroinitializer // CHECK-NEXT: [[TruncV:%.*]] = trunc <3 x i32> [[L1]] to <3 x i1> // CHECK-NEXT: [[L2:%.*]] = zext <3 x i1> [[TruncV]] to <3 x i32> -// CHECK-NEXT: [[L3:%.*]] = load <4 x i32>, ptr [[B]], align 16 -// CHECK-NEXT: [[L4:%.*]] = shufflevector <3 x i32> [[L2]], <3 x i32> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> -// CHECK-NEXT: [[L5:%.*]] = shufflevector <4 x i32> [[L3]], <4 x i32> [[L4]], <4 x i32> <i32 4, i32 5, i32 6, i32 3> -// CHECK-NEXT: store <4 x i32> [[L5]], ptr [[B]], align 16 +// CHECK-NEXT: [[V1:%.*]] = extractelement <3 x i32> [[L2]], i32 0 +// CHECK-NEXT: store i32 [[V1]], ptr %B, align 4 +// CHECK-NEXT: [[V2:%.*]] = extractelement <3 x i32> [[L2]], i32 1 +// CHECK-NEXT: [[B2:%.*]] = getelementptr <4 x i32>, ptr %B, i32 0, i32 1 +// CHECK-NEXT: store i32 [[V2]], ptr [[B2]], align 4 +// CHECK-NEXT: [[V3:%.*]] = extractelement <3 x i32> [[L2]], i32 2 +// CHECK-NEXT: [[B3:%.*]] = getelementptr <4 x i32>, ptr %B, i32 0, i32 2 void BoolSizeMismatch() { bool4 B = {true,true,true,true}; B.xyz = false.xxx; diff --git a/clang/test/CodeGenHLSL/builtins/VectorElementStore.hlsl b/clang/test/CodeGenHLSL/builtins/VectorElementStore.hlsl new file mode 100644 index 0000000..e0c3aa5 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/VectorElementStore.hlsl @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -finclude-default-header -emit-llvm -disable-llvm-passes \ +// RUN: -triple dxil-pc-shadermodel6.3-library %s -o - | FileCheck %s + +// Test groupshared vector element store for uint. +// CHECK-LABEL: test_uint4 +// CHECK: [[VAL:%.*]] = load i32, ptr %Val.addr, align 4 +// CHECK: [[IDX:%.*]] = load i32, ptr %Idx.addr, align 4 +// CHECK: [[PTR:%.*]] = getelementptr <4 x i32>, ptr addrspace(3) @SMem, i32 0, i32 [[IDX]] +// CHECK: store i32 [[VAL]], ptr addrspace(3) [[PTR]], align 4 +// CHECK-: ret void +groupshared uint4 SMem; +void test_uint4(uint Idx, uint Val) { + SMem[Idx] = Val; +} + +// Test local vector element store for bool. +// CHECK: [[COND1:%.*]] = load i32, ptr addrspace(3) @Cond, align 4 +// CHECK: [[COND2:%.*]] = trunc i32 [[COND1]] to i1 +// CHECK: [[IDX:%.*]] = load i32, ptr %Idx.addr, align 4 +// CHECK: [[COND3:%.*]] = zext i1 [[COND2]] to i32 +// CHECK: [[PTR:%.*]] = getelementptr <3 x i32>, ptr %Val, i32 0, i32 [[IDX]] +// CHECK: store i32 [[COND3]], ptr [[PTR]], align 4 +// CHECK: ret +groupshared bool Cond; +bool3 test_bool(uint Idx) { + bool3 Val = { false, false, false}; + Val[Idx] = Cond; + return Val; +} + +// Test resource vector element store for float. +// CHECK: [[VAL:%.*]] = load float, ptr %Val.addr, align 4 +// CHECK: [[RES_PTR:%.*]] = call {{.*}} ptr @_ZN4hlsl18RWStructuredBufferIDv4_fEixEj(ptr {{.*}} @_ZL3Buf, i32 noundef 0) +// CHECK: [[IDX:%.*]] = load i32, ptr %Idx.addr, align 4 +// CHECK: [[PTR:%.*]] = getelementptr <4 x float>, ptr [[RES_PTR]], i32 0, i32 [[IDX]] +// CHECK: store float [[VAL]], ptr [[PTR]], align 4 +// CHECK: ret void +RWStructuredBuffer<float4> Buf : register(u0); +void test_float(uint Idx, float Val) { + Buf[0][Idx] = Val; +} diff --git a/clang/test/CodeGenHLSL/builtins/VectorSwizzles.hlsl b/clang/test/CodeGenHLSL/builtins/VectorSwizzles.hlsl new file mode 100644 index 0000000..c632e79 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/VectorSwizzles.hlsl @@ -0,0 +1,96 @@ +// RUN: %clang_cc1 -finclude-default-header -fnative-half-type \ +// RUN: -triple dxil-pc-shadermodel6.3-library %s -disable-llvm-passes \ +// RUN: -emit-llvm -o - | FileCheck %s + +// CHECK-LABEL: Single + +// Setup local vars. +// CHECK: [[VecAddr:%.*]] = alloca <3 x i64>, align 32 +// CHECK-NEXT: [[AAddr:%.*]] = alloca i64, align 8 +// CHECK-NEXT: store <3 x i64> %vec, ptr [[VecAddr]], align 32 +// CHECK-NEXT: store i64 %a, ptr [[AAddr]], align 8 + +// Update single element of the vector. +// CHECK-NEXT: [[A:%.*]] = load i64, ptr [[AAddr]], align 8 +// CHECK-NEXT: [[Vy:%.*]] = getelementptr <3 x i64>, ptr [[VecAddr]], i32 0, i32 1 +// CHECK-NEXT: store i64 [[A]], ptr [[Vy]], align 8 + +// Return. +// CHECK-NEXT: [[RetVal:%.*]] = load <3 x i64>, ptr [[VecAddr]], align 32 +// CHECK-NEXT: ret <3 x i64> [[RetVal]] +uint64_t3 Single(uint64_t3 vec, uint64_t a){ + vec.y = a; + return vec; +} + +// CHECK-LABEL: Double + +// Setup local vars. +// CHECK: [[VecAddr:%.*]] = alloca <3 x float>, align 16 +// CHECK-NEXT: [[AAddr:%.*]] = alloca float, align 4 +// CHECK-NEXT: [[BAddr:%.*]] = alloca float, align 4 +// CHECK-NEXT: store <3 x float> %vec, ptr [[VecAddr]], align 16 +// CHECK-NEXT: store float %a, ptr [[AAddr]], align 4 +// CHECK-NEXT: store float %b, ptr [[BAddr]], align 4 + +// Create temporary vector {a, b}. +// CHECK-NEXT: [[A:%.*]] = load float, ptr [[AAddr]], align 4 +// CHECK-NEXT: [[TmpVec0:%.*]] = insertelement <2 x float> poison, float [[A]], i32 0 +// CHECK-NEXT: [[B:%.*]] = load float, ptr [[BAddr]], align 4 +// CHECK-NEXT: [[TmpVec1:%.*]] = insertelement <2 x float> [[TmpVec0]], float [[B]], i32 1 + +// Update two elements of the vector from temporary vector. +// CHECK-NEXT: [[TmpX:%.*]] = extractelement <2 x float> [[TmpVec1]], i32 0 +// CHECK-NEXT: [[VecZ:%.*]] = getelementptr <3 x float>, ptr [[VecAddr]], i32 0, i32 2 +// CHECK-NEXT: store float [[TmpX]], ptr [[VecZ]], align 4 +// CHECK-NEXT: [[TmpY:%.*]] = extractelement <2 x float> [[TmpVec1]], i32 1 +// CHECK-NEXT: [[VecY:%.*]] = getelementptr <3 x float>, ptr [[VecAddr]], i32 0, i32 1 +// CHECK-NEXT: store float [[TmpY]], ptr [[VecY]], align 4 + +// Return. +// CHECK-NEXT: [[RetVal:%.*]] = load <3 x float>, ptr [[VecAddr]], align 16 +// CHECK-NEXT: ret <3 x float> [[RetVal]] +float3 Double(float3 vec, float a, float b) { + vec.zy = {a, b}; + return vec; +} + +// CHECK-LABEL: Shuffle + +// Setup local vars. +// CHECK: [[VecAddr:%.*]] = alloca <4 x half>, align 8 +// CHECK-NEXT: [[AAddr:%.*]] = alloca half, align 2 +// CHECK-NEXT: [[BAddr:%.*]] = alloca half, align 2 +// CHECK-NEXT: store <4 x half> %vec, ptr [[VecAddr]], align 8 +// CHECK-NEXT: store half %a, ptr [[AAddr]], align 2 +// CHECK-NEXT: store half %b, ptr [[BAddr]], align 2 + +// Create temporary vector {a, b, 13.74, a}. +// CHECK-NEXT: [[A:%.*]] = load half, ptr [[AAddr]], align 2 +// CHECK-NEXT: [[TmpVec0:%.*]] = insertelement <4 x half> poison, half [[A]], i32 0 +// CHECK-NEXT: [[B:%.*]] = load half, ptr [[BAddr]], align 2 +// CHECK-NEXT: [[TmpVec1:%.*]] = insertelement <4 x half> [[TmpVec0]], half [[B]], i32 1 +// CHECK-NEXT: [[TmpVec2:%.*]] = insertelement <4 x half> %vecinit1, half 0xH4ADF, i32 2 +// CHECK-NEXT: [[A:%.*]] = load half, ptr [[AAddr]], align 2 +// CHECK-NEXT: [[TmpVec3:%.*]] = insertelement <4 x half> [[TmpVec2]], half [[A]], i32 3 + +// Update four elements of the vector via mixed up swizzle from the temporary vector. +// CHECK-NEXT: [[TmpX:%.*]] = extractelement <4 x half> [[TmpVec3]], i32 0 +// CHECK-NEXT: [[VecZ:%.*]] = getelementptr <4 x half>, ptr [[VecAddr]], i32 0, i32 2 +// CHECK-NEXT: store half [[TmpX]], ptr [[VecZ]], align 2 +// CHECK-NEXT: [[TmpY:%.*]] = extractelement <4 x half> [[TmpVec3]], i32 1 +// CHECK-NEXT: [[VecW:%.*]] = getelementptr <4 x half>, ptr [[VecAddr]], i32 0, i32 3 +// CHECK-NEXT: store half [[TmpY]], ptr [[VecW]], align 2 +// CHECK-NEXT: [[TmpZ:%.*]] = extractelement <4 x half> [[TmpVec3]], i32 2 +// CHECK-NEXT: store half [[TmpZ]], ptr [[VecAddr]], align 2 +// CHECK-NEXT: [[TmpW:%.*]] = extractelement <4 x half> [[TmpVec3]], i32 3 +// CHECK-NEXT: [[VecY:%.*]] = getelementptr <4 x half>, ptr [[VecAddr]], i32 0, i32 1 +// CHECK-NEXT: store half [[TmpW]], ptr [[VecY]], align 2 + +// Return. +// CHECK-NEXT: [[RetVal:%.*]] = load <4 x half>, ptr [[VecAddr]], align 8 +// CHECK-NEXT: ret <4 x half> [[RetVal]] +half4 Shuffle(half4 vec, half a, half b) { + vec.zwxy = {a, b, 13.74, a}; + return vec; +} diff --git a/clang/test/CodeGenHLSL/builtins/ddx-coarse-builtin.hlsl b/clang/test/CodeGenHLSL/builtins/ddx-coarse-builtin.hlsl new file mode 100644 index 0000000..01216ee --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/ddx-coarse-builtin.hlsl @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s \ +// RUN: -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple spirv-pc-vulkan-compute %s \ +// RUN: -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK-SPIRV + +// CHECK-LABEL: half @_Z19test_f16_ddx_coarseDh +// CHECK: %hlsl.ddx.coarse = call {{.*}} half @llvm.dx.ddx.coarse.f16(half %{{.*}}) +// CHECK: ret half %hlsl.ddx.coarse +// CHECK-LABEL-SPIRV: half @_Z19test_f16_ddx_coarseDh +// CHECK-SPIRV: %hlsl.ddx.coarse = call {{.*}} half @llvm.spv.ddx.coarse.f16(half %{{.*}}) +// CHECK-SPIRV: ret half %hlsl.ddx.coarse +half test_f16_ddx_coarse(half val) { + return __builtin_hlsl_elementwise_ddx_coarse(val); +} + +// CHECK-LABEL: float @_Z19test_f32_ddx_coarsef +// CHECK: %hlsl.ddx.coarse = call {{.*}} float @llvm.dx.ddx.coarse.f32(float %{{.*}}) +// CHECK: ret float %hlsl.ddx.coarse +// CHECK-LABEL-SPIRV: float @_Z19test_f32_ddx_coarsef +// CHECK-SPIRV: %hlsl.ddx.coarse = call {{.*}} float @llvm.spv.ddx.coarse.f32(float %{{.*}}) +// CHECK-SPIRV: ret float %hlsl.ddx.coarse +float test_f32_ddx_coarse(float val) { + return __builtin_hlsl_elementwise_ddx_coarse(val); +} diff --git a/clang/test/CodeGenHLSL/builtins/ddx-coarse.hlsl b/clang/test/CodeGenHLSL/builtins/ddx-coarse.hlsl new file mode 100644 index 0000000..c200d47 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/ddx-coarse.hlsl @@ -0,0 +1,86 @@ +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s \ +// RUN: -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple spirv-pc-vulkan-compute %s \ +// RUN: -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK-SPIRV + +// CHECK-LABEL: half @_Z19test_f16_ddx_coarseDh +// CHECK: %hlsl.ddx.coarse = call {{.*}} half @llvm.dx.ddx.coarse.f16(half %{{.*}}) +// CHECK: ret half %hlsl.ddx.coarse +// CHECK-LABEL-SPIRV: half @_Z19test_f16_ddx_coarseDh +// CHECK-SPIRV: %hlsl.ddx.coarse = call {{.*}} half @llvm.spv.ddx.coarse.f16(half %{{.*}}) +// CHECK-SPIRV: ret half %hlsl.ddx.coarse +half test_f16_ddx_coarse(half val) { + return ddx_coarse(val); +} + +// CHECK-LABEL: <2 x half> @_Z20test_f16_ddx_coarse2Dv2_Dh +// CHECK: %hlsl.ddx.coarse = call {{.*}} <2 x half> @llvm.dx.ddx.coarse.v2f16(<2 x half> %{{.*}}) +// CHECK: ret <2 x half> %hlsl.ddx.coarse +// CHECK-LABEL-SPIRV: <2 x half> @_Z20test_f16_ddx_coarse2Dv2_Dh +// CHECK-SPIRV: %hlsl.ddx.coarse = call {{.*}} <2 x half> @llvm.spv.ddx.coarse.v2f16(<2 x half> %{{.*}}) +// CHECK-SPIRV: ret <2 x half> %hlsl.ddx.coarse +half2 test_f16_ddx_coarse2(half2 val) { + return ddx_coarse(val); +} + +// CHECK-LABEL: <3 x half> @_Z20test_f16_ddx_coarse3Dv3_Dh +// CHECK: %hlsl.ddx.coarse = call {{.*}} <3 x half> @llvm.dx.ddx.coarse.v3f16(<3 x half> %{{.*}}) +// CHECK: ret <3 x half> %hlsl.ddx.coarse +// CHECK-LABEL-SPIRV: <3 x half> @_Z20test_f16_ddx_coarse3Dv3_Dh +// CHECK-SPIRV: %hlsl.ddx.coarse = call {{.*}} <3 x half> @llvm.spv.ddx.coarse.v3f16(<3 x half> %{{.*}}) +// CHECK-SPIRV: ret <3 x half> %hlsl.ddx.coarse +half3 test_f16_ddx_coarse3(half3 val) { + return ddx_coarse(val); +} + +// CHECK-LABEL: <4 x half> @_Z20test_f16_ddx_coarse4Dv4_Dh +// CHECK: %hlsl.ddx.coarse = call {{.*}} <4 x half> @llvm.dx.ddx.coarse.v4f16(<4 x half> %{{.*}}) +// CHECK: ret <4 x half> %hlsl.ddx.coarse +// CHECK-LABEL-SPIRV: <4 x half> @_Z20test_f16_ddx_coarse4Dv4_Dh +// CHECK-SPIRV: %hlsl.ddx.coarse = call {{.*}} <4 x half> @llvm.spv.ddx.coarse.v4f16(<4 x half> %{{.*}}) +// CHECK-SPIRV: ret <4 x half> %hlsl.ddx.coarse +half4 test_f16_ddx_coarse4(half4 val) { + return ddx_coarse(val); +} + +// CHECK-LABEL: float @_Z19test_f32_ddx_coarsef +// CHECK: %hlsl.ddx.coarse = call {{.*}} float @llvm.dx.ddx.coarse.f32(float %{{.*}}) +// CHECK: ret float %hlsl.ddx.coarse +// CHECK-LABEL-SPIRV: float @_Z19test_f32_ddx_coarsef +// CHECK-SPIRV: %hlsl.ddx.coarse = call {{.*}} float @llvm.spv.ddx.coarse.f32(float %{{.*}}) +// CHECK-SPIRV: ret float %hlsl.ddx.coarse +float test_f32_ddx_coarse(float val) { + return ddx_coarse(val); +} + +// CHECK-LABEL: <2 x float> @_Z20test_f32_ddx_coarse2Dv2_f +// CHECK: %hlsl.ddx.coarse = call {{.*}} <2 x float> @llvm.dx.ddx.coarse.v2f32(<2 x float> %{{.*}}) +// CHECK: ret <2 x float> %hlsl.ddx.coarse +// CHECK-LABEL-SPIRV: <2 x float> @_Z20test_f32_ddx_coarse2Dv2_f +// CHECK-SPIRV: %hlsl.ddx.coarse = call {{.*}} <2 x float> @llvm.spv.ddx.coarse.v2f32(<2 x float> %{{.*}}) +// CHECK-SPIRV: ret <2 x float> %hlsl.ddx.coarse +float2 test_f32_ddx_coarse2(float2 val) { + return ddx_coarse(val); +} + +// CHECK-LABEL: <3 x float> @_Z20test_f32_ddx_coarse3Dv3_f +// CHECK: %hlsl.ddx.coarse = call {{.*}} <3 x float> @llvm.dx.ddx.coarse.v3f32(<3 x float> %{{.*}}) +// CHECK: ret <3 x float> %hlsl.ddx.coarse +// CHECK-LABEL-SPIRV: <3 x float> @_Z20test_f32_ddx_coarse3Dv3_f +// CHECK-SPIRV: %hlsl.ddx.coarse = call {{.*}} <3 x float> @llvm.spv.ddx.coarse.v3f32(<3 x float> %{{.*}}) +// CHECK-SPIRV: ret <3 x float> %hlsl.ddx.coarse +float3 test_f32_ddx_coarse3(float3 val) { + return ddx_coarse(val); +} + +// CHECK-LABEL: <4 x float> @_Z20test_f32_ddx_coarse4Dv4_f +// CHECK: %hlsl.ddx.coarse = call {{.*}} <4 x float> @llvm.dx.ddx.coarse.v4f32(<4 x float> %{{.*}}) +// CHECK: ret <4 x float> %hlsl.ddx.coarse +// CHECK-LABEL-SPIRV: <4 x float> @_Z20test_f32_ddx_coarse4Dv4_f +// CHECK-SPIRV: %hlsl.ddx.coarse = call {{.*}} <4 x float> @llvm.spv.ddx.coarse.v4f32(<4 x float> %{{.*}}) +// CHECK-SPIRV: ret <4 x float> %hlsl.ddx.coarse +float4 test_f32_ddx_coarse4(float4 val) { + return ddx_coarse(val); +} diff --git a/clang/test/CodeGenHLSL/builtins/ddy-coarse-builtin.hlsl b/clang/test/CodeGenHLSL/builtins/ddy-coarse-builtin.hlsl new file mode 100644 index 0000000..2967deb --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/ddy-coarse-builtin.hlsl @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s \ +// RUN: -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple spirv-pc-vulkan-compute %s \ +// RUN: -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK-SPIRV + +// CHECK-LABEL: half @_Z19test_f16_ddy_coarseDh +// CHECK: %hlsl.ddy.coarse = call {{.*}} half @llvm.dx.ddy.coarse.f16(half %{{.*}}) +// CHECK: ret half %hlsl.ddy.coarse +// CHECK-LABEL-SPIRV: half @_Z19test_f16_ddy_coarseDh +// CHECK-SPIRV: %hlsl.ddy.coarse = call {{.*}} half @llvm.spv.ddy.coarse.f16(half %{{.*}}) +// CHECK-SPIRV: ret half %hlsl.ddy.coarse +half test_f16_ddy_coarse(half val) { + return __builtin_hlsl_elementwise_ddy_coarse(val); +} + +// CHECK-LABEL: float @_Z19test_f32_ddy_coarsef +// CHECK: %hlsl.ddy.coarse = call {{.*}} float @llvm.dx.ddy.coarse.f32(float %{{.*}}) +// CHECK: ret float %hlsl.ddy.coarse +// CHECK-LABEL-SPIRV: float @_Z19test_f32_ddy_coarsef +// CHECK-SPIRV: %hlsl.ddy.coarse = call {{.*}} float @llvm.spv.ddy.coarse.f32(float %{{.*}}) +// CHECK-SPIRV: ret float %hlsl.ddy.coarse +float test_f32_ddy_coarse(float val) { + return __builtin_hlsl_elementwise_ddy_coarse(val); +} diff --git a/clang/test/CodeGenHLSL/builtins/ddy-coarse.hlsl b/clang/test/CodeGenHLSL/builtins/ddy-coarse.hlsl new file mode 100644 index 0000000..faa972a --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/ddy-coarse.hlsl @@ -0,0 +1,86 @@ +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s \ +// RUN: -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple spirv-pc-vulkan-compute %s \ +// RUN: -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK-SPIRV + +// CHECK-LABEL: half @_Z19test_f16_ddy_coarseDh +// CHECK: %hlsl.ddy.coarse = call {{.*}} half @llvm.dx.ddy.coarse.f16(half %{{.*}}) +// CHECK: ret half %hlsl.ddy.coarse +// CHECK-LABEL-SPIRV: half @_Z19test_f16_ddy_coarseDh +// CHECK-SPIRV: %hlsl.ddy.coarse = call {{.*}} half @llvm.spv.ddy.coarse.f16(half %{{.*}}) +// CHECK-SPIRV: ret half %hlsl.ddy.coarse +half test_f16_ddy_coarse(half val) { + return ddy_coarse(val); +} + +// CHECK-LABEL: <2 x half> @_Z20test_f16_ddy_coarse2Dv2_Dh +// CHECK: %hlsl.ddy.coarse = call {{.*}} <2 x half> @llvm.dx.ddy.coarse.v2f16(<2 x half> %{{.*}}) +// CHECK: ret <2 x half> %hlsl.ddy.coarse +// CHECK-LABEL-SPIRV: <2 x half> @_Z20test_f16_ddy_coarse2Dv2_Dh +// CHECK-SPIRV: %hlsl.ddy.coarse = call {{.*}} <2 x half> @llvm.spv.ddy.coarse.v2f16(<2 x half> %{{.*}}) +// CHECK-SPIRV: ret <2 x half> %hlsl.ddy.coarse +half2 test_f16_ddy_coarse2(half2 val) { + return ddy_coarse(val); +} + +// CHECK-LABEL: <3 x half> @_Z20test_f16_ddy_coarse3Dv3_Dh +// CHECK: %hlsl.ddy.coarse = call {{.*}} <3 x half> @llvm.dx.ddy.coarse.v3f16(<3 x half> %{{.*}}) +// CHECK: ret <3 x half> %hlsl.ddy.coarse +// CHECK-LABEL-SPIRV: <3 x half> @_Z20test_f16_ddy_coarse3Dv3_Dh +// CHECK-SPIRV: %hlsl.ddy.coarse = call {{.*}} <3 x half> @llvm.spv.ddy.coarse.v3f16(<3 x half> %{{.*}}) +// CHECK-SPIRV: ret <3 x half> %hlsl.ddy.coarse +half3 test_f16_ddy_coarse3(half3 val) { + return ddy_coarse(val); +} + +// CHECK-LABEL: <4 x half> @_Z20test_f16_ddy_coarse4Dv4_Dh +// CHECK: %hlsl.ddy.coarse = call {{.*}} <4 x half> @llvm.dx.ddy.coarse.v4f16(<4 x half> %{{.*}}) +// CHECK: ret <4 x half> %hlsl.ddy.coarse +// CHECK-LABEL-SPIRV: <4 x half> @_Z20test_f16_ddy_coarse4Dv4_Dh +// CHECK-SPIRV: %hlsl.ddy.coarse = call {{.*}} <4 x half> @llvm.spv.ddy.coarse.v4f16(<4 x half> %{{.*}}) +// CHECK-SPIRV: ret <4 x half> %hlsl.ddy.coarse +half4 test_f16_ddy_coarse4(half4 val) { + return ddy_coarse(val); +} + +// CHECK-LABEL: float @_Z19test_f32_ddy_coarsef +// CHECK: %hlsl.ddy.coarse = call {{.*}} float @llvm.dx.ddy.coarse.f32(float %{{.*}}) +// CHECK: ret float %hlsl.ddy.coarse +// CHECK-LABEL-SPIRV: float @_Z19test_f32_ddy_coarsef +// CHECK-SPIRV: %hlsl.ddy.coarse = call {{.*}} float @llvm.spv.ddy.coarse.f32(float %{{.*}}) +// CHECK-SPIRV: ret float %hlsl.ddy.coarse +float test_f32_ddy_coarse(float val) { + return ddy_coarse(val); +} + +// CHECK-LABEL: <2 x float> @_Z20test_f32_ddy_coarse2Dv2_f +// CHECK: %hlsl.ddy.coarse = call {{.*}} <2 x float> @llvm.dx.ddy.coarse.v2f32(<2 x float> %{{.*}}) +// CHECK: ret <2 x float> %hlsl.ddy.coarse +// CHECK-LABEL-SPIRV: <2 x float> @_Z20test_f32_ddy_coarse2Dv2_f +// CHECK-SPIRV: %hlsl.ddy.coarse = call {{.*}} <2 x float> @llvm.spv.ddy.coarse.v2f32(<2 x float> %{{.*}}) +// CHECK-SPIRV: ret <2 x float> %hlsl.ddy.coarse +float2 test_f32_ddy_coarse2(float2 val) { + return ddy_coarse(val); +} + +// CHECK-LABEL: <3 x float> @_Z20test_f32_ddy_coarse3Dv3_f +// CHECK: %hlsl.ddy.coarse = call {{.*}} <3 x float> @llvm.dx.ddy.coarse.v3f32(<3 x float> %{{.*}}) +// CHECK: ret <3 x float> %hlsl.ddy.coarse +// CHECK-LABEL-SPIRV: <3 x float> @_Z20test_f32_ddy_coarse3Dv3_f +// CHECK-SPIRV: %hlsl.ddy.coarse = call {{.*}} <3 x float> @llvm.spv.ddy.coarse.v3f32(<3 x float> %{{.*}}) +// CHECK-SPIRV: ret <3 x float> %hlsl.ddy.coarse +float3 test_f32_ddy_coarse3(float3 val) { + return ddy_coarse(val); +} + +// CHECK-LABEL: <4 x float> @_Z20test_f32_ddy_coarse4Dv4_f +// CHECK: %hlsl.ddy.coarse = call {{.*}} <4 x float> @llvm.dx.ddy.coarse.v4f32(<4 x float> %{{.*}}) +// CHECK: ret <4 x float> %hlsl.ddy.coarse +// CHECK-LABEL-SPIRV: <4 x float> @_Z20test_f32_ddy_coarse4Dv4_f +// CHECK-SPIRV: %hlsl.ddy.coarse = call {{.*}} <4 x float> @llvm.spv.ddy.coarse.v4f32(<4 x float> %{{.*}}) +// CHECK-SPIRV: ret <4 x float> %hlsl.ddy.coarse +float4 test_f32_ddy_coarse4(float4 val) { + return ddy_coarse(val); +} diff --git a/clang/test/CodeGenHLSL/builtins/exp-overloads.hlsl b/clang/test/CodeGenHLSL/builtins/exp-overloads.hlsl index df34bee..c22f012 100644 --- a/clang/test/CodeGenHLSL/builtins/exp-overloads.hlsl +++ b/clang/test/CodeGenHLSL/builtins/exp-overloads.hlsl @@ -3,86 +3,86 @@ // RUN: FileCheck %s --check-prefixes=CHECK // CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_exp_double -// CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32( -// CHECK: ret float %elt.exp +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32( +// CHECK: ret float [[EXP]] float test_exp_double(double p0) { return exp(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp_double2 -// CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp.v2f32 -// CHECK: ret <2 x float> %elt.exp +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp.v2f32 +// CHECK: ret <2 x float> [[EXP]] float2 test_exp_double2(double2 p0) { return exp(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp_double3 -// CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp.v3f32 -// CHECK: ret <3 x float> %elt.exp +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp.v3f32 +// CHECK: ret <3 x float> [[EXP]] float3 test_exp_double3(double3 p0) { return exp(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp_double4 -// CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp.v4f32 -// CHECK: ret <4 x float> %elt.exp +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp.v4f32 +// CHECK: ret <4 x float> [[EXP]] float4 test_exp_double4(double4 p0) { return exp(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_exp_int -// CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32( -// CHECK: ret float %elt.exp +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32( +// CHECK: ret float [[EXP]] float test_exp_int(int p0) { return exp(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp_int2 -// CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp.v2f32 -// CHECK: ret <2 x float> %elt.exp +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp.v2f32 +// CHECK: ret <2 x float> [[EXP]] float2 test_exp_int2(int2 p0) { return exp(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp_int3 -// CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp.v3f32 -// CHECK: ret <3 x float> %elt.exp +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp.v3f32 +// CHECK: ret <3 x float> [[EXP]] float3 test_exp_int3(int3 p0) { return exp(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp_int4 -// CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp.v4f32 -// CHECK: ret <4 x float> %elt.exp +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp.v4f32 +// CHECK: ret <4 x float> [[EXP]] float4 test_exp_int4(int4 p0) { return exp(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_exp_uint -// CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32( -// CHECK: ret float %elt.exp +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32( +// CHECK: ret float [[EXP]] float test_exp_uint(uint p0) { return exp(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp_uint2 -// CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp.v2f32 -// CHECK: ret <2 x float> %elt.exp +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp.v2f32 +// CHECK: ret <2 x float> [[EXP]] float2 test_exp_uint2(uint2 p0) { return exp(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp_uint3 -// CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp.v3f32 -// CHECK: ret <3 x float> %elt.exp +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp.v3f32 +// CHECK: ret <3 x float> [[EXP]] float3 test_exp_uint3(uint3 p0) { return exp(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp_uint4 -// CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp.v4f32 -// CHECK: ret <4 x float> %elt.exp +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp.v4f32 +// CHECK: ret <4 x float> [[EXP]] float4 test_exp_uint4(uint4 p0) { return exp(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_exp_int64_t -// CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32( -// CHECK: ret float %elt.exp +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32( +// CHECK: ret float [[EXP]] float test_exp_int64_t(int64_t p0) { return exp(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp_int64_t2 -// CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp.v2f32 -// CHECK: ret <2 x float> %elt.exp +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp.v2f32 +// CHECK: ret <2 x float> [[EXP]] float2 test_exp_int64_t2(int64_t2 p0) { return exp(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp_int64_t3 -// CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp.v3f32 -// CHECK: ret <3 x float> %elt.exp +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp.v3f32 +// CHECK: ret <3 x float> [[EXP]] float3 test_exp_int64_t3(int64_t3 p0) { return exp(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp_int64_t4 -// CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp.v4f32 -// CHECK: ret <4 x float> %elt.exp +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp.v4f32 +// CHECK: ret <4 x float> [[EXP]] float4 test_exp_int64_t4(int64_t4 p0) { return exp(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_exp_uint64_t -// CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32( -// CHECK: ret float %elt.exp +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32( +// CHECK: ret float [[EXP]] float test_exp_uint64_t(uint64_t p0) { return exp(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp_uint64_t2 -// CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp.v2f32 -// CHECK: ret <2 x float> %elt.exp +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp.v2f32 +// CHECK: ret <2 x float> [[EXP]] float2 test_exp_uint64_t2(uint64_t2 p0) { return exp(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp_uint64_t3 -// CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp.v3f32 -// CHECK: ret <3 x float> %elt.exp +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp.v3f32 +// CHECK: ret <3 x float> [[EXP]] float3 test_exp_uint64_t3(uint64_t3 p0) { return exp(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp_uint64_t4 -// CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp.v4f32 -// CHECK: ret <4 x float> %elt.exp +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp.v4f32 +// CHECK: ret <4 x float> [[EXP]] float4 test_exp_uint64_t4(uint64_t4 p0) { return exp(p0); } diff --git a/clang/test/CodeGenHLSL/builtins/exp.hlsl b/clang/test/CodeGenHLSL/builtins/exp.hlsl index d50ef02..56efb03 100644 --- a/clang/test/CodeGenHLSL/builtins/exp.hlsl +++ b/clang/test/CodeGenHLSL/builtins/exp.hlsl @@ -6,47 +6,47 @@ // RUN: FileCheck %s --check-prefixes=CHECK,NO_HALF // NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) half @_Z13test_exp_half -// NATIVE_HALF: %elt.exp = call reassoc nnan ninf nsz arcp afn half @llvm.exp.f16( -// NATIVE_HALF: ret half %elt.exp +// NATIVE_HALF: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.exp.f16( +// NATIVE_HALF: ret half [[EXP]] // NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) float @_Z13test_exp_half -// NO_HALF: %elt.exp = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32( -// NO_HALF: ret float %elt.exp +// NO_HALF: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32( +// NO_HALF: ret float [[EXP]] half test_exp_half(half p0) { return exp(p0); } // NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x half> @_Z14test_exp_half2 -// NATIVE_HALF: %elt.exp = call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.exp.v2f16 -// NATIVE_HALF: ret <2 x half> %elt.exp +// NATIVE_HALF: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.exp.v2f16 +// NATIVE_HALF: ret <2 x half> [[EXP]] // NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z14test_exp_half2 -// NO_HALF: %elt.exp = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp.v2f32( -// NO_HALF: ret <2 x float> %elt.exp +// NO_HALF: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp.v2f32( +// NO_HALF: ret <2 x float> [[EXP]] half2 test_exp_half2(half2 p0) { return exp(p0); } // NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x half> @_Z14test_exp_half3 -// NATIVE_HALF: %elt.exp = call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.exp.v3f16 -// NATIVE_HALF: ret <3 x half> %elt.exp +// NATIVE_HALF: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.exp.v3f16 +// NATIVE_HALF: ret <3 x half> [[EXP]] // NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z14test_exp_half3 -// NO_HALF: %elt.exp = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp.v3f32( -// NO_HALF: ret <3 x float> %elt.exp +// NO_HALF: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp.v3f32( +// NO_HALF: ret <3 x float> [[EXP]] half3 test_exp_half3(half3 p0) { return exp(p0); } // NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x half> @_Z14test_exp_half4 -// NATIVE_HALF: %elt.exp = call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.exp.v4f16 -// NATIVE_HALF: ret <4 x half> %elt.exp +// NATIVE_HALF: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.exp.v4f16 +// NATIVE_HALF: ret <4 x half> [[EXP]] // NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z14test_exp_half4 -// NO_HALF: %elt.exp = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp.v4f32( -// NO_HALF: ret <4 x float> %elt.exp +// NO_HALF: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp.v4f32( +// NO_HALF: ret <4 x float> [[EXP]] half4 test_exp_half4(half4 p0) { return exp(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z14test_exp_float -// CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32( -// CHECK: ret float %elt.exp +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32( +// CHECK: ret float [[EXP:%.*]] float test_exp_float(float p0) { return exp(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z15test_exp_float2 -// CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp.v2f32 -// CHECK: ret <2 x float> %elt.exp +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp.v2f32 +// CHECK: ret <2 x float> [[EXP]] float2 test_exp_float2(float2 p0) { return exp(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z15test_exp_float3 -// CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp.v3f32 -// CHECK: ret <3 x float> %elt.exp +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp.v3f32 +// CHECK: ret <3 x float> [[EXP]] float3 test_exp_float3(float3 p0) { return exp(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z15test_exp_float4 -// CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp.v4f32 -// CHECK: ret <4 x float> %elt.exp +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp.v4f32 +// CHECK: ret <4 x float> [[EXP]] float4 test_exp_float4(float4 p0) { return exp(p0); } diff --git a/clang/test/CodeGenHLSL/builtins/exp2-overloads.hlsl b/clang/test/CodeGenHLSL/builtins/exp2-overloads.hlsl index 2048277..a8a6f3b 100644 --- a/clang/test/CodeGenHLSL/builtins/exp2-overloads.hlsl +++ b/clang/test/CodeGenHLSL/builtins/exp2-overloads.hlsl @@ -3,86 +3,86 @@ // RUN: FileCheck %s --check-prefixes=CHECK // CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_exp2_double -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32( -// CHECK: ret float %elt.exp2 +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32( +// CHECK: ret float [[EXP2]] float test_exp2_double(double p0) { return exp2(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp2_double2 -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32 -// CHECK: ret <2 x float> %elt.exp2 +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32 +// CHECK: ret <2 x float> [[EXP2]] float2 test_exp2_double2(double2 p0) { return exp2(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp2_double3 -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32 -// CHECK: ret <3 x float> %elt.exp2 +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32 +// CHECK: ret <3 x float> [[EXP2]] float3 test_exp2_double3(double3 p0) { return exp2(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp2_double4 -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32 -// CHECK: ret <4 x float> %elt.exp2 +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32 +// CHECK: ret <4 x float> [[EXP2]] float4 test_exp2_double4(double4 p0) { return exp2(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_exp2_int -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32( -// CHECK: ret float %elt.exp2 +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32( +// CHECK: ret float [[EXP2]] float test_exp2_int(int p0) { return exp2(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp2_int2 -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32 -// CHECK: ret <2 x float> %elt.exp2 +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32 +// CHECK: ret <2 x float> [[EXP2]] float2 test_exp2_int2(int2 p0) { return exp2(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp2_int3 -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32 -// CHECK: ret <3 x float> %elt.exp2 +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32 +// CHECK: ret <3 x float> [[EXP2]] float3 test_exp2_int3(int3 p0) { return exp2(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp2_int4 -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32 -// CHECK: ret <4 x float> %elt.exp2 +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32 +// CHECK: ret <4 x float> [[EXP2]] float4 test_exp2_int4(int4 p0) { return exp2(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_exp2_uint -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32( -// CHECK: ret float %elt.exp2 +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32( +// CHECK: ret float [[EXP2]] float test_exp2_uint(uint p0) { return exp2(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp2_uint2 -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32 -// CHECK: ret <2 x float> %elt.exp2 +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32 +// CHECK: ret <2 x float> [[EXP2]] float2 test_exp2_uint2(uint2 p0) { return exp2(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp2_uint3 -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32 -// CHECK: ret <3 x float> %elt.exp2 +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32 +// CHECK: ret <3 x float> [[EXP2]] float3 test_exp2_uint3(uint3 p0) { return exp2(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp2_uint4 -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32 -// CHECK: ret <4 x float> %elt.exp2 +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32 +// CHECK: ret <4 x float> [[EXP2]] float4 test_exp2_uint4(uint4 p0) { return exp2(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_exp2_int64_t -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32( -// CHECK: ret float %elt.exp2 +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32( +// CHECK: ret float [[EXP2]] float test_exp2_int64_t(int64_t p0) { return exp2(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp2_int64_t2 -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32 -// CHECK: ret <2 x float> %elt.exp2 +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32 +// CHECK: ret <2 x float> [[EXP2]] float2 test_exp2_int64_t2(int64_t2 p0) { return exp2(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp2_int64_t3 -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32 -// CHECK: ret <3 x float> %elt.exp2 +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32 +// CHECK: ret <3 x float> [[EXP2]] float3 test_exp2_int64_t3(int64_t3 p0) { return exp2(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp2_int64_t4 -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32 -// CHECK: ret <4 x float> %elt.exp2 +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32 +// CHECK: ret <4 x float> [[EXP2]] float4 test_exp2_int64_t4(int64_t4 p0) { return exp2(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_exp2_uint64_t -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32( -// CHECK: ret float %elt.exp2 +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32( +// CHECK: ret float [[EXP2]] float test_exp2_uint64_t(uint64_t p0) { return exp2(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp2_uint64_t2 -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32 -// CHECK: ret <2 x float> %elt.exp2 +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32 +// CHECK: ret <2 x float> [[EXP2]] float2 test_exp2_uint64_t2(uint64_t2 p0) { return exp2(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp2_uint64_t3 -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32 -// CHECK: ret <3 x float> %elt.exp2 +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32 +// CHECK: ret <3 x float> [[EXP2]] float3 test_exp2_uint64_t3(uint64_t3 p0) { return exp2(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp2_uint64_t4 -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32 -// CHECK: ret <4 x float> %elt.exp2 +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32 +// CHECK: ret <4 x float> [[EXP2]] float4 test_exp2_uint64_t4(uint64_t4 p0) { return exp2(p0); } diff --git a/clang/test/CodeGenHLSL/builtins/exp2.hlsl b/clang/test/CodeGenHLSL/builtins/exp2.hlsl index ed8cfcf..b4d9c41 100644 --- a/clang/test/CodeGenHLSL/builtins/exp2.hlsl +++ b/clang/test/CodeGenHLSL/builtins/exp2.hlsl @@ -6,47 +6,47 @@ // RUN: FileCheck %s --check-prefixes=CHECK,NO_HALF // NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) half @_Z14test_exp2_half -// NATIVE_HALF: %elt.exp2 = call reassoc nnan ninf nsz arcp afn half @llvm.exp2.f16( -// NATIVE_HALF: ret half %elt.exp2 +// NATIVE_HALF: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.exp2.f16( +// NATIVE_HALF: ret half [[EXP2]] // NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) float @_Z14test_exp2_half -// NO_HALF: %elt.exp2 = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32( -// NO_HALF: ret float %elt.exp2 +// NO_HALF: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32( +// NO_HALF: ret float [[EXP2]] half test_exp2_half(half p0) { return exp2(p0); } // NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x half> @_Z15test_exp2_half2 -// NATIVE_HALF: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.exp2.v2f16 -// NATIVE_HALF: ret <2 x half> %elt.exp2 +// NATIVE_HALF: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.exp2.v2f16 +// NATIVE_HALF: ret <2 x half> [[EXP2]] // NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z15test_exp2_half2 -// NO_HALF: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32( -// NO_HALF: ret <2 x float> %elt.exp2 +// NO_HALF: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32( +// NO_HALF: ret <2 x float> [[EXP2]] half2 test_exp2_half2(half2 p0) { return exp2(p0); } // NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x half> @_Z15test_exp2_half3 -// NATIVE_HALF: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.exp2.v3f16 -// NATIVE_HALF: ret <3 x half> %elt.exp2 +// NATIVE_HALF: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.exp2.v3f16 +// NATIVE_HALF: ret <3 x half> [[EXP2]] // NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z15test_exp2_half3 -// NO_HALF: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32( -// NO_HALF: ret <3 x float> %elt.exp2 +// NO_HALF: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32( +// NO_HALF: ret <3 x float> [[EXP2]] half3 test_exp2_half3(half3 p0) { return exp2(p0); } // NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x half> @_Z15test_exp2_half4 -// NATIVE_HALF: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.exp2.v4f16 -// NATIVE_HALF: ret <4 x half> %elt.exp2 +// NATIVE_HALF: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.exp2.v4f16 +// NATIVE_HALF: ret <4 x half> [[EXP2]] // NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z15test_exp2_half4 -// NO_HALF: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32( -// NO_HALF: ret <4 x float> %elt.exp2 +// NO_HALF: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32( +// NO_HALF: ret <4 x float> [[EXP2]] half4 test_exp2_half4(half4 p0) { return exp2(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z15test_exp2_float -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32( -// CHECK: ret float %elt.exp2 +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32( +// CHECK: ret float [[EXP2]] float test_exp2_float(float p0) { return exp2(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z16test_exp2_float2 -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32 -// CHECK: ret <2 x float> %elt.exp2 +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32 +// CHECK: ret <2 x float> [[EXP2]] float2 test_exp2_float2(float2 p0) { return exp2(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z16test_exp2_float3 -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32 -// CHECK: ret <3 x float> %elt.exp2 +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32 +// CHECK: ret <3 x float> [[EXP2]] float3 test_exp2_float3(float3 p0) { return exp2(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z16test_exp2_float4 -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32 -// CHECK: ret <4 x float> %elt.exp2 +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32 +// CHECK: ret <4 x float> [[EXP2]] float4 test_exp2_float4(float4 p0) { return exp2(p0); } diff --git a/clang/test/CodeGenHLSL/builtins/f16tof32-builtin.hlsl b/clang/test/CodeGenHLSL/builtins/f16tof32-builtin.hlsl new file mode 100644 index 0000000..65dba66 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/f16tof32-builtin.hlsl @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ +// RUN: -o - | FileCheck %s + +// CHECK: define hidden noundef nofpclass(nan inf) float +// CHECK: %hlsl.f16tof32 = call reassoc nnan ninf nsz arcp afn float @llvm.dx.legacyf16tof32.i32(i32 %0) +// CHECK: ret float %hlsl.f16tof32 +// CHECK: declare float @llvm.dx.legacyf16tof32.i32(i32) +float test_scalar(uint p0) { return __builtin_hlsl_elementwise_f16tof32(p0); } + +// CHECK: define hidden noundef nofpclass(nan inf) <2 x float> +// CHECK: %hlsl.f16tof32 = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.dx.legacyf16tof32.v2i32(<2 x i32> %0) +// CHECK: ret <2 x float> %hlsl.f16tof32 +// CHECK: declare <2 x float> @llvm.dx.legacyf16tof32.v2i32(<2 x i32>) +float2 test_uint2(uint2 p0) { return __builtin_hlsl_elementwise_f16tof32(p0); } + +// CHECK: define hidden noundef nofpclass(nan inf) <3 x float> @_Z10test_uint3Dv3_j(<3 x i32> noundef %p0) #0 { +// CHECK: %hlsl.f16tof32 = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.dx.legacyf16tof32.v3i32(<3 x i32> %0) +// CHECK: ret <3 x float> %hlsl.f16tof32 +// CHECK: declare <3 x float> @llvm.dx.legacyf16tof32.v3i32(<3 x i32>) +float3 test_uint3(uint3 p0) { return __builtin_hlsl_elementwise_f16tof32(p0); } + +// CHECK: define hidden noundef nofpclass(nan inf) <4 x float> @_Z10test_uint4Dv4_j(<4 x i32> noundef %p0) #0 { +// CHECK: %hlsl.f16tof32 = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.legacyf16tof32.v4i32(<4 x i32> %0) +// CHECK: ret <4 x float> %hlsl.f16tof32 +// CHECK: declare <4 x float> @llvm.dx.legacyf16tof32.v4i32(<4 x i32>) +float4 test_uint4(uint4 p0) { return __builtin_hlsl_elementwise_f16tof32(p0); } + + + diff --git a/clang/test/CodeGenHLSL/builtins/f16tof32.hlsl b/clang/test/CodeGenHLSL/builtins/f16tof32.hlsl new file mode 100644 index 0000000..b68bc19 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/f16tof32.hlsl @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ +// RUN: -o - | FileCheck %s + +// CHECK: define hidden noundef nofpclass(nan inf) float +// CHECK: %hlsl.f16tof32 = call reassoc nnan ninf nsz arcp afn float @llvm.dx.legacyf16tof32.i32(i32 %0) +// CHECK: ret float %hlsl.f16tof32 +// CHECK: declare float @llvm.dx.legacyf16tof32.i32(i32) +float test_scalar(uint p0) { return f16tof32(p0); } + +// CHECK: define hidden noundef nofpclass(nan inf) <2 x float> +// CHECK: %hlsl.f16tof32 = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.dx.legacyf16tof32.v2i32(<2 x i32> %0) +// CHECK: ret <2 x float> %hlsl.f16tof32 +// CHECK: declare <2 x float> @llvm.dx.legacyf16tof32.v2i32(<2 x i32>) +float2 test_uint2(uint2 p0) { return f16tof32(p0); } + +// CHECK: define hidden noundef nofpclass(nan inf) <3 x float> @_Z10test_uint3Dv3_j(<3 x i32> noundef %p0) #0 { +// CHECK: %hlsl.f16tof32 = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.dx.legacyf16tof32.v3i32(<3 x i32> %0) +// CHECK: ret <3 x float> %hlsl.f16tof32 +// CHECK: declare <3 x float> @llvm.dx.legacyf16tof32.v3i32(<3 x i32>) +float3 test_uint3(uint3 p0) { return f16tof32(p0); } + +// CHECK: define hidden noundef nofpclass(nan inf) <4 x float> @_Z10test_uint4Dv4_j(<4 x i32> noundef %p0) #0 { +// CHECK: %hlsl.f16tof32 = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.legacyf16tof32.v4i32(<4 x i32> %0) +// CHECK: ret <4 x float> %hlsl.f16tof32 +// CHECK: declare <4 x float> @llvm.dx.legacyf16tof32.v4i32(<4 x i32>) +float4 test_uint4(uint4 p0) { return f16tof32(p0); } + + + diff --git a/clang/test/CodeGenHLSL/builtins/faceforward.hlsl b/clang/test/CodeGenHLSL/builtins/faceforward.hlsl index 70459d8..261454e 100644 --- a/clang/test/CodeGenHLSL/builtins/faceforward.hlsl +++ b/clang/test/CodeGenHLSL/builtins/faceforward.hlsl @@ -1,9 +1,9 @@ // RUN: %clang_cc1 -finclude-default-header -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type -fnative-int16-type \ -// RUN: -emit-llvm -o - | FileCheck %s +// RUN: -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,DXCHECK // RUN: %clang_cc1 -finclude-default-header -triple \ // RUN: spirv-unknown-vulkan-compute %s -fnative-half-type -fnative-int16-type \ -// RUN: -emit-llvm -o - | FileCheck %s --check-prefix=SPVCHECK +// RUN: -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,SPVCHECK // CHECK-LABEL: test_faceforward_half // CHECK: %hlsl.dot.i = fmul reassoc nnan ninf nsz arcp afn half %{{.*}}, %{{.*}} @@ -11,42 +11,31 @@ // CHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn half %{{.*}} // CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %cmp.i, half %{{.*}}, half %fneg.i // CHECK: ret half %hlsl.select.i -// SPVCHECK-LABEL: test_faceforward_half -// SPVCHECK: %spv.faceforward.i = call reassoc nnan ninf nsz arcp afn noundef half @llvm.spv.faceforward.f16(half %{{.*}}, half %{{.*}}, half %{{.*}}) -// SPVCHECK: ret half %spv.faceforward.i half test_faceforward_half(half N, half I, half Ng) { return faceforward(N, I, Ng); } // CHECK-LABEL: test_faceforward_half2 -// CHECK: %hlsl.dot.i = call reassoc nnan ninf nsz arcp afn half @llvm.dx.fdot.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}}) +// DXCHECK: %hlsl.dot.i = call reassoc nnan ninf nsz arcp afn half @llvm.[[ICF:dx]].fdot.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}}) +// SPVCHECK: %hlsl.dot.i = call reassoc nnan ninf nsz arcp afn half @llvm.[[ICF:spv]].fdot.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}}) // CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn olt half %hlsl.dot.i, 0xH0000 // CHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <2 x half> %{{.*}} // CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %cmp.i, <2 x half> %{{.*}}, <2 x half> %fneg.i // CHECK: ret <2 x half> %hlsl.select.i -// SPVCHECK-LABEL: test_faceforward_half2 -// SPVCHECK: %spv.faceforward.i = call reassoc nnan ninf nsz arcp afn noundef <2 x half> @llvm.spv.faceforward.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}}, <2 x half> %{{.*}}) -// SPVCHECK: ret <2 x half> %spv.faceforward.i half2 test_faceforward_half2(half2 N, half2 I, half2 Ng) { return faceforward(N, I, Ng); } // CHECK-LABEL: test_faceforward_half3 -// CHECK: %hlsl.dot.i = call reassoc nnan ninf nsz arcp afn half @llvm.dx.fdot.v3f16(<3 x half> %{{.*}}, <3 x half> %{{.*}}) +// CHECK: %hlsl.dot.i = call reassoc nnan ninf nsz arcp afn half @llvm.[[ICF]].fdot.v3f16(<3 x half> %{{.*}}, <3 x half> %{{.*}}) // CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn olt half %hlsl.dot.i, 0xH0000 // CHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <3 x half> %{{.*}} // CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %cmp.i, <3 x half> %{{.*}}, <3 x half> %fneg.i // CHECK: ret <3 x half> %hlsl.select.i -// SPVCHECK-LABEL: test_faceforward_half3 -// SPVCHECK: %spv.faceforward.i = call reassoc nnan ninf nsz arcp afn noundef <3 x half> @llvm.spv.faceforward.v3f16(<3 x half> %{{.*}}, <3 x half> %{{.*}}, <3 x half> %{{.*}}) -// SPVCHECK: ret <3 x half> %spv.faceforward.i half3 test_faceforward_half3(half3 N, half3 I, half3 Ng) { return faceforward(N, I, Ng); } // CHECK-LABEL: test_faceforward_half4 -// CHECK: %hlsl.dot.i = call reassoc nnan ninf nsz arcp afn half @llvm.dx.fdot.v4f16(<4 x half> %{{.*}}, <4 x half> %{{.*}}) +// CHECK: %hlsl.dot.i = call reassoc nnan ninf nsz arcp afn half @llvm.[[ICF]].fdot.v4f16(<4 x half> %{{.*}}, <4 x half> %{{.*}}) // CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn olt half %hlsl.dot.i, 0xH0000 // CHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <4 x half> %{{.*}} // CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %cmp.i, <4 x half> %{{.*}}, <4 x half> %fneg.i // CHECK: ret <4 x half> %hlsl.select.i -// SPVCHECK-LABEL: test_faceforward_half4 -// SPVCHECK: %spv.faceforward.i = call reassoc nnan ninf nsz arcp afn noundef <4 x half> @llvm.spv.faceforward.v4f16(<4 x half> %{{.*}}, <4 x half> %{{.*}}, <4 x half> %{{.*}}) -// SPVCHECK: ret <4 x half> %spv.faceforward.i half4 test_faceforward_half4(half4 N, half4 I, half4 Ng) { return faceforward(N, I, Ng); } // CHECK-LABEL: test_faceforward_float @@ -55,40 +44,28 @@ half4 test_faceforward_half4(half4 N, half4 I, half4 Ng) { return faceforward(N, // CHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn float %{{.*}} // CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %cmp.i, float %{{.*}}, float %fneg.i // CHECK: ret float %hlsl.select.i -// SPVCHECK-LABEL: test_faceforward_float -// SPVCHECK: %spv.faceforward.i = call reassoc nnan ninf nsz arcp afn noundef float @llvm.spv.faceforward.f32(float %{{.*}}, float %{{.*}}, float %{{.*}}) -// SPVCHECK: ret float %spv.faceforward.i float test_faceforward_float(float N, float I, float Ng) { return faceforward(N, I, Ng); } // CHECK-LABEL: test_faceforward_float2 -// CHECK: %hlsl.dot.i = call reassoc nnan ninf nsz arcp afn float @llvm.dx.fdot.v2f32(<2 x float> %{{.*}}, <2 x float> %{{.*}}) +// CHECK: %hlsl.dot.i = call reassoc nnan ninf nsz arcp afn float @llvm.[[ICF]].fdot.v2f32(<2 x float> %{{.*}}, <2 x float> %{{.*}}) // CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn olt float %hlsl.dot.i, 0.000000e+00 // CHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <2 x float> %{{.*}} // CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %cmp.i, <2 x float> %{{.*}}, <2 x float> %fneg.i // CHECK: ret <2 x float> %hlsl.select.i -// SPVCHECK-LABEL: test_faceforward_float2 -// SPVCHECK: %spv.faceforward.i = call reassoc nnan ninf nsz arcp afn noundef <2 x float> @llvm.spv.faceforward.v2f32(<2 x float> %{{.*}}, <2 x float> %{{.*}}, <2 x float> %{{.*}}) -// SPVCHECK: ret <2 x float> %spv.faceforward.i float2 test_faceforward_float2(float2 N, float2 I, float2 Ng) { return faceforward(N, I, Ng); } // CHECK-LABEL: test_faceforward_float3 -// CHECK: %hlsl.dot.i = call reassoc nnan ninf nsz arcp afn float @llvm.dx.fdot.v3f32(<3 x float> %{{.*}}, <3 x float> %{{.*}}) +// CHECK: %hlsl.dot.i = call reassoc nnan ninf nsz arcp afn float @llvm.[[ICF]].fdot.v3f32(<3 x float> %{{.*}}, <3 x float> %{{.*}}) // CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn olt float %hlsl.dot.i, 0.000000e+00 // CHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <3 x float> %{{.*}} // CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %cmp.i, <3 x float> %{{.*}}, <3 x float> %fneg.i // CHECK: ret <3 x float> %hlsl.select.i -// SPVCHECK-LABEL: test_faceforward_float3 -// SPVCHECK: %spv.faceforward.i = call reassoc nnan ninf nsz arcp afn noundef <3 x float> @llvm.spv.faceforward.v3f32(<3 x float> %{{.*}}, <3 x float> %{{.*}}, <3 x float> %{{.*}}) -// SPVCHECK: ret <3 x float> %spv.faceforward.i float3 test_faceforward_float3(float3 N, float3 I, float3 Ng) { return faceforward(N, I, Ng); } // CHECK-LABEL: test_faceforward_float4 -// CHECK: %hlsl.dot.i = call reassoc nnan ninf nsz arcp afn float @llvm.dx.fdot.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}) +// CHECK: %hlsl.dot.i = call reassoc nnan ninf nsz arcp afn float @llvm.[[ICF]].fdot.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}) // CHECK: %cmp.i = fcmp reassoc nnan ninf nsz arcp afn olt float %hlsl.dot.i, 0.000000e+00 // CHECK: %fneg.i = fneg reassoc nnan ninf nsz arcp afn <4 x float> %{{.*}} // CHECK: %hlsl.select.i = select reassoc nnan ninf nsz arcp afn i1 %cmp.i, <4 x float> %{{.*}}, <4 x float> %fneg.i // CHECK: ret <4 x float> %hlsl.select.i -// SPVCHECK-LABEL: test_faceforward_float4 -// SPVCHECK: %spv.faceforward.i = call reassoc nnan ninf nsz arcp afn noundef <4 x float> @llvm.spv.faceforward.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}) -// SPVCHECK: ret <4 x float> %spv.faceforward.i float4 test_faceforward_float4(float4 N, float4 I, float4 Ng) { return faceforward(N, I, Ng); } diff --git a/clang/test/CodeGenHLSL/builtins/firstbithigh.hlsl b/clang/test/CodeGenHLSL/builtins/firstbithigh.hlsl index 368d652..51b0f81 100644 --- a/clang/test/CodeGenHLSL/builtins/firstbithigh.hlsl +++ b/clang/test/CodeGenHLSL/builtins/firstbithigh.hlsl @@ -1,161 +1,260 @@ // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ -// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type -fnative-int16-type \ -// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s -DTARGET=dx +// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ +// RUN: -fnative-int16-type -emit-llvm -O1 -o - | FileCheck %s -DTARGET=dx \ +// RUN: --check-prefixes=CHECK,DXCHECK // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ -// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type -fnative-int16-type \ -// RUN: -emit-llvm -disable-llvm-passes \ -// RUN: -o - | FileCheck %s -DTARGET=spv +// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \ +// RUN: -fnative-int16-type -emit-llvm -O1 -o - | FileCheck %s -DTARGET=spv #ifdef __HLSL_ENABLE_16_BIT // CHECK-LABEL: test_firstbithigh_ushort -// CHECK: call i32 @llvm.[[TARGET]].firstbituhigh.i16 +// CHECK: [[FBH:%.*]] = tail call {{.*}}i32 @llvm.[[TARGET]].firstbituhigh.i16 +// DXCHECK-NEXT: [[SUB:%.*]] = sub i32 15, [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 [[FBH]], -1 +// DXCHECK-NEXT: select i1 %cmp.i, i32 -1, i32 [[SUB]] +// CHECK-NEXT: ret i32 uint test_firstbithigh_ushort(uint16_t p0) { return firstbithigh(p0); } // CHECK-LABEL: test_firstbithigh_ushort2 -// CHECK: call <2 x i32> @llvm.[[TARGET]].firstbituhigh.v2i16 +// CHECK: [[FBH:%.*]] = tail call {{.*}}<2 x i32> @llvm.[[TARGET]].firstbituhigh.v2i16 +// DXCHECK-NEXT: [[SUB:%.*]] = sub <2 x i32> splat (i32 15), [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <2 x i32> [[FBH]], splat (i32 -1) +// DXCHECK-NEXT: select <2 x i1> %cmp.i, <2 x i32> splat (i32 -1), <2 x i32> [[SUB]] +// CHECK-NEXT: ret <2 x i32> uint2 test_firstbithigh_ushort2(uint16_t2 p0) { return firstbithigh(p0); } // CHECK-LABEL: test_firstbithigh_ushort3 -// CHECK: call <3 x i32> @llvm.[[TARGET]].firstbituhigh.v3i16 +// CHECK: [[FBH:%.*]] = tail call {{.*}}<3 x i32> @llvm.[[TARGET]].firstbituhigh.v3i16 +// DXCHECK-NEXT: [[SUB:%.*]] = sub <3 x i32> splat (i32 15), [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <3 x i32> [[FBH]], splat (i32 -1) +// DXCHECK-NEXT: select <3 x i1> %cmp.i, <3 x i32> splat (i32 -1), <3 x i32> [[SUB]] +// CHECK-NEXT: ret <3 x i32> uint3 test_firstbithigh_ushort3(uint16_t3 p0) { return firstbithigh(p0); } // CHECK-LABEL: test_firstbithigh_ushort4 -// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i16 +// CHECK: [[FBH:%.*]] = tail call {{.*}}<4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i16 +// DXCHECK-NEXT: [[SUB:%.*]] = sub <4 x i32> splat (i32 15), [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <4 x i32> [[FBH]], splat (i32 -1) +// DXCHECK-NEXT: select <4 x i1> %cmp.i, <4 x i32> splat (i32 -1), <4 x i32> [[SUB]] +// CHECK-NEXT: ret <4 x i32> uint4 test_firstbithigh_ushort4(uint16_t4 p0) { return firstbithigh(p0); } // CHECK-LABEL: test_firstbithigh_short -// CHECK: call i32 @llvm.[[TARGET]].firstbitshigh.i16 +// CHECK: [[FBH:%.*]] = tail call {{.*}}i32 @llvm.[[TARGET]].firstbitshigh.i16 +// DXCHECK-NEXT: [[SUB:%.*]] = sub i32 15, [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 [[FBH]], -1 +// DXCHECK-NEXT: select i1 %cmp.i, i32 -1, i32 [[SUB]] +// CHECK-NEXT: ret i32 uint test_firstbithigh_short(int16_t p0) { return firstbithigh(p0); } // CHECK-LABEL: test_firstbithigh_short2 -// CHECK: call <2 x i32> @llvm.[[TARGET]].firstbitshigh.v2i16 +// CHECK: [[FBH:%.*]] = tail call {{.*}}<2 x i32> @llvm.[[TARGET]].firstbitshigh.v2i16 +// DXCHECK-NEXT: [[SUB:%.*]] = sub <2 x i32> splat (i32 15), [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <2 x i32> [[FBH]], splat (i32 -1) +// DXCHECK-NEXT: select <2 x i1> %cmp.i, <2 x i32> splat (i32 -1), <2 x i32> [[SUB]] +// CHECK-NEXT: ret <2 x i32> uint2 test_firstbithigh_short2(int16_t2 p0) { return firstbithigh(p0); } // CHECK-LABEL: test_firstbithigh_short3 -// CHECK: call <3 x i32> @llvm.[[TARGET]].firstbitshigh.v3i16 +// CHECK: [[FBH:%.*]] = tail call {{.*}}<3 x i32> @llvm.[[TARGET]].firstbitshigh.v3i16 +// DXCHECK-NEXT: [[SUB:%.*]] = sub <3 x i32> splat (i32 15), [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <3 x i32> [[FBH]], splat (i32 -1) +// DXCHECK-NEXT: select <3 x i1> %cmp.i, <3 x i32> splat (i32 -1), <3 x i32> [[SUB]] +// CHECK-NEXT: ret <3 x i32> uint3 test_firstbithigh_short3(int16_t3 p0) { return firstbithigh(p0); } // CHECK-LABEL: test_firstbithigh_short4 -// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbitshigh.v4i16 +// CHECK: [[FBH:%.*]] = tail call {{.*}}<4 x i32> @llvm.[[TARGET]].firstbitshigh.v4i16 +// DXCHECK-NEXT: [[SUB:%.*]] = sub <4 x i32> splat (i32 15), [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <4 x i32> [[FBH]], splat (i32 -1) +// DXCHECK-NEXT: select <4 x i1> %cmp.i, <4 x i32> splat (i32 -1), <4 x i32> [[SUB]] +// CHECK-NEXT: ret <4 x i32> uint4 test_firstbithigh_short4(int16_t4 p0) { return firstbithigh(p0); } #endif // __HLSL_ENABLE_16_BIT // CHECK-LABEL: test_firstbithigh_uint -// CHECK: call i32 @llvm.[[TARGET]].firstbituhigh.i32 +// CHECK: [[FBH:%.*]] = tail call {{.*}}i32 @llvm.[[TARGET]].firstbituhigh.i32 +// DXCHECK-NEXT: [[SUB:%.*]] = sub i32 31, [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 [[FBH]], -1 +// DXCHECK-NEXT: select i1 %cmp.i, i32 -1, i32 [[SUB]] +// CHECK-NEXT: ret i32 uint test_firstbithigh_uint(uint p0) { return firstbithigh(p0); } // CHECK-LABEL: test_firstbithigh_uint2 -// CHECK: call <2 x i32> @llvm.[[TARGET]].firstbituhigh.v2i32 +// CHECK: [[FBH:%.*]] = tail call {{.*}}<2 x i32> @llvm.[[TARGET]].firstbituhigh.v2i32 +// DXCHECK-NEXT: [[SUB:%.*]] = sub <2 x i32> splat (i32 31), [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <2 x i32> [[FBH]], splat (i32 -1) +// DXCHECK-NEXT: select <2 x i1> %cmp.i, <2 x i32> splat (i32 -1), <2 x i32> [[SUB]] +// CHECK-NEXT: ret <2 x i32> uint2 test_firstbithigh_uint2(uint2 p0) { return firstbithigh(p0); } // CHECK-LABEL: test_firstbithigh_uint3 -// CHECK: call <3 x i32> @llvm.[[TARGET]].firstbituhigh.v3i32 +// CHECK: [[FBH:%.*]] = tail call {{.*}}<3 x i32> @llvm.[[TARGET]].firstbituhigh.v3i32 +// DXCHECK-NEXT: [[SUB:%.*]] = sub <3 x i32> splat (i32 31), [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <3 x i32> [[FBH]], splat (i32 -1) +// DXCHECK-NEXT: select <3 x i1> %cmp.i, <3 x i32> splat (i32 -1), <3 x i32> [[SUB]] +// CHECK-NEXT: ret <3 x i32> uint3 test_firstbithigh_uint3(uint3 p0) { return firstbithigh(p0); } // CHECK-LABEL: test_firstbithigh_uint4 -// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i32 +// CHECK: [[FBH:%.*]] = tail call {{.*}}<4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i32 +// DXCHECK-NEXT: [[SUB:%.*]] = sub <4 x i32> splat (i32 31), [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <4 x i32> [[FBH]], splat (i32 -1) +// DXCHECK-NEXT: select <4 x i1> %cmp.i, <4 x i32> splat (i32 -1), <4 x i32> [[SUB]] +// CHECK-NEXT: ret <4 x i32> uint4 test_firstbithigh_uint4(uint4 p0) { return firstbithigh(p0); } // CHECK-LABEL: test_firstbithigh_ulong -// CHECK: call i32 @llvm.[[TARGET]].firstbituhigh.i64 +// CHECK: [[FBH:%.*]] = tail call {{.*}}i32 @llvm.[[TARGET]].firstbituhigh.i64 +// DXCHECK-NEXT: [[SUB:%.*]] = sub i32 63, [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 [[FBH]], -1 +// DXCHECK-NEXT: select i1 %cmp.i, i32 -1, i32 [[SUB]] +// CHECK-NEXT: ret i32 uint test_firstbithigh_ulong(uint64_t p0) { return firstbithigh(p0); } // CHECK-LABEL: test_firstbithigh_ulong2 -// CHECK: call <2 x i32> @llvm.[[TARGET]].firstbituhigh.v2i64 +// CHECK: [[FBH:%.*]] = tail call {{.*}}<2 x i32> @llvm.[[TARGET]].firstbituhigh.v2i64 +// DXCHECK-NEXT: [[SUB:%.*]] = sub <2 x i32> splat (i32 63), [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <2 x i32> [[FBH]], splat (i32 -1) +// DXCHECK-NEXT: select <2 x i1> %cmp.i, <2 x i32> splat (i32 -1), <2 x i32> [[SUB]] +// CHECK-NEXT: ret <2 x i32> uint2 test_firstbithigh_ulong2(uint64_t2 p0) { return firstbithigh(p0); } // CHECK-LABEL: test_firstbithigh_ulong3 -// CHECK: call <3 x i32> @llvm.[[TARGET]].firstbituhigh.v3i64 +// CHECK: [[FBH:%.*]] = tail call {{.*}}<3 x i32> @llvm.[[TARGET]].firstbituhigh.v3i64 +// DXCHECK-NEXT: [[SUB:%.*]] = sub <3 x i32> splat (i32 63), [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <3 x i32> [[FBH]], splat (i32 -1) +// DXCHECK-NEXT: select <3 x i1> %cmp.i, <3 x i32> splat (i32 -1), <3 x i32> [[SUB]] +// CHECK-NEXT: ret <3 x i32> uint3 test_firstbithigh_ulong3(uint64_t3 p0) { return firstbithigh(p0); } // CHECK-LABEL: test_firstbithigh_ulong4 -// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i64 +// CHECK: [[FBH:%.*]] = tail call {{.*}}<4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i64 +// DXCHECK-NEXT: [[SUB:%.*]] = sub <4 x i32> splat (i32 63), [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <4 x i32> [[FBH]], splat (i32 -1) +// DXCHECK-NEXT: select <4 x i1> %cmp.i, <4 x i32> splat (i32 -1), <4 x i32> [[SUB]] +// CHECK-NEXT: ret <4 x i32> uint4 test_firstbithigh_ulong4(uint64_t4 p0) { return firstbithigh(p0); } // CHECK-LABEL: test_firstbithigh_int -// CHECK: call i32 @llvm.[[TARGET]].firstbitshigh.i32 +// CHECK: [[FBH:%.*]] = tail call {{.*}}i32 @llvm.[[TARGET]].firstbitshigh.i32 +// DXCHECK-NEXT: [[SUB:%.*]] = sub i32 31, [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 [[FBH]], -1 +// DXCHECK-NEXT: select i1 %cmp.i, i32 -1, i32 [[SUB]] +// CHECK-NEXT: ret i32 uint test_firstbithigh_int(int p0) { return firstbithigh(p0); } // CHECK-LABEL: test_firstbithigh_int2 -// CHECK: call <2 x i32> @llvm.[[TARGET]].firstbitshigh.v2i32 +// CHECK: [[FBH:%.*]] = tail call {{.*}}<2 x i32> @llvm.[[TARGET]].firstbitshigh.v2i32 +// DXCHECK-NEXT: [[SUB:%.*]] = sub <2 x i32> splat (i32 31), [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <2 x i32> [[FBH]], splat (i32 -1) +// DXCHECK-NEXT: select <2 x i1> %cmp.i, <2 x i32> splat (i32 -1), <2 x i32> [[SUB]] +// CHECK-NEXT: ret <2 x i32> uint2 test_firstbithigh_int2(int2 p0) { return firstbithigh(p0); } // CHECK-LABEL: test_firstbithigh_int3 -// CHECK: call <3 x i32> @llvm.[[TARGET]].firstbitshigh.v3i32 +// CHECK: [[FBH:%.*]] = tail call {{.*}}<3 x i32> @llvm.[[TARGET]].firstbitshigh.v3i32 +// DXCHECK-NEXT: [[SUB:%.*]] = sub <3 x i32> splat (i32 31), [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <3 x i32> [[FBH]], splat (i32 -1) +// DXCHECK-NEXT: select <3 x i1> %cmp.i, <3 x i32> splat (i32 -1), <3 x i32> [[SUB]] +// CHECK-NEXT: ret <3 x i32> uint3 test_firstbithigh_int3(int3 p0) { return firstbithigh(p0); } // CHECK-LABEL: test_firstbithigh_int4 -// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbitshigh.v4i32 +// CHECK: [[FBH:%.*]] = tail call {{.*}}<4 x i32> @llvm.[[TARGET]].firstbitshigh.v4i32 +// DXCHECK-NEXT: [[SUB:%.*]] = sub <4 x i32> splat (i32 31), [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <4 x i32> [[FBH]], splat (i32 -1) +// DXCHECK-NEXT: select <4 x i1> %cmp.i, <4 x i32> splat (i32 -1), <4 x i32> [[SUB]] +// CHECK-NEXT: ret <4 x i32> uint4 test_firstbithigh_int4(int4 p0) { return firstbithigh(p0); } // CHECK-LABEL: test_firstbithigh_long -// CHECK: call i32 @llvm.[[TARGET]].firstbitshigh.i64 +// CHECK: [[FBH:%.*]] = tail call {{.*}}i32 @llvm.[[TARGET]].firstbitshigh.i64 +// DXCHECK-NEXT: [[SUB:%.*]] = sub i32 63, [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 [[FBH]], -1 +// DXCHECK-NEXT: select i1 %cmp.i, i32 -1, i32 [[SUB]] +// CHECK-NEXT: ret i32 uint test_firstbithigh_long(int64_t p0) { return firstbithigh(p0); } // CHECK-LABEL: test_firstbithigh_long2 -// CHECK: call <2 x i32> @llvm.[[TARGET]].firstbitshigh.v2i64 +// CHECK: [[FBH:%.*]] = tail call {{.*}}<2 x i32> @llvm.[[TARGET]].firstbitshigh.v2i64 +// DXCHECK-NEXT: [[SUB:%.*]] = sub <2 x i32> splat (i32 63), [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <2 x i32> [[FBH]], splat (i32 -1) +// DXCHECK-NEXT: select <2 x i1> %cmp.i, <2 x i32> splat (i32 -1), <2 x i32> [[SUB]] +// CHECK-NEXT: ret <2 x i32> uint2 test_firstbithigh_long2(int64_t2 p0) { return firstbithigh(p0); } // CHECK-LABEL: test_firstbithigh_long3 -// CHECK: call <3 x i32> @llvm.[[TARGET]].firstbitshigh.v3i64 +// CHECK: [[FBH:%.*]] = tail call {{.*}}<3 x i32> @llvm.[[TARGET]].firstbitshigh.v3i64 +// DXCHECK-NEXT: [[SUB:%.*]] = sub <3 x i32> splat (i32 63), [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <3 x i32> [[FBH]], splat (i32 -1) +// DXCHECK-NEXT: select <3 x i1> %cmp.i, <3 x i32> splat (i32 -1), <3 x i32> [[SUB]] +// CHECK-NEXT: ret <3 x i32> uint3 test_firstbithigh_long3(int64_t3 p0) { return firstbithigh(p0); } // CHECK-LABEL: test_firstbithigh_long4 -// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbitshigh.v4i64 +// CHECK: [[FBH:%.*]] = tail call {{.*}}<4 x i32> @llvm.[[TARGET]].firstbitshigh.v4i64 +// DXCHECK-NEXT: [[SUB:%.*]] = sub <4 x i32> splat (i32 63), [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <4 x i32> [[FBH]], splat (i32 -1) +// DXCHECK-NEXT: select <4 x i1> %cmp.i, <4 x i32> splat (i32 -1), <4 x i32> [[SUB]] +// CHECK-NEXT: ret <4 x i32> uint4 test_firstbithigh_long4(int64_t4 p0) { return firstbithigh(p0); } // CHECK-LABEL: test_firstbithigh_upcast -// CHECK: [[FBH:%.*]] = call <4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i32(<4 x i32> %{{.*}}) -// CHECK: [[CONV:%.*]] = zext <4 x i32> [[FBH]] to <4 x i64> -// CHECK: ret <4 x i64> [[CONV]] +// CHECK: [[FBH:%.*]] = tail call {{.*}}<4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i32(<4 x i32> %{{.*}}) +// DXCHECK-NEXT: [[SUB:%.*]] = sub <4 x i32> splat (i32 31), [[FBH]] +// DXCHECK-NEXT: [[ICMP:%.*]] = icmp eq <4 x i32> [[FBH]], splat (i32 -1) +// DXCHECK-NEXT: select <4 x i1> %cmp.i, <4 x i32> splat (i32 -1), <4 x i32> [[SUB]] +// CHECK-NEXT: [[ZEXT:%.*]] = zext <4 x i32> {{.*}} to <4 x i64> +// CHECK-NEXT: ret <4 x i64> [[ZEXT]] uint64_t4 test_firstbithigh_upcast(uint4 p0) { return firstbithigh(p0); } diff --git a/clang/test/CodeGenHLSL/builtins/fwidth.hlsl b/clang/test/CodeGenHLSL/builtins/fwidth.hlsl new file mode 100644 index 0000000..2935fbb --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/fwidth.hlsl @@ -0,0 +1,118 @@ +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s \ +// RUN: -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple spirv-unknown-vulkan1.3-library %s \ +// RUN: -emit-llvm -disable-llvm-passes -fnative-half-type -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK-SPIRV + +// CHECK-LABEL: define {{.*}} half @_ZN4hlsl8__detail11fwidth_implIDhEET_S2_ +// CHECK: %hlsl.ddx.coarse = call {{.*}} half @llvm.dx.ddx.coarse.f16(half %{{.*}}) +// CHECK: %{{.*}} = call {{.*}} half @llvm.fabs.f16(half %{{.*}}) +// CHECK: %hlsl.ddy.coarse = call {{.*}} half @llvm.dx.ddy.coarse.f16(half %{{.*}}) +// CHECK: %{{.*}} = call {{.*}} half @llvm.fabs.f16(half %{{.*}}) +// CHECK: %{{.*}} = fadd {{.*}} %{{.*}}, %{{.*}} +// CHECK: ret half %{{.*}} +// CHECK-LABEL-SPIRV: half @_Z15test_f16_fwidthDh +// CHECK-SPIRV: %spv.fwidth = call {{.*}} half @llvm.spv.fwidth.f16(half %{{.*}}) +// CHECK-SPIRV: ret half %spv.fwidth +half test_f16_fwidth(half val) { + return fwidth(val); +} + +// CHECK-LABEL: define {{.*}} <2 x half> @_ZN4hlsl8__detail11fwidth_implIDv2_DhEET_S3_ +// CHECK: %hlsl.ddx.coarse = call {{.*}} <2 x half> @llvm.dx.ddx.coarse.v2f16(<2 x half> %{{.*}}) +// CHECK: %{{.*}} = call {{.*}} <2 x half> @llvm.fabs.v2f16(<2 x half> %{{.*}}) +// CHECK: %hlsl.ddy.coarse = call {{.*}} <2 x half> @llvm.dx.ddy.coarse.v2f16(<2 x half> %{{.*}}) +// CHECK: %{{.*}} = call {{.*}} <2 x half> @llvm.fabs.v2f16(<2 x half> %{{.*}}) +// CHECK: %{{.*}} = fadd {{.*}} %{{.*}}, %{{.*}} +// CHECK: ret <2 x half> %{{.*}} +// CHECK-LABEL-SPIRV: <2 x half> @_Z16test_f16_fwidth2Dv2_Dh +// CHECK-SPIRV: %spv.fwidth = call {{.*}} <2 x half> @llvm.spv.fwidth.v2f16(<2 x half> %{{.*}}) +// CHECK-SPIRV: ret <2 x half> %spv.fwidth +half2 test_f16_fwidth2(half2 val) { + return fwidth(val); +} + +// CHECK-LABEL: define {{.*}} <3 x half> @_ZN4hlsl8__detail11fwidth_implIDv3_DhEET_S3_ +// CHECK: %hlsl.ddx.coarse = call {{.*}} <3 x half> @llvm.dx.ddx.coarse.v3f16(<3 x half> %{{.*}}) +// CHECK: %{{.*}} = call {{.*}} <3 x half> @llvm.fabs.v3f16(<3 x half> %{{.*}}) +// CHECK: %hlsl.ddy.coarse = call {{.*}} <3 x half> @llvm.dx.ddy.coarse.v3f16(<3 x half> %{{.*}}) +// CHECK: %{{.*}} = call {{.*}} <3 x half> @llvm.fabs.v3f16(<3 x half> %{{.*}}) +// CHECK: %{{.*}} = fadd {{.*}} %{{.*}}, %{{.*}} +// CHECK: ret <3 x half> %{{.*}} +// CHECK-LABEL-SPIRV: <3 x half> @_Z16test_f16_fwidth3Dv3_Dh +// CHECK-SPIRV: %spv.fwidth = call {{.*}} <3 x half> @llvm.spv.fwidth.v3f16(<3 x half> %{{.*}}) +// CHECK-SPIRV: ret <3 x half> %spv.fwidth +half3 test_f16_fwidth3(half3 val) { + return fwidth(val); +} + +// CHECK-LABEL: define {{.*}} <4 x half> @_ZN4hlsl8__detail11fwidth_implIDv4_DhEET_S3_ +// CHECK: %hlsl.ddx.coarse = call {{.*}} <4 x half> @llvm.dx.ddx.coarse.v4f16(<4 x half> %{{.*}}) +// CHECK: %{{.*}} = call {{.*}} <4 x half> @llvm.fabs.v4f16(<4 x half> %{{.*}}) +// CHECK: %hlsl.ddy.coarse = call {{.*}} <4 x half> @llvm.dx.ddy.coarse.v4f16(<4 x half> %{{.*}}) +// CHECK: %{{.*}} = call {{.*}} <4 x half> @llvm.fabs.v4f16(<4 x half> %{{.*}}) +// CHECK: %{{.*}} = fadd {{.*}} %{{.*}}, %{{.*}} +// CHECK: ret <4 x half> %{{.*}} +// CHECK-LABEL-SPIRV: <4 x half> @_Z16test_f16_fwidth4Dv4_Dh +// CHECK-SPIRV: %spv.fwidth = call {{.*}} <4 x half> @llvm.spv.fwidth.v4f16(<4 x half> %{{.*}}) +// CHECK-SPIRV: ret <4 x half> %spv.fwidth +half4 test_f16_fwidth4(half4 val) { + return fwidth(val); +} + +// CHECK-LABEL: define {{.*}} float @_ZN4hlsl8__detail11fwidth_implIfEET_S2_ +// CHECK: %hlsl.ddx.coarse = call {{.*}} float @llvm.dx.ddx.coarse.f32(float %{{.*}}) +// CHECK: %{{.*}} = call {{.*}} float @llvm.fabs.f32(float %{{.*}}) +// CHECK: %hlsl.ddy.coarse = call {{.*}} float @llvm.dx.ddy.coarse.f32(float %{{.*}}) +// CHECK: %{{.*}} = call {{.*}} float @llvm.fabs.f32(float %{{.*}}) +// CHECK: %{{.*}} = fadd {{.*}} %{{.*}}, %{{.*}} +// CHECK: ret float %{{.*}} +// CHECK-LABEL-SPIRV: float @_Z15test_f32_fwidthf +// CHECK-SPIRV: %spv.fwidth = call {{.*}} float @llvm.spv.fwidth.f32(float %{{.*}}) +// CHECK-SPIRV: ret float %spv.fwidth +float test_f32_fwidth(float val) { + return fwidth(val); +} + +// CHECK-LABEL: define {{.*}} <2 x float> @_ZN4hlsl8__detail11fwidth_implIDv2_fEET_S3_ +// CHECK: %hlsl.ddx.coarse = call {{.*}} <2 x float> @llvm.dx.ddx.coarse.v2f32(<2 x float> %{{.*}}) +// CHECK: %{{.*}} = call {{.*}} <2 x float> @llvm.fabs.v2f32(<2 x float> %{{.*}}) +// CHECK: %hlsl.ddy.coarse = call {{.*}} <2 x float> @llvm.dx.ddy.coarse.v2f32(<2 x float> %{{.*}}) +// CHECK: %{{.*}} = call {{.*}} <2 x float> @llvm.fabs.v2f32(<2 x float> %{{.*}}) +// CHECK: %{{.*}} = fadd {{.*}} %{{.*}}, %{{.*}} +// CHECK: ret <2 x float> %{{.*}} +// CHECK-LABEL-SPIRV: <2 x float> @_Z16test_f32_fwidth2Dv2_f +// CHECK-SPIRV: %spv.fwidth = call {{.*}} <2 x float> @llvm.spv.fwidth.v2f32(<2 x float> %{{.*}}) +// CHECK-SPIRV: ret <2 x float> %spv.fwidth +float2 test_f32_fwidth2(float2 val) { + return fwidth(val); +} + +// CHECK-LABEL: define {{.*}} <3 x float> @_ZN4hlsl8__detail11fwidth_implIDv3_fEET_S3_ +// CHECK: %hlsl.ddx.coarse = call {{.*}} <3 x float> @llvm.dx.ddx.coarse.v3f32(<3 x float> %{{.*}}) +// CHECK: %{{.*}} = call {{.*}} <3 x float> @llvm.fabs.v3f32(<3 x float> %{{.*}}) +// CHECK: %hlsl.ddy.coarse = call {{.*}} <3 x float> @llvm.dx.ddy.coarse.v3f32(<3 x float> %{{.*}}) +// CHECK: %{{.*}} = call {{.*}} <3 x float> @llvm.fabs.v3f32(<3 x float> %{{.*}}) +// CHECK: %{{.*}} = fadd {{.*}} %{{.*}}, %{{.*}} +// CHECK: ret <3 x float> %{{.*}} +// CHECK-LABEL-SPIRV: <3 x float> @_Z16test_f32_fwidth3Dv3_f +// CHECK-SPIRV: %spv.fwidth = call {{.*}} <3 x float> @llvm.spv.fwidth.v3f32(<3 x float> %{{.*}}) +// CHECK-SPIRV: ret <3 x float> %spv.fwidth +float3 test_f32_fwidth3(float3 val) { + return fwidth(val); +} + +// CHECK-LABEL: define {{.*}} <4 x float> @_ZN4hlsl8__detail11fwidth_implIDv4_fEET_S3_ +// CHECK: %hlsl.ddx.coarse = call {{.*}} <4 x float> @llvm.dx.ddx.coarse.v4f32(<4 x float> %{{.*}}) +// CHECK: %{{.*}} = call {{.*}} <4 x float> @llvm.fabs.v4f32(<4 x float> %{{.*}}) +// CHECK: %hlsl.ddy.coarse = call {{.*}} <4 x float> @llvm.dx.ddy.coarse.v4f32(<4 x float> %{{.*}}) +// CHECK: %{{.*}} = call {{.*}} <4 x float> @llvm.fabs.v4f32(<4 x float> %{{.*}}) +// CHECK: %{{.*}} = fadd {{.*}} %{{.*}}, %{{.*}} +// CHECK: ret <4 x float> %{{.*}} +// CHECK-LABEL-SPIRV: <4 x float> @_Z16test_f32_fwidth4Dv4_f +// CHECK-SPIRV: %spv.fwidth = call {{.*}} <4 x float> @llvm.spv.fwidth.v4f32(<4 x float> %{{.*}}) +// CHECK-SPIRV: ret <4 x float> %spv.fwidth +float4 test_f32_fwidth4(float4 val) { + return fwidth(val); +} diff --git a/clang/test/CodeGenHLSL/builtins/ldexp.hlsl b/clang/test/CodeGenHLSL/builtins/ldexp.hlsl index 012adc5..2dec126 100644 --- a/clang/test/CodeGenHLSL/builtins/ldexp.hlsl +++ b/clang/test/CodeGenHLSL/builtins/ldexp.hlsl @@ -1,49 +1,49 @@ // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -fnative-int16-type -emit-llvm -disable-llvm-passes -o - | FileCheck %s // CHECK-LABEL: define linkonce_odr hidden noundef nofpclass(nan inf) half @_ZN4hlsl8__detail10ldexp_implIDhEET_S2_S2_ -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn half @llvm.exp2.f16(half %{{.*}}) -// CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn half %elt.exp2, %{{.*}} +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.exp2.f16(half %{{.*}}) +// CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn half [[EXP2]], %{{.*}} // CHECK: ret half %mul half test_ldexp_half(half X, half Exp) { return ldexp(X, Exp); } // CHECK-LABEL: define linkonce_odr hidden noundef nofpclass(nan inf) <2 x half> @_ZN4hlsl8__detail10ldexp_implIDv2_DhEET_S3_S3_ -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.exp2.v2f16(<2 x half> %{{.*}}) -// CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn <2 x half> %elt.exp2, %{{.*}} +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.exp2.v2f16(<2 x half> %{{.*}}) +// CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn <2 x half> [[EXP2]], %{{.*}} // CHECK: ret <2 x half> %mul half2 test_ldexp_half2(half2 X, half2 Exp) { return ldexp(X, Exp); } // CHECK-LABEL: define linkonce_odr hidden noundef nofpclass(nan inf) <3 x half> @_ZN4hlsl8__detail10ldexp_implIDv3_DhEET_S3_S3_ -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.exp2.v3f16(<3 x half> %{{.*}}) -// CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn <3 x half> %elt.exp2, %{{.*}} +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.exp2.v3f16(<3 x half> %{{.*}}) +// CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn <3 x half> [[EXP2]], %{{.*}} // CHECK: ret <3 x half> %mul half3 test_ldexp_half3(half3 X, half3 Exp) { return ldexp(X, Exp); } // CHECK-LABEL: define linkonce_odr hidden noundef nofpclass(nan inf) <4 x half> @_ZN4hlsl8__detail10ldexp_implIDv4_DhEET_S3_S3_ -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.exp2.v4f16(<4 x half> %{{.*}}) -// CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn <4 x half> %elt.exp2, %{{.*}} +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.exp2.v4f16(<4 x half> %{{.*}}) +// CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn <4 x half> [[EXP2]], %{{.*}} // CHECK: ret <4 x half> %mul half4 test_ldexp_half4(half4 X, half4 Exp) { return ldexp(X, Exp); } // CHECK-LABEL: define linkonce_odr hidden noundef nofpclass(nan inf) float @_ZN4hlsl8__detail10ldexp_implIfEET_S2_S2_ -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32(float %{{.*}}) -// CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn float %elt.exp2, %{{.*}} +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32(float %{{.*}}) +// CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn float [[EXP2]], %{{.*}} // CHECK: ret float %mul float test_ldexp_float(float X, float Exp) { return ldexp(X, Exp); } // CHECK-LABEL: define linkonce_odr hidden noundef nofpclass(nan inf) <2 x float> @_ZN4hlsl8__detail10ldexp_implIDv2_fEET_S3_S3_ -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32(<2 x float> %{{.*}}) -// CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn <2 x float> %elt.exp2, %{{.*}} +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32(<2 x float> %{{.*}}) +// CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn <2 x float> [[EXP2]], %{{.*}} // CHECK: ret <2 x float> %mul float2 test_ldexp_float2(float2 X, float2 Exp) { return ldexp(X, Exp); } // CHECK-LABEL: define linkonce_odr hidden noundef nofpclass(nan inf) <3 x float> @_ZN4hlsl8__detail10ldexp_implIDv3_fEET_S3_S3_ -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32(<3 x float> %{{.*}}) -// CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn <3 x float> %elt.exp2, %{{.*}} +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32(<3 x float> %{{.*}}) +// CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn <3 x float> [[EXP2]], %{{.*}} // CHECK: ret <3 x float> %mul float3 test_ldexp_float3(float3 X, float3 Exp) { return ldexp(X, Exp); } // CHECK-LABEL: define linkonce_odr hidden noundef nofpclass(nan inf) <4 x float> @_ZN4hlsl8__detail10ldexp_implIDv4_fEET_S3_S3_ -// CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32(<4 x float> %{{.*}}) -// CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn <4 x float> %elt.exp2, %{{.*}} +// CHECK: [[EXP2:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32(<4 x float> %{{.*}}) +// 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); } diff --git a/clang/test/CodeGenHLSL/builtins/lit.hlsl b/clang/test/CodeGenHLSL/builtins/lit.hlsl index c0b109a..364c2e8 100644 --- a/clang/test/CodeGenHLSL/builtins/lit.hlsl +++ b/clang/test/CodeGenHLSL/builtins/lit.hlsl @@ -7,11 +7,12 @@ // CHECK: %vecinit2.i = insertelement <4 x half> %{{.*}}, half 0xH3C00, i32 3 // CHECK: %cmp4.i = fcmp reassoc nnan ninf nsz arcp afn olt half %{{.*}}, 0xH0000 // CHECK: %hlsl.or.i = or i1 %{{.*}}, %cmp4.i -// CHECK: %elt.log.i = call reassoc nnan ninf nsz arcp afn half @llvm.log.f16(half %{{.*}}) -// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn half %elt.log.i, %{{.*}} -// CHECK: %elt.exp.i = call reassoc nnan ninf nsz arcp afn half @llvm.exp.f16(half %mul.i) +// CHECK: [[LOG:%.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.log.f16(half %{{.*}}) +// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn half [[LOG]], %{{.*}} +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.exp.f16(half %mul.i) // CHECK: %hlsl.select7.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, half 0xH0000, half %{{.*}} -// CHECK: %vecins.i = insertelement <4 x half> %{{.*}}, half %hlsl.select7.i, i32 2 +// CHECK: [[PTR:%.*]] = getelementptr <4 x half>, ptr %Result.i, i32 0, i32 2 +// CHECK: store half %hlsl.select7.i, ptr [[PTR]], align 2 // CHECK: ret <4 x half> %{{.*}} half4 test_lit_half(half NDotL, half NDotH, half M) { return lit(NDotL, NDotH, M); } @@ -22,10 +23,11 @@ half4 test_lit_half(half NDotL, half NDotH, half M) { return lit(NDotL, NDotH, M // CHECK: %vecinit2.i = insertelement <4 x float> %{{.*}}, float 1.000000e+00, i32 3 // CHECK: %cmp4.i = fcmp reassoc nnan ninf nsz arcp afn olt float %{{.*}}, 0.000000e+00 // CHECK: %hlsl.or.i = or i1 %{{.*}}, %cmp4.i -// CHECK: %elt.log.i = call reassoc nnan ninf nsz arcp afn float @llvm.log.f32(float %{{.*}}) -// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float %elt.log.i, %{{.*}} -// CHECK: %elt.exp.i = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32(float %mul.i) +// CHECK: [[LOG:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.log.f32(float %{{.*}}) +// CHECK: %mul.i = fmul reassoc nnan ninf nsz arcp afn float [[LOG]], %{{.*}} +// CHECK: [[EXP:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32(float %mul.i) // CHECK: %hlsl.select7.i = select reassoc nnan ninf nsz arcp afn i1 %{{.*}}, float 0.000000e+00, float %{{.*}} -// CHECK: %vecins.i = insertelement <4 x float> %{{.*}}, float %hlsl.select7.i, i32 2 +// CHECK: [[PTR:%.*]] = getelementptr <4 x float>, ptr %Result.i, i32 0, i32 2 +// CHECK: store float %hlsl.select7.i, ptr [[PTR]], align 4 // CHECK: ret <4 x float> %{{.*}} float4 test_lit_float(float NDotL, float NDotH, float M) { return lit(NDotL, NDotH, M); } diff --git a/clang/test/CodeGenHLSL/builtins/round-overloads.hlsl b/clang/test/CodeGenHLSL/builtins/round-overloads.hlsl index 3b07fce..5719d9d 100644 --- a/clang/test/CodeGenHLSL/builtins/round-overloads.hlsl +++ b/clang/test/CodeGenHLSL/builtins/round-overloads.hlsl @@ -3,86 +3,86 @@ // RUN: FileCheck %s --check-prefixes=CHECK // CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_round_double -// CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn float @llvm.roundeven.f32( -// CHECK: ret float %elt.roundeven +// CHECK: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.roundeven.f32( +// CHECK: ret float [[ROUNDEVEN]] float test_round_double(double p0) { return round(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_round_double2 -// CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.roundeven.v2f32 -// CHECK: ret <2 x float> %elt.roundeven +// CHECK: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.roundeven.v2f32 +// CHECK: ret <2 x float> [[ROUNDEVEN]] float2 test_round_double2(double2 p0) { return round(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_round_double3 -// CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.roundeven.v3f32 -// CHECK: ret <3 x float> %elt.roundeven +// CHECK: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.roundeven.v3f32 +// CHECK: ret <3 x float> [[ROUNDEVEN]] float3 test_round_double3(double3 p0) { return round(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_round_double4 -// CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.roundeven.v4f32 -// CHECK: ret <4 x float> %elt.roundeven +// CHECK: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.roundeven.v4f32 +// CHECK: ret <4 x float> [[ROUNDEVEN]] float4 test_round_double4(double4 p0) { return round(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_round_int -// CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn float @llvm.roundeven.f32( -// CHECK: ret float %elt.roundeven +// CHECK: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.roundeven.f32( +// CHECK: ret float [[ROUNDEVEN]] float test_round_int(int p0) { return round(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_round_int2 -// CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.roundeven.v2f32 -// CHECK: ret <2 x float> %elt.roundeven +// CHECK: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.roundeven.v2f32 +// CHECK: ret <2 x float> [[ROUNDEVEN]] float2 test_round_int2(int2 p0) { return round(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_round_int3 -// CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.roundeven.v3f32 -// CHECK: ret <3 x float> %elt.roundeven +// CHECK: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.roundeven.v3f32 +// CHECK: ret <3 x float> [[ROUNDEVEN]] float3 test_round_int3(int3 p0) { return round(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_round_int4 -// CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.roundeven.v4f32 -// CHECK: ret <4 x float> %elt.roundeven +// CHECK: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.roundeven.v4f32 +// CHECK: ret <4 x float> [[ROUNDEVEN]] float4 test_round_int4(int4 p0) { return round(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_round_uint -// CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn float @llvm.roundeven.f32( -// CHECK: ret float %elt.roundeven +// CHECK: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.roundeven.f32( +// CHECK: ret float [[ROUNDEVEN]] float test_round_uint(uint p0) { return round(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_round_uint2 -// CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.roundeven.v2f32 -// CHECK: ret <2 x float> %elt.roundeven +// CHECK: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.roundeven.v2f32 +// CHECK: ret <2 x float> [[ROUNDEVEN]] float2 test_round_uint2(uint2 p0) { return round(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_round_uint3 -// CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.roundeven.v3f32 -// CHECK: ret <3 x float> %elt.roundeven +// CHECK: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.roundeven.v3f32 +// CHECK: ret <3 x float> [[ROUNDEVEN]] float3 test_round_uint3(uint3 p0) { return round(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_round_uint4 -// CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.roundeven.v4f32 -// CHECK: ret <4 x float> %elt.roundeven +// CHECK: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.roundeven.v4f32 +// CHECK: ret <4 x float> [[ROUNDEVEN]] float4 test_round_uint4(uint4 p0) { return round(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_round_int64_t -// CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn float @llvm.roundeven.f32( -// CHECK: ret float %elt.roundeven +// CHECK: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.roundeven.f32( +// CHECK: ret float [[ROUNDEVEN]] float test_round_int64_t(int64_t p0) { return round(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_round_int64_t2 -// CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.roundeven.v2f32 -// CHECK: ret <2 x float> %elt.roundeven +// CHECK: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.roundeven.v2f32 +// CHECK: ret <2 x float> [[ROUNDEVEN]] float2 test_round_int64_t2(int64_t2 p0) { return round(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_round_int64_t3 -// CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.roundeven.v3f32 -// CHECK: ret <3 x float> %elt.roundeven +// CHECK: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.roundeven.v3f32 +// CHECK: ret <3 x float> [[ROUNDEVEN]] float3 test_round_int64_t3(int64_t3 p0) { return round(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_round_int64_t4 -// CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.roundeven.v4f32 -// CHECK: ret <4 x float> %elt.roundeven +// CHECK: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.roundeven.v4f32 +// CHECK: ret <4 x float> [[ROUNDEVEN]] float4 test_round_int64_t4(int64_t4 p0) { return round(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_round_uint64_t -// CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn float @llvm.roundeven.f32( -// CHECK: ret float %elt.roundeven +// CHECK: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.roundeven.f32( +// CHECK: ret float [[ROUNDEVEN]] float test_round_uint64_t(uint64_t p0) { return round(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_round_uint64_t2 -// CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.roundeven.v2f32 -// CHECK: ret <2 x float> %elt.roundeven +// CHECK: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.roundeven.v2f32 +// CHECK: ret <2 x float> [[ROUNDEVEN]] float2 test_round_uint64_t2(uint64_t2 p0) { return round(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_round_uint64_t3 -// CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.roundeven.v3f32 -// CHECK: ret <3 x float> %elt.roundeven +// CHECK: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.roundeven.v3f32 +// CHECK: ret <3 x float> [[ROUNDEVEN]] float3 test_round_uint64_t3(uint64_t3 p0) { return round(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_round_uint64_t4 -// CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.roundeven.v4f32 -// CHECK: ret <4 x float> %elt.roundeven +// CHECK: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.roundeven.v4f32 +// CHECK: ret <4 x float> [[ROUNDEVEN]] float4 test_round_uint64_t4(uint64_t4 p0) { return round(p0); } diff --git a/clang/test/CodeGenHLSL/builtins/round.hlsl b/clang/test/CodeGenHLSL/builtins/round.hlsl index 0d4afee6..8161b0c 100644 --- a/clang/test/CodeGenHLSL/builtins/round.hlsl +++ b/clang/test/CodeGenHLSL/builtins/round.hlsl @@ -6,47 +6,47 @@ // RUN: FileCheck %s --check-prefixes=CHECK,NO_HALF // NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) half @_Z15test_round_half -// NATIVE_HALF: %elt.roundeven = call reassoc nnan ninf nsz arcp afn half @llvm.roundeven.f16( -// NATIVE_HALF: ret half %elt.roundeven +// NATIVE_HALF: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn half @llvm.roundeven.f16( +// NATIVE_HALF: ret half [[ROUNDEVEN]] // NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) float @_Z15test_round_half -// NO_HALF: %elt.roundeven = call reassoc nnan ninf nsz arcp afn float @llvm.roundeven.f32( -// NO_HALF: ret float %elt.roundeven +// NO_HALF: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.roundeven.f32( +// NO_HALF: ret float [[ROUNDEVEN]] half test_round_half(half p0) { return round(p0); } // NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x half> @_Z16test_round_half2 -// NATIVE_HALF: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.roundeven.v2f16 -// NATIVE_HALF: ret <2 x half> %elt.roundeven +// NATIVE_HALF: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.roundeven.v2f16 +// NATIVE_HALF: ret <2 x half> [[ROUNDEVEN:%.*]] // NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z16test_round_half2 -// NO_HALF: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.roundeven.v2f32( -// NO_HALF: ret <2 x float> %elt.roundeven +// NO_HALF: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.roundeven.v2f32( +// NO_HALF: ret <2 x float> [[ROUNDEVEN]] half2 test_round_half2(half2 p0) { return round(p0); } // NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x half> @_Z16test_round_half3 -// NATIVE_HALF: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.roundeven.v3f16 -// NATIVE_HALF: ret <3 x half> %elt.roundeven +// NATIVE_HALF: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.roundeven.v3f16 +// NATIVE_HALF: ret <3 x half> [[ROUNDEVEN:%.*]] // NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z16test_round_half3 -// NO_HALF: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.roundeven.v3f32( -// NO_HALF: ret <3 x float> %elt.roundeven +// NO_HALF: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.roundeven.v3f32( +// NO_HALF: ret <3 x float> [[ROUNDEVEN]] half3 test_round_half3(half3 p0) { return round(p0); } // NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x half> @_Z16test_round_half4 -// NATIVE_HALF: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.roundeven.v4f16 -// NATIVE_HALF: ret <4 x half> %elt.roundeven +// NATIVE_HALF: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.roundeven.v4f16 +// NATIVE_HALF: ret <4 x half> [[ROUNDEVEN:%.*]] // NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z16test_round_half4 -// NO_HALF: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.roundeven.v4f32( -// NO_HALF: ret <4 x float> %elt.roundeven +// NO_HALF: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.roundeven.v4f32( +// NO_HALF: ret <4 x float> [[ROUNDEVEN]] half4 test_round_half4(half4 p0) { return round(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z16test_round_float -// CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn float @llvm.roundeven.f32( -// CHECK: ret float %elt.roundeven +// CHECK: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.roundeven.f32( +// CHECK: ret float [[ROUNDEVEN]] float test_round_float(float p0) { return round(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z17test_round_float2 -// CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.roundeven.v2f32 -// CHECK: ret <2 x float> %elt.roundeven +// CHECK: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.roundeven.v2f32 +// CHECK: ret <2 x float> [[ROUNDEVEN]] float2 test_round_float2(float2 p0) { return round(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z17test_round_float3 -// CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.roundeven.v3f32 -// CHECK: ret <3 x float> %elt.roundeven +// CHECK: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.roundeven.v3f32 +// CHECK: ret <3 x float> [[ROUNDEVEN]] float3 test_round_float3(float3 p0) { return round(p0); } // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z17test_round_float4 -// CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.roundeven.v4f32 -// CHECK: ret <4 x float> %elt.roundeven +// CHECK: [[ROUNDEVEN:%.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.roundeven.v4f32 +// CHECK: ret <4 x float> [[ROUNDEVEN]] float4 test_round_float4(float4 p0) { return round(p0); } diff --git a/clang/test/CodeGenHLSL/builtins/select.hlsl b/clang/test/CodeGenHLSL/builtins/select.hlsl index 7590b4a..e516984 100644 --- a/clang/test/CodeGenHLSL/builtins/select.hlsl +++ b/clang/test/CodeGenHLSL/builtins/select.hlsl @@ -20,16 +20,6 @@ struct S test_select_infer_struct(bool cond0, struct S tVal, struct S fVal) { return select(cond0, tVal, fVal); } -// CHECK-LABEL: test_select_infer_array -// CHECK: [[TRUE_VAL:%.*]] = load [3 x i32], ptr {{%.*}}, align 4 -// CHECK: [[FALSE_VAL:%.*]] = load [3 x i32], ptr {{%.*}}, align 4 -// CHECK: [[SELECT:%.*]] = select i1 {{%.*}}, [3 x i32] [[TRUE_VAL]], [3 x i32] [[FALSE_VAL]] -// CHECK: store [3 x i32] [[SELECT]], ptr {{%.*}}, align 4 -// CHECK: ret void -int test_select_infer_array(bool cond, int tVal[3], int fVal[3])[3] { - return select(cond, tVal, fVal); -} - // CHECK-LABEL: test_select_bool_vector // CHECK: [[SELECT:%.*]] = select i1 {{%.*}}, <2 x i32> {{%.*}}, <2 x i32> {{%.*}} // CHECK: ret <2 x i32> [[SELECT]] @@ -38,24 +28,24 @@ int2 test_select_bool_vector(bool cond0, int2 tVal, int2 fVal) { } // CHECK-LABEL: test_select_vector_1 -// CHECK: [[SELECT:%.*]] = select <1 x i1> {{%.*}}, <1 x i32> {{%.*}}, <1 x i32> {{%.*}} +// CHECK: [[SELECT:%.*]] = select i1 {{%.*}}, <1 x i32> {{%.*}}, <1 x i32> {{%.*}} // CHECK: ret <1 x i32> [[SELECT]] int1 test_select_vector_1(bool1 cond0, int1 tVals, int1 fVals) { - return select<int,1>(cond0, tVals, fVals); + return select(cond0, tVals, fVals); } // CHECK-LABEL: test_select_vector_2 // CHECK: [[SELECT:%.*]] = select <2 x i1> {{%.*}}, <2 x i32> {{%.*}}, <2 x i32> {{%.*}} // CHECK: ret <2 x i32> [[SELECT]] int2 test_select_vector_2(bool2 cond0, int2 tVals, int2 fVals) { - return select<int,2>(cond0, tVals, fVals); + return select(cond0, tVals, fVals); } // CHECK-LABEL: test_select_vector_3 // CHECK: [[SELECT:%.*]] = select <3 x i1> {{%.*}}, <3 x i32> {{%.*}}, <3 x i32> {{%.*}} // CHECK: ret <3 x i32> [[SELECT]] int3 test_select_vector_3(bool3 cond0, int3 tVals, int3 fVals) { - return select<int,3>(cond0, tVals, fVals); + return select(cond0, tVals, fVals); } // CHECK-LABEL: test_select_vector_4 @@ -86,10 +76,54 @@ int4 test_select_vector_vector_scalar(bool4 cond0, int4 tVals, int fVal) { // CHECK-LABEL: test_select_vector_scalar_scalar // CHECK: [[SPLAT_SRC1:%.*]] = insertelement <4 x i32> poison, i32 {{%.*}}, i64 0 // CHECK: [[SPLAT1:%.*]] = shufflevector <4 x i32> [[SPLAT_SRC1]], <4 x i32> poison, <4 x i32> zeroinitializer -// CHECK: [[SPLAT_SRC2:%.*]] = insertelement <4 x i32> poison, i32 %3, i64 0 +// CHECK: [[SPLAT_SRC2:%.*]] = insertelement <4 x i32> poison, i32 {{%.*}}, i64 0 // CHECK: [[SPLAT2:%.*]] = shufflevector <4 x i32> [[SPLAT_SRC2]], <4 x i32> poison, <4 x i32> zeroinitializer // CHECK: [[SELECT:%.*]] = select <4 x i1> {{%.*}}, <4 x i32> [[SPLAT1]], <4 x i32> [[SPLAT2]] // CHECK: ret <4 x i32> [[SELECT]] int4 test_select_vector_scalar_scalar(bool4 cond0, int tVal, int fVal) { return select(cond0, tVal, fVal); } + +// CHECK-LABEL: test_select_nonbool_cond_vector_4 +// CHECK: [[TMP0:%.*]] = load <4 x i32>, ptr %cond0.addr, align 16 +// CHECK: [[TOBOOL:%.*]] = icmp ne <4 x i32> [[TMP0]], zeroinitializer +// CHECK: [[SELECT:%.*]] = select <4 x i1> [[TOBOOL]], <4 x i1> {{%.*}}, <4 x i1> {{%.*}} +// CHECK: ret <4 x i1> [[SELECT]] +bool4 test_select_nonbool_cond_vector_4(int4 cond0, bool4 tVal, bool4 fVal) { + return select(cond0, tVal, fVal); +} + +// CHECK-LABEL: test_select_nonbool_cond_vector_scalar_vector +// CHECK: [[TMP0:%.*]] = load <3 x i32>, ptr %cond0.addr, align 16 +// CHECK: [[TOBOOL:%.*]] = icmp ne <3 x i32> [[TMP0]], zeroinitializer +// CHECK: [[SPLAT_SRC1:%.*]] = insertelement <3 x i32> poison, i32 {{%.*}}, i64 0 +// CHECK: [[SPLAT1:%.*]] = shufflevector <3 x i32> [[SPLAT_SRC1]], <3 x i32> poison, <3 x i32> zeroinitializer +// CHECK: [[SELECT:%.*]] = select <3 x i1> [[TOBOOL]], <3 x i32> [[SPLAT1]], <3 x i32> {{%.*}} +// CHECK: ret <3 x i32> [[SELECT]] +int3 test_select_nonbool_cond_vector_scalar_vector(int3 cond0, int tVal, int3 fVal) { + return select(cond0, tVal, fVal); +} + +// CHECK-LABEL: test_select_nonbool_cond_vector_vector_scalar +// CHECK: [[TMP0:%.*]] = load <2 x i32>, ptr %cond0.addr, align 8 +// CHECK: [[TOBOOL:%.*]] = icmp ne <2 x i32> [[TMP0]], zeroinitializer +// CHECK: [[SPLAT_SRC1:%.*]] = insertelement <2 x i32> poison, i32 {{%.*}}, i64 0 +// CHECK: [[SPLAT1:%.*]] = shufflevector <2 x i32> [[SPLAT_SRC1]], <2 x i32> poison, <2 x i32> zeroinitializer +// CHECK: [[SELECT:%.*]] = select <2 x i1> [[TOBOOL]], <2 x i32> {{%.*}}, <2 x i32> [[SPLAT1]] +// CHECK: ret <2 x i32> [[SELECT]] +int2 test_select_nonbool_cond_vector_vector_scalar(int2 cond0, int2 tVal, int fVal) { + return select(cond0, tVal, fVal); +} + +// CHECK-LABEL: test_select_nonbool_cond_vector_scalar_scalar +// CHECK: [[TMP0:%.*]] = load <4 x i32>, ptr %cond0.addr, align 16 +// CHECK: [[TOBOOL:%.*]] = icmp ne <4 x i32> [[TMP0]], zeroinitializer +// CHECK: [[SPLAT_SRC1:%.*]] = insertelement <4 x i32> poison, i32 {{%.*}}, i64 0 +// CHECK: [[SPLAT1:%.*]] = shufflevector <4 x i32> [[SPLAT_SRC1]], <4 x i32> poison, <4 x i32> zeroinitializer +// CHECK: [[SPLAT_SRC2:%.*]] = insertelement <4 x i32> poison, i32 {{%.*}}, i64 0 +// CHECK: [[SPLAT2:%.*]] = shufflevector <4 x i32> [[SPLAT_SRC2]], <4 x i32> poison, <4 x i32> zeroinitializer +// CHECK: [[SELECT:%.*]] = select <4 x i1> [[TOBOOL]], <4 x i32> [[SPLAT1]], <4 x i32> [[SPLAT2]] +// CHECK: ret <4 x i32> [[SELECT]] +int4 test_select_nonbool_cond_vector_scalar_scalar(int4 cond0, int tVal, int fVal) { + return select(cond0, tVal, fVal); +} diff --git a/clang/test/CodeGenHLSL/resources/StructuredBuffers-methods-lib.hlsl b/clang/test/CodeGenHLSL/resources/StructuredBuffers-methods-lib.hlsl index 1f248d0..54c386c 100644 --- a/clang/test/CodeGenHLSL/resources/StructuredBuffers-methods-lib.hlsl +++ b/clang/test/CodeGenHLSL/resources/StructuredBuffers-methods-lib.hlsl @@ -104,6 +104,44 @@ export float TestLoad() { // CHECK-NEXT: %[[VAL:.*]] = load float, ptr %[[PTR]] // CHECK-NEXT: ret float %[[VAL]] +export float TestLoadWithStatus() { + uint s1; + uint s2; + float ret = RWSB1.Load(1, s1) + SB1.Load(2, s2); + ret += float(s1 + s2); + return ret; +} + +// CHECK: define noundef nofpclass(nan inf) float @TestLoadWithStatus()() +// CHECK: call {{.*}} float @hlsl::RWStructuredBuffer<float>::Load(unsigned int, unsigned int&)(ptr {{.*}} @RWSB1, i32 noundef 1, ptr {{.*}} %tmp) +// CHECK: call {{.*}} float @hlsl::StructuredBuffer<float>::Load(unsigned int, unsigned int&)(ptr {{.*}} @SB1, i32 noundef 2, ptr {{.*}} %tmp1) +// CHECK: add +// CHECK: ret float + +// CHECK: define {{.*}} float @hlsl::RWStructuredBuffer<float>::Load(unsigned int, unsigned int&)(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status) +// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWStructuredBuffer", ptr %{{.*}}, i32 0, i32 0 +// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", float, 1, 0), ptr %__handle +// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr +// CHECK-NEXT: %[[LOADED_STATUS_ADDR:.*]] = load ptr, ptr %Status.addr +// DXIL-NEXT: %[[STRUCT:.*]] = call { float, i1 } @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %[[HANDLE]], i32 %[[INDEX]], i32 0) +// CHECK-NEXT: %[[VALUE:.*]] = extractvalue { float, i1 } %[[STRUCT]], 0 +// CHECK-NEXT: %[[STATUS_TEMP:.*]] = extractvalue { float, i1 } %[[STRUCT]], 1 +// CHECK-NEXT: %[[STATUS_EXT:.*]] = zext i1 %[[STATUS_TEMP]] to i32 +// CHECK-NEXT: store i32 %[[STATUS_EXT]], ptr %[[LOADED_STATUS_ADDR]], align 4 +// CHECK-NEXT: ret float %[[VALUE]] + +// CHECK: define {{.*}} float @hlsl::StructuredBuffer<float>::Load(unsigned int, unsigned int&)(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status) +// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::StructuredBuffer", ptr %{{.*}}, i32 0, i32 0 +// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", float, 0, 0), ptr %__handle +// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr +// CHECK-NEXT: %[[LOADED_STATUS_ADDR:.*]] = load ptr, ptr %Status.addr, align 4 +// DXIL-NEXT: %[[STRUCT:.*]] = call { float, i1 } @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_f32_0_0t(target("dx.RawBuffer", float, 0, 0) %[[HANDLE]], i32 %[[INDEX]], i32 0) +// CHECK-NEXT: %[[VALUE:.*]] = extractvalue { float, i1 } %[[STRUCT]], 0 +// CHECK-NEXT: %[[STATUS_TEMP:.*]] = extractvalue { float, i1 } %[[STRUCT]], 1 +// CHECK-NEXT: %[[STATUS_EXT:.*]] = zext i1 %[[STATUS_TEMP]] to i32 +// CHECK-NEXT: store i32 %[[STATUS_EXT]], ptr %[[LOADED_STATUS_ADDR]], align 4 +// CHECK-NEXT: ret float %[[VALUE]] + export uint TestGetDimensions() { uint dim1, dim2, dim3, stride1, stride2, stride3; SB1.GetDimensions(dim1, stride1); diff --git a/clang/test/CodeGenHLSL/resources/StructuredBuffers-methods-ps.hlsl b/clang/test/CodeGenHLSL/resources/StructuredBuffers-methods-ps.hlsl index 25fa759..157bae2 100644 --- a/clang/test/CodeGenHLSL/resources/StructuredBuffers-methods-ps.hlsl +++ b/clang/test/CodeGenHLSL/resources/StructuredBuffers-methods-ps.hlsl @@ -65,6 +65,43 @@ export float TestLoad() { // CHECK-NEXT: %[[VAL:.*]] = load <2 x i32>, ptr %[[BUFPTR]] // CHECK-NEXT: ret <2 x i32> %[[VAL]] +export float TestLoadWithStatus() { + uint status; + uint status2; + float val = ROSB1.Load(10, status).x + ROSB2.Load(20, status2).x; + return val + float(status + status2); +} + +// CHECK: define {{.*}} float @TestLoadWithStatus()() +// CHECK: call {{.*}} float @hlsl::RasterizerOrderedStructuredBuffer<float>::Load(unsigned int, unsigned int&)(ptr {{.*}} @ROSB1, i32 noundef 10, ptr {{.*}} %tmp) +// CHECK: call {{.*}} <2 x i32> @hlsl::RasterizerOrderedStructuredBuffer<int vector[2]>::Load(unsigned int, unsigned int&)(ptr {{.*}} @ROSB2, i32 noundef 20, ptr {{.*}} %tmp2) +// CHECK: ret + +// CHECK: define {{.*}} float @hlsl::RasterizerOrderedStructuredBuffer<float>::Load(unsigned int, unsigned int&)(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status) +// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RasterizerOrderedStructuredBuffer", ptr {{.*}}, i32 0, i32 0 +// CHECK-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", float, 1, 1), ptr %__handle +// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr +// CHECK-NEXT: %[[LOADED_STATUS_ADDR:.*]] = load ptr, ptr %Status.addr, align 4 +// DXIL-NEXT: %[[STRUCT:.*]] = call { float, i1 } @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_f32_1_1t(target("dx.RawBuffer", float, 1, 1) %[[HANDLE]], i32 %[[INDEX]], i32 0) +// CHECK-NEXT: %[[VALUE:.*]] = extractvalue { float, i1 } %[[STRUCT]], 0 +// CHECK-NEXT: %[[STATUS_TEMP:.*]] = extractvalue { float, i1 } %[[STRUCT]], 1 +// CHECK-NEXT: %[[STATUS_EXT:.*]] = zext i1 %[[STATUS_TEMP]] to i32 +// CHECK-NEXT: store i32 %[[STATUS_EXT]], ptr %[[LOADED_STATUS_ADDR]], align 4 +// CHECK-NEXT: ret float %[[VALUE]] + +// CHECK: define {{.*}} <2 x i32> @hlsl::RasterizerOrderedStructuredBuffer<int vector[2]>::Load(unsigned int, unsigned int&)(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status) +// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RasterizerOrderedStructuredBuffer.0", ptr {{.*}}, i32 0, i32 0 +// CHECK-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", <2 x i32>, 1, 1), ptr %__handle +// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr +// CHECK-NEXT: %[[LOADED_STATUS_ADDR:.*]] = load ptr, ptr %Status.addr, align 4 +// DXIL-NEXT: %[[STRUCT:.*]] = call { <2 x i32>, i1 } @llvm.dx.resource.load.rawbuffer.v2i32.tdx.RawBuffer_v2i32_1_1t(target("dx.RawBuffer", <2 x i32>, 1, 1) %[[HANDLE]], i32 %[[INDEX]], i32 0) +// CHECK-NEXT: %[[VALUE:.*]] = extractvalue { <2 x i32>, i1 } %[[STRUCT]], 0 +// CHECK-NEXT: %[[STATUS_TEMP:.*]] = extractvalue { <2 x i32>, i1 } %[[STRUCT]], 1 +// CHECK-NEXT: %[[STATUS_EXT:.*]] = zext i1 %[[STATUS_TEMP]] to i32 +// CHECK-NEXT: store i32 %[[STATUS_EXT]], ptr %[[LOADED_STATUS_ADDR]], align 4 +// CHECK-NEXT: ret <2 x i32> %[[VALUE]] + + export uint TestGetDimensions() { uint dim1, dim2, stride1, stride2; ROSB1.GetDimensions(dim1, stride1); diff --git a/clang/test/CodeGenHLSL/resources/TypedBuffers-methods.hlsl b/clang/test/CodeGenHLSL/resources/TypedBuffers-methods.hlsl index fdc1ef0..499f5b1 100644 --- a/clang/test/CodeGenHLSL/resources/TypedBuffers-methods.hlsl +++ b/clang/test/CodeGenHLSL/resources/TypedBuffers-methods.hlsl @@ -38,6 +38,44 @@ export float TestLoad() { // CHECK-NEXT: %[[VEC:.*]] = load <4 x i32>, ptr %[[PTR]] // CHECK-NEXT: ret <4 x i32> %[[VEC]] +export float TestLoadWithStatus() { + uint s1; + uint s2; + float ret = Buf.Load(1, s1) + float(RWBuf.Load(2, s2).y); + ret += float(s1 + s2); + return ret; +} + +// CHECK: define noundef nofpclass(nan inf) float @TestLoadWithStatus()() +// CHECK: call {{.*}} float @hlsl::Buffer<float>::Load(unsigned int, unsigned int&)(ptr {{.*}} @Buf, i32 noundef 1, ptr {{.*}} %tmp) +// CHECK: call {{.*}} <4 x i32> @hlsl::RWBuffer<unsigned int vector[4]>::Load(unsigned int, unsigned int&)(ptr {{.*}} @RWBuf, i32 noundef 2, ptr {{.*}} %tmp1) +// CHECK: add +// CHECK: ret float + +// CHECK: define {{.*}} float @hlsl::Buffer<float>::Load(unsigned int, unsigned int&)(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status) +// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::Buffer", ptr %{{.*}}, i32 0, i32 0 +// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.TypedBuffer", float, 0, 0, 0), ptr %__handle +// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr +// CHECK-NEXT: %[[LOADED_STATUS_ADDR:.*]] = load ptr, ptr %Status.addr +// DXIL-NEXT: %[[STRUCT:.*]] = call { float, i1 } @llvm.dx.resource.load.typedbuffer.f32.tdx.TypedBuffer_f32_0_0_0t(target("dx.TypedBuffer", float, 0, 0, 0) %[[HANDLE]], i32 %[[INDEX]]) +// CHECK-NEXT: %[[VALUE:.*]] = extractvalue { float, i1 } %[[STRUCT]], 0 +// CHECK-NEXT: %[[STATUS_TEMP:.*]] = extractvalue { float, i1 } %[[STRUCT]], 1 +// CHECK-NEXT: %[[STATUS_EXT:.*]] = zext i1 %[[STATUS_TEMP]] to i32 +// CHECK-NEXT: store i32 %[[STATUS_EXT]], ptr %[[LOADED_STATUS_ADDR]], align 4 +// CHECK-NEXT: ret float %[[VALUE]] + +// CHECK: define {{.*}} <4 x i32> @hlsl::RWBuffer<unsigned int vector[4]>::Load(unsigned int, unsigned int&)(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status) +// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWBuffer", ptr %{{.*}}, i32 0, i32 0 +// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.TypedBuffer", <4 x i32>, 1, 0, 0), ptr %__handle +// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr +// CHECK-NEXT: %[[LOADED_STATUS_ADDR:.*]] = load ptr, ptr %Status.addr +// DXIL-NEXT: %[[STRUCT:.*]] = call { <4 x i32>, i1 } @llvm.dx.resource.load.typedbuffer.v4i32.tdx.TypedBuffer_v4i32_1_0_0t(target("dx.TypedBuffer", <4 x i32>, 1, 0, 0) %[[HANDLE]], i32 %[[INDEX]]) +// CHECK-NEXT: %[[VALUE:.*]] = extractvalue { <4 x i32>, i1 } %[[STRUCT]], 0 +// CHECK-NEXT: %[[STATUS_TEMP:.*]] = extractvalue { <4 x i32>, i1 } %[[STRUCT]], 1 +// CHECK-NEXT: %[[STATUS_EXT:.*]] = zext i1 %[[STATUS_TEMP]] to i32 +// CHECK-NEXT: store i32 %[[STATUS_EXT]], ptr %[[LOADED_STATUS_ADDR]], align 4 +// CHECK-NEXT: ret <4 x i32> %[[VALUE]] + export uint TestGetDimensions() { uint dim1, dim2; Buf.GetDimensions(dim1); diff --git a/clang/test/CodeGenHLSL/resources/cbuffer.hlsl b/clang/test/CodeGenHLSL/resources/cbuffer.hlsl index c8efe0d..b72cf58 100644 --- a/clang/test/CodeGenHLSL/resources/cbuffer.hlsl +++ b/clang/test/CodeGenHLSL/resources/cbuffer.hlsl @@ -1,37 +1,123 @@ // RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-compute -fnative-half-type -fnative-int16-type -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s -// CHECK: %__cblayout_CBScalars = type <{ float, double, half, i64, i32, i16, i32, i64 }> -// CHECK: %__cblayout_CBVectors = type <{ <3 x float>, <3 x double>, <2 x half>, <3 x i64>, <4 x i32>, <3 x i16>, <3 x i64> }> -// CHECK: %__cblayout_CBArrays = type <{ [3 x float], [2 x <3 x double>], [2 x [2 x half]], [3 x i64], [2 x [3 x [4 x <4 x i32>]]], [1 x i16], [2 x i64], [4 x i32] }> -// CHECK: %__cblayout_CBStructs = type <{ target("dx.Layout", %A, 8, 0), target("dx.Layout", %B, 14, 0, 8), -// CHECK-SAME: target("dx.Layout", %C, 24, 0, 16), [5 x target("dx.Layout", %A, 8, 0)], -// CHECK-SAME: target("dx.Layout", %__cblayout_D, 94, 0), half, <3 x i16> }> +// CHECK: %__cblayout_CBScalars = type <{ +// CHECK-SAME: float, target("dx.Padding", 4), double, +// CHECK-SAME: half, target("dx.Padding", 6), i64, +// CHECK-SAME: i32, i16, target("dx.Padding", 2), i32, target("dx.Padding", 4), +// CHECK-SAME: i64 +// CHECK-SAME: }> + +// CHECK: %__cblayout_CBVectors = type <{ +// CHECK-SAME: <3 x float>, target("dx.Padding", 4), +// CHECK-SAME: <3 x double>, <2 x half>, target("dx.Padding", 4), +// CHECK-SAME: <3 x i64>, target("dx.Padding", 8), +// CHECK-SAME: <4 x i32>, +// CHECK-SAME: <3 x i16>, target("dx.Padding", 10), +// CHECK-SAME: <3 x i64> +// CHECK-SAME: }> + +// CHECK: %__cblayout_CBArrays = type <{ +// CHECK-SAME: <{ [2 x <{ float, target("dx.Padding", 12) }>], float }>, target("dx.Padding", 12), +// CHECK-SAME: <{ [1 x <{ <3 x double>, target("dx.Padding", 8) }>], <3 x double> }>, target("dx.Padding", 8), +// CHECK-SAME: <{ [1 x <{ +// CHECK-SAME: <{ [1 x <{ half, target("dx.Padding", 14) }>], half }>, target("dx.Padding", 14) }>], +// CHECK-SAME: <{ [1 x <{ half, target("dx.Padding", 14) }>], half }> +// CHECK-SAME: }>, target("dx.Padding", 14), +// CHECK-SAME: <{ [2 x <{ i64, target("dx.Padding", 8) }>], i64 }>, target("dx.Padding", 8), +// CHECK-SAME: [2 x [3 x [4 x <4 x i32>]]] +// CHECK-SAME: [1 x i16], target("dx.Padding", 14), +// CHECK-SAME: <{ [1 x <{ i64, target("dx.Padding", 8) }>], i64 }>, target("dx.Padding", 8), +// CHECK-SAME: <{ [3 x <{ i32, target("dx.Padding", 12) }>], i32 }> +// CHECK-SAME: }> + +// CHECK: %__cblayout_CBStructs = type <{ +// CHECK-SAME: %A, target("dx.Padding", 8), + +// TODO: We should have target("dx.Padding", 2) padding after %B, but we don't +// correctly handle 2- and 3-element vectors inside structs yet because of +// DataLayout rules. See https://github.com/llvm/llvm-project/issues/123968. +// +// CHECK-SAME: %B, + +// CHECK-SAME: %C, target("dx.Padding", 8), +// CHECK-SAME: <{ [4 x <{ %A, target("dx.Padding", 8) }>], %A }>, target("dx.Padding", 8), +// CHECK-SAME: %__cblayout_D, half, +// CHECK-SAME: <3 x i16> +// CHECK-SAME: }> // CHECK: %A = type <{ <2 x float> }> // CHECK: %B = type <{ <2 x float>, <3 x i16> }> -// CHECK: %C = type <{ i32, target("dx.Layout", %A, 8, 0) }> -// CHECK: %__cblayout_D = type <{ [2 x [3 x target("dx.Layout", %B, 14, 0, 8)]] }> +// CHECK: %C = type <{ i32, target("dx.Padding", 12), %A }> + +// CHECK: %__cblayout_D = type <{ +// CHECK-SAME: <{ [1 x <{ +// CHECK-SAME: <{ [2 x <{ %B, target("dx.Padding", 2) }>], %B }>, target("dx.Padding", 2) +// CHECK-SAME: }>], +// CHECK-SAME: <{ [2 x <{ %B, target("dx.Padding", 2) }>], %B }> }> +// CHECK-SAME: }> + +// CHECK: %__cblayout_CBClasses = type <{ +// CHECK-SAME: %K, target("dx.Padding", 12), +// CHECK-SAME: %L, target("dx.Padding", 8), +// CHECK-SAME: %M, target("dx.Padding", 12), +// CHECK-SAME: <{ [9 x <{ %K, target("dx.Padding", 12) }>], %K }> +// CHECK-SAME: }> -// CHECK: %__cblayout_CBClasses = type <{ target("dx.Layout", %K, 4, 0), target("dx.Layout", %L, 8, 0, 4), -// CHECK-SAME: target("dx.Layout", %M, 68, 0), [10 x target("dx.Layout", %K, 4, 0)] }> // CHECK: %K = type <{ float }> // CHECK: %L = type <{ float, float }> -// CHECK: %M = type <{ [5 x target("dx.Layout", %K, 4, 0)] }> - -// CHECK: %__cblayout_CBMix = type <{ [2 x target("dx.Layout", %Test, 8, 0, 4)], float, [3 x [2 x <2 x float>]], float, -// CHECK-SAME: target("dx.Layout", %anon, 4, 0), double, target("dx.Layout", %anon.0, 8, 0), float, <1 x double>, i16 }> +// CHECK: %M = type <{ <{ [4 x <{ %K, target("dx.Padding", 12) }>], %K }> }> + +// CHECK: %__cblayout_CBMix = type <{ +// CHECK-SAME: <{ [1 x <{ %Test, target("dx.Padding", 8) }>], %Test }>, float, target("dx.Padding", 4) +// CHECK-SAME: <{ [2 x <{ +// CHECK-SAME: <{ [1 x <{ <2 x float>, target("dx.Padding", 8) }>], <2 x float> }>, target("dx.Padding", 8) }>], +// CHECK-SAME: <{ [1 x <{ <2 x float>, target("dx.Padding", 8) }>], <2 x float> }> +// CHECK-SAME: }>, float, target("dx.Padding", 4), +// CHECK-SAME: %anon, target("dx.Padding", 4), double, +// CHECK-SAME: %anon.0, float, target("dx.Padding", 4), +// CHECK-SAME: <1 x double>, i16 +// CHECK-SAME: }> // CHECK: %Test = type <{ float, float }> // CHECK: %anon = type <{ float }> // CHECK: %anon.0 = type <{ <2 x i32> }> -// CHECK: %__cblayout_CB_A = type <{ [2 x double], [3 x <3 x float>], float, [3 x double], half, [1 x <2 x double>], float, [2 x <3 x half>], <3 x half> }> -// CHECK: %__cblayout_CB_B = type <{ [3 x <3 x double>], <3 x half> }> -// CHECK: %__cblayout_CB_C = type <{ i32, target("dx.Layout", %F, 96, 0, 16, 28, 32, 56, 64, 80, 84, 90), half, target("dx.Layout", %G, 258, 0, 48, 64, 256), double }> - -// CHECK: %F = type <{ double, <3 x float>, float, <3 x double>, half, <2 x double>, float, <3 x half>, <3 x half> }> -// CHECK: %G = type <{ target("dx.Layout", %E, 36, 0, 8, 16, 20, 22, 24, 32), [1 x float], [2 x target("dx.Layout", %F, 96, 0, 16, 28, 32, 56, 64, 80, 84, 90)], half }> -// CHECK: %E = type <{ float, double, float, half, i16, i64, i32 }> +// CHECK: %__cblayout_CB_A = type <{ +// CHECK-SAME: <{ [1 x <{ double, target("dx.Padding", 8) }>], double }>, target("dx.Padding", 8), +// CHECK-SAME: <{ [2 x <{ <3 x float>, target("dx.Padding", 4) }>], <3 x float> }>, float, +// CHECK-SAME: <{ [2 x <{ double, target("dx.Padding", 8) }>], double }>, half, target("dx.Padding", 6), +// CHECK-SAME: [1 x <2 x double>], +// CHECK-SAME: float, target("dx.Padding", 12), +// CHECK-SAME: <{ [1 x <{ <3 x half>, target("dx.Padding", 10) }>], <3 x half> }>, <3 x half> +// CHECK-SAME: }> + +// CHECK: %__cblayout_CB_B = type <{ +// CHECK-SAME: <{ [2 x <{ <3 x double>, target("dx.Padding", 8) }>], <3 x double> }>, <3 x half> +// CHECK-SAME: }> + +// CHECK: %__cblayout_CB_C = type <{ +// CHECK-SAME: i32, target("dx.Padding", 12), +// CHECK-SAME: %F, +// CHECK-SAME: half, target("dx.Padding", 14), +// CHECK-SAME: %G, target("dx.Padding", 6), double +// CHECK-SAME: }> + +// CHECK: %F = type <{ +// CHECK-SAME: double, target("dx.Padding", 8), +// CHECK-SAME: <3 x float>, float, +// CHECK-SAME: <3 x double>, half, target("dx.Padding", 6), +// CHECK-SAME: <2 x double>, +// CHECK-SAME: float, <3 x half>, <3 x half> +// CHECK-SAME: }> + +// CHECK: %G = type <{ +// CHECK-SAME: %E, target("dx.Padding", 12), +// CHECK-SAME: [1 x float], target("dx.Padding", 12), +// CHECK-SAME: [2 x %F], +// CHECK-SAME: half +// CHECK-SAME: }> + +// CHECK: %E = type <{ float, target("dx.Padding", 4), double, float, half, i16, i64, i32 }> cbuffer CBScalars : register(b1, space5) { float a1; @@ -44,8 +130,7 @@ cbuffer CBScalars : register(b1, space5) { int64_t a8; } -// CHECK: @CBScalars.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CBScalars, -// CHECK-SAME: 56, 0, 8, 16, 24, 32, 36, 40, 48)) +// CHECK: @CBScalars.cb = global target("dx.CBuffer", %__cblayout_CBScalars) // CHECK: @a1 = external hidden addrspace(2) global float, align 4 // CHECK: @a2 = external hidden addrspace(2) global double, align 8 // CHECK: @a3 = external hidden addrspace(2) global half, align 2 @@ -67,8 +152,7 @@ cbuffer CBVectors { // FIXME: add a bool vectors after llvm-project/llvm#91639 is added } -// CHECK: @CBVectors.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CBVectors, -// CHECK-SAME: 136, 0, 16, 40, 48, 80, 96, 112)) +// CHECK: @CBVectors.cb = global target("dx.CBuffer", %__cblayout_CBVectors) // CHECK: @b1 = external hidden addrspace(2) global <3 x float>, align 16 // CHECK: @b2 = external hidden addrspace(2) global <3 x double>, align 32 // CHECK: @b3 = external hidden addrspace(2) global <2 x half>, align 4 @@ -89,16 +173,15 @@ cbuffer CBArrays : register(b2) { bool c8[4]; } -// CHECK: @CBArrays.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CBArrays, -// CHECK-SAME: 708, 0, 48, 112, 176, 224, 608, 624, 656)) -// CHECK: @c1 = external hidden addrspace(2) global [3 x float], align 4 -// CHECK: @c2 = external hidden addrspace(2) global [2 x <3 x double>], align 32 -// CHECK: @c3 = external hidden addrspace(2) global [2 x [2 x half]], align 2 -// CHECK: @c4 = external hidden addrspace(2) global [3 x i64], align 8 +// CHECK: @CBArrays.cb = global target("dx.CBuffer", %__cblayout_CBArrays) +// CHECK: @c1 = external hidden addrspace(2) global <{ [2 x <{ float, target("dx.Padding", 12) }>], float }>, align 4 +// CHECK: @c2 = external hidden addrspace(2) global <{ [1 x <{ <3 x double>, target("dx.Padding", 8) }>], <3 x double> }>, align 32 +// CHECK: @c3 = external hidden addrspace(2) global <{ [1 x <{ <{ [1 x <{ half, target("dx.Padding", 14) }>], half }>, target("dx.Padding", 14) }>], <{ [1 x <{ half, target("dx.Padding", 14) }>], half }> }>, align 2 +// CHECK: @c4 = external hidden addrspace(2) global <{ [2 x <{ i64, target("dx.Padding", 8) }>], i64 }>, align 8 // CHECK: @c5 = external hidden addrspace(2) global [2 x [3 x [4 x <4 x i32>]]], align 16 // CHECK: @c6 = external hidden addrspace(2) global [1 x i16], align 2 -// CHECK: @c7 = external hidden addrspace(2) global [2 x i64], align 8 -// CHECK: @c8 = external hidden addrspace(2) global [4 x i32], align 4 +// CHECK: @c7 = external hidden addrspace(2) global <{ [1 x <{ i64, target("dx.Padding", 8) }>], i64 }>, align 8 +// CHECK: @c8 = external hidden addrspace(2) global <{ [3 x <{ i32, target("dx.Padding", 12) }>], i32 }>, align 4 // CHECK: @CBArrays.str = private unnamed_addr constant [9 x i8] c"CBArrays\00", align 1 typedef uint32_t4 uint32_t8[2]; @@ -110,8 +193,7 @@ cbuffer CBTypedefArray : register(space2) { T2 t2[2]; } -// CHECK: @CBTypedefArray.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CBTypedefArray, -// CHECK-SAME: 128, 0, 64)) +// CHECK: @CBTypedefArray.cb = global target("dx.CBuffer", %__cblayout_CBTypedefArray) // CHECK: @t1 = external hidden addrspace(2) global [2 x [2 x <4 x i32>]], align 16 // CHECK: @t2 = external hidden addrspace(2) global [2 x [2 x <4 x i32>]], align 16 // CHECK: @CBTypedefArray.str = private unnamed_addr constant [15 x i8] c"CBTypedefArray\00", align 1 @@ -135,13 +217,12 @@ struct D { Empty es; }; -// CHECK: @CBStructs.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CBStructs, -// CHECK-SAME: 246, 0, 16, 32, 64, 144, 238, 240)) -// CHECK: @a = external hidden addrspace(2) global target("dx.Layout", %A, 8, 0), align 1 -// CHECK: @b = external hidden addrspace(2) global target("dx.Layout", %B, 14, 0, 8), align 1 -// CHECK: @c = external hidden addrspace(2) global target("dx.Layout", %C, 24, 0, 16), align 1 -// CHECK: @array_of_A = external hidden addrspace(2) global [5 x target("dx.Layout", %A, 8, 0)], align 1 -// CHECK: @d = external hidden addrspace(2) global target("dx.Layout", %__cblayout_D, 94, 0), align 1 +// CHECK: @CBStructs.cb = global target("dx.CBuffer", %__cblayout_CBStructs) +// CHECK: @a = external hidden addrspace(2) global %A, align 1 +// CHECK: @b = external hidden addrspace(2) global %B, align 1 +// CHECK: @c = external hidden addrspace(2) global %C, align 1 +// CHECK: @array_of_A = external hidden addrspace(2) global <{ [4 x <{ %A, target("dx.Padding", 8) }>], %A }>, align 1 +// CHECK: @d = external hidden addrspace(2) global %__cblayout_D, align 1 // CHECK: @e = external hidden addrspace(2) global half, align 2 // CHECK: @f = external hidden addrspace(2) global <3 x i16>, align 8 // CHECK: @CBStructs.str = private unnamed_addr constant [10 x i8] c"CBStructs\00", align 1 @@ -176,27 +257,25 @@ cbuffer CBClasses { K ka[10]; }; -// CHECK: @CBClasses.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CBClasses, -// CHECK-SAME: 260, 0, 16, 32, 112)) -// CHECK: @k = external hidden addrspace(2) global target("dx.Layout", %K, 4, 0), align 1 -// CHECK: @l = external hidden addrspace(2) global target("dx.Layout", %L, 8, 0, 4), align 1 -// CHECK: @m = external hidden addrspace(2) global target("dx.Layout", %M, 68, 0), align 1 -// CHECK: @ka = external hidden addrspace(2) global [10 x target("dx.Layout", %K, 4, 0)], align 1 +// CHECK: @CBClasses.cb = global target("dx.CBuffer", %__cblayout_CBClasses) +// CHECK: @k = external hidden addrspace(2) global %K, align 1 +// CHECK: @l = external hidden addrspace(2) global %L, align 1 +// CHECK: @m = external hidden addrspace(2) global %M, align 1 +// CHECK: @ka = external hidden addrspace(2) global <{ [9 x <{ %K, target("dx.Padding", 12) }>], %K }>, align 1 // CHECK: @CBClasses.str = private unnamed_addr constant [10 x i8] c"CBClasses\00", align 1 struct Test { float a, b; }; -// CHECK: @CBMix.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CBMix, -// CHECK-SAME: 170, 0, 24, 32, 120, 128, 136, 144, 152, 160, 168)) -// CHECK: @test = external hidden addrspace(2) global [2 x target("dx.Layout", %Test, 8, 0, 4)], align 1 +// CHECK: @CBMix.cb = global target("dx.CBuffer", %__cblayout_CBMix) +// CHECK: @test = external hidden addrspace(2) global <{ [1 x <{ %Test, target("dx.Padding", 8) }>], %Test }>, align 1 // CHECK: @f1 = external hidden addrspace(2) global float, align 4 -// CHECK: @f2 = external hidden addrspace(2) global [3 x [2 x <2 x float>]], align 8 +// CHECK: @f2 = external hidden addrspace(2) global <{ [2 x <{ <{ [1 x <{ <2 x float>, target("dx.Padding", 8) }>], <2 x float> }>, target("dx.Padding", 8) }>], <{ [1 x <{ <2 x float>, target("dx.Padding", 8) }>], <2 x float> }> }>, align 8 // CHECK: @f3 = external hidden addrspace(2) global float, align 4 -// CHECK: @f4 = external hidden addrspace(2) global target("dx.Layout", %anon, 4, 0), align 1 +// CHECK: @f4 = external hidden addrspace(2) global %anon, align 1 // CHECK: @f5 = external hidden addrspace(2) global double, align 8 -// CHECK: @f6 = external hidden addrspace(2) global target("dx.Layout", %anon.0, 8, 0), align 1 +// CHECK: @f6 = external hidden addrspace(2) global %anon.0, align 1 // CHECK: @f7 = external hidden addrspace(2) global float, align 4 // CHECK: @f8 = external hidden addrspace(2) global <1 x double>, align 8 // CHECK: @f9 = external hidden addrspace(2) global i16, align 2 @@ -215,7 +294,7 @@ cbuffer CBMix { uint16_t f9; }; -// CHECK: @CB_A.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CB_A, 188, 0, 32, 76, 80, 120, 128, 144, 160, 182)) +// CHECK: @CB_A.cb = global target("dx.CBuffer", %__cblayout_CB_A) cbuffer CB_A { double B0[2]; @@ -229,7 +308,7 @@ cbuffer CB_A { half3 B8; } -// CHECK: @CB_B.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CB_B, 94, 0, 88)) +// CHECK: @CB_B.cb = global target("dx.CBuffer", %__cblayout_CB_B) cbuffer CB_B { double3 B9[3]; half3 B10; @@ -264,7 +343,7 @@ struct G { half C3; }; -// CHECK: @CB_C.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CB_C, 400, 0, 16, 112, 128, 392)) +// CHECK: @CB_C.cb = global target("dx.CBuffer", %__cblayout_CB_C) cbuffer CB_C { int D0; F D1; @@ -275,63 +354,63 @@ cbuffer CB_C { // CHECK: define internal void @_init_buffer_CBScalars.cb() // CHECK-NEXT: entry: -// CHECK-NEXT: %CBScalars.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CBScalars, 56, 0, 8, 16, 24, 32, 36, 40, 48)) -// CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBScalarss_56_0_8_16_24_32_36_40_48tt(i32 5, i32 1, i32 1, i32 0, ptr @CBScalars.str) -// CHECK-NEXT: store target("dx.CBuffer", target("dx.Layout", %__cblayout_CBScalars, 56, 0, 8, 16, 24, 32, 36, 40, 48)) %CBScalars.cb_h, ptr @CBScalars.cb, align 4 +// CHECK-NEXT: %CBScalars.cb_h = call target("dx.CBuffer", %__cblayout_CBScalars) +// CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.CBuffer_s___cblayout_CBScalarsst(i32 5, i32 1, i32 1, i32 0, ptr @CBScalars.str) +// CHECK-NEXT: store target("dx.CBuffer", %__cblayout_CBScalars) %CBScalars.cb_h, ptr @CBScalars.cb, align 4 // CHECK: define internal void @_init_buffer_CBVectors.cb() // CHECK-NEXT: entry: -// CHECK-NEXT: %CBVectors.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CBVectors, 136, 0, 16, 40, 48, 80, 96, 112)) -// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBVectorss_136_0_16_40_48_80_96_112tt(i32 0, i32 0, i32 1, i32 0, ptr @CBVectors.str) -// CHECK-NEXT: store target("dx.CBuffer", target("dx.Layout", %__cblayout_CBVectors, 136, 0, 16, 40, 48, 80, 96, 112)) %CBVectors.cb_h, ptr @CBVectors.cb, align 4 +// CHECK-NEXT: %CBVectors.cb_h = call target("dx.CBuffer", %__cblayout_CBVectors) +// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_CBVectorsst(i32 0, i32 0, i32 1, i32 0, ptr @CBVectors.str) +// CHECK-NEXT: store target("dx.CBuffer", %__cblayout_CBVectors) %CBVectors.cb_h, ptr @CBVectors.cb, align 4 // CHECK: define internal void @_init_buffer_CBArrays.cb() // CHECK-NEXT: entry: -// CHECK-NEXT: %CBArrays.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CBArrays, 708, 0, 48, 112, 176, 224, 608, 624, 656)) -// CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBArrayss_708_0_48_112_176_224_608_624_656tt(i32 0, i32 2, i32 1, i32 0, ptr @CBArrays.str) -// CHECK-NEXT: store target("dx.CBuffer", target("dx.Layout", %__cblayout_CBArrays, 708, 0, 48, 112, 176, 224, 608, 624, 656)) %CBArrays.cb_h, ptr @CBArrays.cb, align 4 +// CHECK-NEXT: %CBArrays.cb_h = call target("dx.CBuffer", %__cblayout_CBArrays) +// CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.CBuffer_s___cblayout_CBArraysst(i32 0, i32 2, i32 1, i32 0, ptr @CBArrays.str) +// CHECK-NEXT: store target("dx.CBuffer", %__cblayout_CBArrays) %CBArrays.cb_h, ptr @CBArrays.cb, align 4 // CHECK: define internal void @_init_buffer_CBTypedefArray.cb() // CHECK-NEXT: entry: -// CHECK-NEXT: %CBTypedefArray.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CBTypedefArray, 128, 0, 64)) -// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBTypedefArrays_128_0_64tt(i32 1, i32 2, i32 1, i32 0, ptr @CBTypedefArray.str) -// CHECK-NEXT: store target("dx.CBuffer", target("dx.Layout", %__cblayout_CBTypedefArray, 128, 0, 64)) %CBTypedefArray.cb_h, ptr @CBTypedefArray.cb, align 4 +// CHECK-NEXT: %CBTypedefArray.cb_h = call target("dx.CBuffer", %__cblayout_CBTypedefArray) +// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_CBTypedefArrayst(i32 1, i32 2, i32 1, i32 0, ptr @CBTypedefArray.str) +// CHECK-NEXT: store target("dx.CBuffer", %__cblayout_CBTypedefArray) %CBTypedefArray.cb_h, ptr @CBTypedefArray.cb, align 4 // CHECK: define internal void @_init_buffer_CBStructs.cb() // CHECK-NEXT: entry: -// CHECK-NEXT: %CBStructs.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CBStructs, 246, 0, 16, 32, 64, 144, 238, 240)) -// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBStructss_246_0_16_32_64_144_238_240tt(i32 2, i32 0, i32 1, i32 0, ptr @CBStructs.str) -// CHECK-NEXT: store target("dx.CBuffer", target("dx.Layout", %__cblayout_CBStructs, 246, 0, 16, 32, 64, 144, 238, 240)) %CBStructs.cb_h, ptr @CBStructs.cb, align 4 +// CHECK-NEXT: %CBStructs.cb_h = call target("dx.CBuffer", %__cblayout_CBStructs) +// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_CBStructsst(i32 2, i32 0, i32 1, i32 0, ptr @CBStructs.str) +// CHECK-NEXT: store target("dx.CBuffer", %__cblayout_CBStructs) %CBStructs.cb_h, ptr @CBStructs.cb, align 4 // CHECK: define internal void @_init_buffer_CBClasses.cb() // CHECK-NEXT: entry: -// CHECK-NEXT: %CBClasses.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CBClasses, 260, 0, 16, 32, 112)) -// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBClassess_260_0_16_32_112tt(i32 3, i32 0, i32 1, i32 0, ptr @CBClasses.str) -// CHECK-NEXT: store target("dx.CBuffer", target("dx.Layout", %__cblayout_CBClasses, 260, 0, 16, 32, 112)) %CBClasses.cb_h, ptr @CBClasses.cb, align 4 +// CHECK-NEXT: %CBClasses.cb_h = call target("dx.CBuffer", %__cblayout_CBClasses) +// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_CBClassesst(i32 3, i32 0, i32 1, i32 0, ptr @CBClasses.str) +// CHECK-NEXT: store target("dx.CBuffer", %__cblayout_CBClasses) %CBClasses.cb_h, ptr @CBClasses.cb, align 4 // CHECK: define internal void @_init_buffer_CBMix.cb() // CHECK-NEXT: entry: -// CHECK-NEXT: %CBMix.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CBMix, 170, 0, 24, 32, 120, 128, 136, 144, 152, 160, 168)) -// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBMixs_170_0_24_32_120_128_136_144_152_160_168tt(i32 4, i32 0, i32 1, i32 0, ptr @CBMix.str) -// CHECK-NEXT: store target("dx.CBuffer", target("dx.Layout", %__cblayout_CBMix, 170, 0, 24, 32, 120, 128, 136, 144, 152, 160, 168)) %CBMix.cb_h, ptr @CBMix.cb, align 4 +// CHECK-NEXT: %CBMix.cb_h = call target("dx.CBuffer", %__cblayout_CBMix) +// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_CBMixst(i32 4, i32 0, i32 1, i32 0, ptr @CBMix.str) +// CHECK-NEXT: store target("dx.CBuffer", %__cblayout_CBMix) %CBMix.cb_h, ptr @CBMix.cb, align 4 // CHECK: define internal void @_init_buffer_CB_A.cb() // CHECK-NEXT: entry: -// CHECK-NEXT: %CB_A.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB_A, 188, 0, 32, 76, 80, 120, 128, 144, 160, 182)) -// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_tdx.Layout_s___cblayout_CB_As_188_0_32_76_80_120_128_144_160_182tt(i32 5, i32 0, i32 1, i32 0, ptr @CB_A.str) -// CHECK-NEXT: store target("dx.CBuffer", target("dx.Layout", %__cblayout_CB_A, 188, 0, 32, 76, 80, 120, 128, 144, 160, 182)) %CB_A.cb_h, ptr @CB_A.cb, align 4 +// CHECK-NEXT: %CB_A.cb_h = call target("dx.CBuffer", %__cblayout_CB_A) +// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_CB_Ast(i32 5, i32 0, i32 1, i32 0, ptr @CB_A.str) +// CHECK-NEXT: store target("dx.CBuffer", %__cblayout_CB_A) %CB_A.cb_h, ptr @CB_A.cb, align 4 // CHECK: define internal void @_init_buffer_CB_B.cb() // CHECK-NEXT: entry: -// CHECK-NEXT: %CB_B.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB_B, 94, 0, 88)) -// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_tdx.Layout_s___cblayout_CB_Bs_94_0_88tt(i32 6, i32 0, i32 1, i32 0, ptr @CB_B.str) -// CHECK-NEXT: store target("dx.CBuffer", target("dx.Layout", %__cblayout_CB_B, 94, 0, 88)) %CB_B.cb_h, ptr @CB_B.cb, align 4 +// CHECK-NEXT: %CB_B.cb_h = call target("dx.CBuffer", %__cblayout_CB_B) +// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_CB_Bst(i32 6, i32 0, i32 1, i32 0, ptr @CB_B.str) +// CHECK-NEXT: store target("dx.CBuffer", %__cblayout_CB_B) %CB_B.cb_h, ptr @CB_B.cb, align 4 // CHECK: define internal void @_init_buffer_CB_C.cb() // CHECK-NEXT: entry: -// CHECK-NEXT: %CB_C.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB_C, 400, 0, 16, 112, 128, 392)) -// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_tdx.Layout_s___cblayout_CB_Cs_400_0_16_112_128_392tt(i32 7, i32 0, i32 1, i32 0, ptr @CB_C.str) -// CHECK-NEXT: store target("dx.CBuffer", target("dx.Layout", %__cblayout_CB_C, 400, 0, 16, 112, 128, 392)) %CB_C.cb_h, ptr @CB_C.cb, align 4 +// CHECK-NEXT: %CB_C.cb_h = call target("dx.CBuffer", %__cblayout_CB_C) +// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_CB_Cst(i32 7, i32 0, i32 1, i32 0, ptr @CB_C.str) +// CHECK-NEXT: store target("dx.CBuffer", %__cblayout_CB_C) %CB_C.cb_h, ptr @CB_C.cb, align 4 RWBuffer<float> Buf; diff --git a/clang/test/CodeGenHLSL/resources/cbuffer_and_namespaces.hlsl b/clang/test/CodeGenHLSL/resources/cbuffer_and_namespaces.hlsl index b7bdce3..1fe0a68 100644 --- a/clang/test/CodeGenHLSL/resources/cbuffer_and_namespaces.hlsl +++ b/clang/test/CodeGenHLSL/resources/cbuffer_and_namespaces.hlsl @@ -4,18 +4,18 @@ // CHECK: %"n0::n1::__cblayout_A" = type <{ float }> // CHECK: %"n0::__cblayout_B" = type <{ float }> -// CHECK: %"n0::n2::__cblayout_C" = type <{ float, target("dx.Layout", %"n0::Foo", 4, 0) }> +// CHECK: %"n0::n2::__cblayout_C" = type <{ float, target("dx.Padding", 12), %"n0::Foo" }> // CHECK: %"n0::Foo" = type <{ float }> -// CHECK: @A.cb = global target("dx.CBuffer", target("dx.Layout", %"n0::n1::__cblayout_A", 4, 0)) +// CHECK: @A.cb = global target("dx.CBuffer", %"n0::n1::__cblayout_A") // CHECK: @_ZN2n02n11aE = external hidden addrspace(2) global float, align 4 -// CHECK: @B.cb = global target("dx.CBuffer", target("dx.Layout", %"n0::__cblayout_B", 4, 0)) +// CHECK: @B.cb = global target("dx.CBuffer", %"n0::__cblayout_B") // CHECK: @_ZN2n01aE = external hidden addrspace(2) global float, align 4 -// CHECK: @C.cb = global target("dx.CBuffer", target("dx.Layout", %"n0::n2::__cblayout_C", 20, 0, 16)) +// CHECK: @C.cb = global target("dx.CBuffer", %"n0::n2::__cblayout_C") // CHECK: @_ZN2n02n21aE = external hidden addrspace(2) global float, align 4 -// CHECK: external hidden addrspace(2) global target("dx.Layout", %"n0::Foo", 4, 0), align 1 +// CHECK: external hidden addrspace(2) global %"n0::Foo", align 1 namespace n0 { struct Foo { diff --git a/clang/test/CodeGenHLSL/resources/cbuffer_geps.hlsl b/clang/test/CodeGenHLSL/resources/cbuffer_geps.hlsl new file mode 100644 index 0000000..7a0b458 --- /dev/null +++ b/clang/test/CodeGenHLSL/resources/cbuffer_geps.hlsl @@ -0,0 +1,117 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-compute -fnative-half-type -fnative-int16-type -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s + +// Capture the anonymous struct types for check lines below. +// CHECK: [[ANON_1:%.*]] = type <{ float, target("dx.Padding", 12), <4 x i32> }> +// CHECK: [[ANON_2:%.*]] = type <{ <2 x i32>, target("dx.Padding", 8), <{ [3 x <{ %ArrayAndScalar, target("dx.Padding", 12) }>], %ArrayAndScalar }> + +template <typename T> void use(T); + +cbuffer CBArrays : register(b2) { + float c1[30]; + double3 c2[20]; + float16_t c3[10][20]; + uint64_t c4[30]; + int4 c5[20][30][40]; + uint16_t c6[10]; + int64_t c7[20]; + bool c8[40]; +} + +// CHECK-LABEL: define hidden void @_Z8cbarraysv() +void cbarrays() { + // CHECK: load float, ptr addrspace(2) @c1, align 16 + use(c1[0]); + // CHECK: load float, ptr addrspace(2) getelementptr (<{ float, target("dx.Padding", 12) }>, ptr addrspace(2) @c1, i32 7, i32 0), align 16 + use(c1[7]); + // CHECK: load float, ptr addrspace(2) getelementptr (<{ float, target("dx.Padding", 12) }>, ptr addrspace(2) @c1, i32 29, i32 0), align 16 + use(c1[29]); + + // CHECK: load <3 x double>, ptr addrspace(2) getelementptr (<{ <3 x double>, target("dx.Padding", 8) }>, ptr addrspace(2) @c2, i32 8, i32 0), align 32 + use(c2[8]); + // CHECK: load half, ptr addrspace(2) getelementptr (<{ half, target("dx.Padding", 14) }>, ptr addrspace(2) getelementptr (<{ <{ [19 x <{ half, target("dx.Padding", 14) }>], half }>, target("dx.Padding", 14) }>, ptr addrspace(2) @c3, i32 9, i32 0), i32 5, i32 0), align 16 + use(c3[9][5]); + // CHECK: load i64, ptr addrspace(2) getelementptr (<{ i64, target("dx.Padding", 8) }>, ptr addrspace(2) @c4, i32 6, i32 0), align 16 + use(c4[6]); + // CHECK: load <4 x i32>, ptr addrspace(2) getelementptr inbounds ([40 x <4 x i32>], ptr addrspace(2) getelementptr inbounds ([30 x [40 x <4 x i32>]], ptr addrspace(2) getelementptr inbounds ([20 x [30 x [40 x <4 x i32>]]], ptr addrspace(2) @c5, i32 0, i32 1), i32 0, i32 12), i32 0, i32 15), align 16 + use(c5[1][12][15]); + // CHECK: load i16, ptr addrspace(2) getelementptr (<{ i16, target("dx.Padding", 14) }>, ptr addrspace(2) @c6, i32 4, i32 0), align 16 + use(c6[4]); + // CHECK: load i64, ptr addrspace(2) getelementptr (<{ i64, target("dx.Padding", 8) }>, ptr addrspace(2) @c7, i32 17, i32 0), align 16 + use(c7[17]); + // CHECK: load i32, ptr addrspace(2) getelementptr (<{ i32, target("dx.Padding", 12) }>, ptr addrspace(2) @c8, i32 30, i32 0), align 16 + use(c8[30]); +} + +struct A { + float2 a1; +}; + +struct B : A { + uint16_t3 b1; +}; + +struct C { + int c1; + A c2; +}; + +struct D { + B d1[4][6]; +}; + +cbuffer CBStructs { + A s1; + B s2; + C s3; + A s4[5]; + D s5; +}; + +// CHECK-LABEL: define hidden void @_Z9cbstructsv() +void cbstructs() { + // CHECK: load <2 x float>, ptr addrspace(2) @s1, align 8 + use(s1.a1); + // CHECK: load <3 x i16>, ptr addrspace(2) getelementptr inbounds nuw (%B, ptr addrspace(2) @s2, i32 0, i32 1), align 2 + use(s2.b1); + // CHECK: load <2 x float>, ptr addrspace(2) getelementptr inbounds nuw (%C, ptr addrspace(2) @s3, i32 0, i32 1), align 8 + use(s3.c2.a1); + // CHECK: load <2 x float>, ptr addrspace(2) getelementptr (<{ %A, target("dx.Padding", 8) }>, ptr addrspace(2) @s4, i32 2, i32 0), align 8 + use(s4[2].a1); + // CHECK: load <3 x i16>, ptr addrspace(2) getelementptr inbounds nuw (%B, ptr addrspace(2) getelementptr (<{ %B, target("dx.Padding", 2) }>, ptr addrspace(2) getelementptr (<{ <{ [5 x <{ %B, target("dx.Padding", 2) }>], %B }>, target("dx.Padding", 2) }>, ptr addrspace(2) @s5, i32 3, i32 0), i32 5, i32 0), i32 0, i32 1), align 2 + use(s5.d1[3][5].b1); +} + +struct Scalars { + float a, b; +}; + +struct ArrayAndScalar { + uint4 x[5]; + float y; +}; + +cbuffer CBMix { + Scalars m1[3]; + float m2; + ArrayAndScalar m3; + float2 m4[5][4]; + struct { float c; uint4 d; } m5; + struct { int2 i; ArrayAndScalar j[4]; } m6; + vector<double, 1> m7; +}; + +// CHECK-LABEL: define hidden void @_Z5cbmixv() +void cbmix() { + // CHECK: load float, ptr addrspace(2) getelementptr inbounds nuw (%Scalars, ptr addrspace(2) getelementptr (<{ %Scalars, target("dx.Padding", 8) }>, ptr addrspace(2) @m1, i32 2, i32 0), i32 0, i32 1), align 4 + use(m1[2].b); + // CHECK: load float, ptr addrspace(2) getelementptr inbounds nuw (%ArrayAndScalar, ptr addrspace(2) @m3, i32 0, i32 1), align 4 + use(m3.y); + // CHECK: load <2 x float>, ptr addrspace(2) getelementptr (<{ <2 x float>, target("dx.Padding", 8) }>, ptr addrspace(2) getelementptr (<{ <{ [3 x <{ <2 x float>, target("dx.Padding", 8) }>], <2 x float> }>, target("dx.Padding", 8) }>, ptr addrspace(2) @m4, i32 2, i32 0), i32 3, i32 0), align 16 + use(m4[2][3]); + // CHECK: load <4 x i32>, ptr addrspace(2) getelementptr inbounds nuw ([[ANON_1]], ptr addrspace(2) @m5, i32 0, i32 1), align 16 + use(m5.d); + // CHECK: load <4 x i32>, ptr addrspace(2) getelementptr inbounds ([5 x <4 x i32>], ptr addrspace(2) getelementptr (<{ %ArrayAndScalar, target("dx.Padding", 12) }>, ptr addrspace(2) getelementptr inbounds nuw ([[ANON_2]], ptr addrspace(2) @m6, i32 0, i32 1), i32 2, i32 0), i32 0, i32 2), align 16 + use(m6.j[2].x[2]); + // CHECK: load <1 x double>, ptr addrspace(2) @m7, align 8 + use(m7); +} diff --git a/clang/test/CodeGenHLSL/resources/cbuffer_with_packoffset.hlsl b/clang/test/CodeGenHLSL/resources/cbuffer_with_packoffset.hlsl index 7bedd63..68e263b 100644 --- a/clang/test/CodeGenHLSL/resources/cbuffer_with_packoffset.hlsl +++ b/clang/test/CodeGenHLSL/resources/cbuffer_with_packoffset.hlsl @@ -2,13 +2,24 @@ // RUN: dxil-pc-shadermodel6.3-compute %s \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s -// CHECK: %__cblayout_CB = type <{ float, double, <2 x i32> }> -// CHECK: %__cblayout_CB_1 = type <{ float, <2 x float> }> - -// CHECK: @CB.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 176, 16, 168, 88)) -// CHECK: @a = external hidden addrspace(2) global float, align 4 -// CHECK: @b = external hidden addrspace(2) global double, align 8 -// CHECK: @c = external hidden addrspace(2) global <2 x i32>, align 8 +// CHECK: %__cblayout_CB = type <{ +// CHECK-SAME: target("dx.Padding", 16), +// CHECK-SAME: float, +// CHECK-SAME: target("dx.Padding", 68), +// CHECK-SAME: <2 x i32>, +// CHECK-SAME target("dx.Padding", 72), +// CHECK-SAME: double +// CHECK-SAME: }> +// CHECK: %__cblayout_CB_1 = type <{ +// CHECK-SAME: target("dx.Padding", 80), +// CHECK-SAME: <2 x float>, +// CHECK-SAME: float +// CHECK-SAME: }> + +// CHECK-DAG: @CB.cb = global target("dx.CBuffer", %__cblayout_CB) +// CHECK-DAG: @a = external hidden addrspace(2) global float, align 4 +// CHECK-DAG: @b = external hidden addrspace(2) global double, align 8 +// CHECK-DAG: @c = external hidden addrspace(2) global <2 x i32>, align 8 // CHECK: @CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1 cbuffer CB : register(b1, space3) { @@ -17,9 +28,9 @@ cbuffer CB : register(b1, space3) { int2 c : packoffset(c5.z); } -// CHECK: @CB.cb.1 = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CB_1, 92, 88, 80)) -// CHECK: @x = external hidden addrspace(2) global float, align 4 -// CHECK: @y = external hidden addrspace(2) global <2 x float>, align 8 +// CHECK-DAG: @CB.cb.1 = global target("dx.CBuffer", %__cblayout_CB_1) +// CHECK-DAG: @x = external hidden addrspace(2) global float, align 4 +// CHECK-DAG: @y = external hidden addrspace(2) global <2 x float>, align 8 // Missing packoffset annotation will produce a warning. // Element x will be placed after the element y that has an explicit packoffset. @@ -30,8 +41,7 @@ cbuffer CB : register(b0) { // CHECK: define internal void @_init_buffer_CB.cb() // CHECK-NEXT: entry: -// CHECK-NEXT: %CB.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 176, 16, 168, 88)) -// CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_176_16_168_88tt(i32 3, i32 1, i32 1, i32 0, ptr @CB.str) +// CHECK-NEXT: %CB.cb_h = call target("dx.CBuffer", %__cblayout_CB) @llvm.dx.resource.handlefrombinding.tdx.CBuffer_s___cblayout_CBst(i32 3, i32 1, i32 1, i32 0, ptr @CB.str) float foo() { // CHECK: load float, ptr addrspace(2) @a, align 4 @@ -48,5 +58,5 @@ void main() { } // CHECK: !hlsl.cbs = !{![[CB1:[0-9]+]], ![[CB2:[0-9]+]]} -// CHECK: ![[CB1]] = !{ptr @CB.cb, ptr addrspace(2) @a, ptr addrspace(2) @b, ptr addrspace(2) @c} -// CHECK: ![[CB2]] = !{ptr @CB.cb.1, ptr addrspace(2) @x, ptr addrspace(2) @y} +// CHECK: ![[CB1]] = !{ptr @CB.cb, ptr addrspace(2) @a, ptr addrspace(2) @c, ptr addrspace(2) @b} +// CHECK: ![[CB2]] = !{ptr @CB.cb.1, ptr addrspace(2) @y, ptr addrspace(2) @x} diff --git a/clang/test/CodeGenHLSL/resources/cbuffer_with_static_global_and_function.hlsl b/clang/test/CodeGenHLSL/resources/cbuffer_with_static_global_and_function.hlsl index fa3405d..b8c7bab 100644 --- a/clang/test/CodeGenHLSL/resources/cbuffer_with_static_global_and_function.hlsl +++ b/clang/test/CodeGenHLSL/resources/cbuffer_with_static_global_and_function.hlsl @@ -2,7 +2,7 @@ // CHECK: %__cblayout_A = type <{ float }> -// CHECK: @A.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_A, 4, 0)) +// CHECK: @A.cb = global target("dx.CBuffer", %__cblayout_A) // CHECK: @a = external hidden addrspace(2) global float, align 4 // CHECK-DAG: @_ZL1b = internal global float 3.000000e+00, align 4 // CHECK-NOT: @B.cb diff --git a/clang/test/CodeGenHLSL/resources/default_cbuffer.hlsl b/clang/test/CodeGenHLSL/resources/default_cbuffer.hlsl index ad4d92f..5333dad 100644 --- a/clang/test/CodeGenHLSL/resources/default_cbuffer.hlsl +++ b/clang/test/CodeGenHLSL/resources/default_cbuffer.hlsl @@ -1,19 +1,18 @@ // RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-compute -fnative-half-type -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,DXIL // RUN: %clang_cc1 -finclude-default-header -triple spirv-pc-vulkan1.3-compute -fnative-half-type -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,SPIRV -// DXIL: %"__cblayout_$Globals" = type <{ float, float, target("dx.Layout", %__cblayout_S, 4, 0) }> -// SPIRV: %"__cblayout_$Globals" = type <{ float, float, target("spirv.Layout", %__cblayout_S, 4, 0) }> +// CHECK: %"__cblayout_$Globals" = type <{ float, float, target("{{.*}}.Padding", 8), %__cblayout_S }> // CHECK: %__cblayout_S = type <{ float }> -// DXIL-DAG: @"$Globals.cb" = global target("dx.CBuffer", target("dx.Layout", %"__cblayout_$Globals", 20, 0, 4, 16)) +// DXIL-DAG: @"$Globals.cb" = global target("dx.CBuffer", %"__cblayout_$Globals") // DXIL-DAG: @a = external hidden addrspace(2) global float // DXIL-DAG: @g = external hidden addrspace(2) global float -// DXIL-DAG: @h = external hidden addrspace(2) global target("dx.Layout", %__cblayout_S, 4, 0), align 4 +// DXIL-DAG: @h = external hidden addrspace(2) global %__cblayout_S, align 4 -// SPIRV-DAG: @"$Globals.cb" = global target("spirv.VulkanBuffer", target("spirv.Layout", %"__cblayout_$Globals", 20, 0, 4, 16), 2, 0) +// SPIRV-DAG: @"$Globals.cb" = global target("spirv.VulkanBuffer", %"__cblayout_$Globals", 2, 0) // SPIRV-DAG: @a = external hidden addrspace(12) global float // SPIRV-DAG: @g = external hidden addrspace(12) global float -// SPIRV-DAG: @h = external hidden addrspace(12) global target("spirv.Layout", %__cblayout_S, 4, 0), align 8 +// SPIRV-DAG: @h = external hidden addrspace(12) global %__cblayout_S, align 8 struct EmptyStruct { }; diff --git a/clang/test/CodeGenHLSL/resources/default_cbuffer_with_layout.hlsl b/clang/test/CodeGenHLSL/resources/default_cbuffer_with_layout.hlsl index 1b2cb0e..7be1f90 100644 --- a/clang/test/CodeGenHLSL/resources/default_cbuffer_with_layout.hlsl +++ b/clang/test/CodeGenHLSL/resources/default_cbuffer_with_layout.hlsl @@ -1,17 +1,26 @@ // RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-compute -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s -// CHECK: %"__cblayout_$Globals" = type <{ i32, float, [4 x double], <4 x i32>, <4 x float>, -// CHECK-SAME: target("dx.Layout", %S, 8, 0) }> +// CHECK: %"__cblayout_$Globals" = type <{ +// CHECK-SAME: float, +// CHECK-SAME: target("dx.Padding", 12), +// CHECK-SAME: <{ [3 x <{ double, target("dx.Padding", 8) }>], double }>, +// CHECK-SAME: target("dx.Padding", 8), +// CHECK-SAME: <4 x i32>, +// CHECK-SAME: %S +// CHECK-SAME: i32, +// CHECK-SAME: target("dx.Padding", 4), +// CHECK-SAME: <4 x float> +// CHECK-SAME: }> + // CHECK: %S = type <{ <2 x float> }> +// CHECK-DAG: @"$Globals.cb" = global target("dx.CBuffer", %"__cblayout_$Globals") +// CHECK-DAG: @a = external hidden addrspace(2) global i32, align 4 // CHECK-DAG: @b = external hidden addrspace(2) global float, align 4 +// CHECK-DAG: @c = external hidden addrspace(2) global <{ [3 x <{ double, target("dx.Padding", 8) }>], double }>, align 8 // CHECK-DAG: @d = external hidden addrspace(2) global <4 x i32>, align 16 -// CHECK-DAG: @"$Globals.cb" = global target("dx.CBuffer", -// CHECK-DAG-SAME: target("dx.Layout", %"__cblayout_$Globals", 144, 120, 16, 32, 64, 128, 112)) -// CHECK-DAG: @a = external hidden addrspace(2) global i32, align 4 -// CHECK-DAG: @c = external hidden addrspace(2) global [4 x double], align 8 // CHECK-DAG: @e = external hidden addrspace(2) global <4 x float>, align 16 -// CHECK-DAG: @s = external hidden addrspace(2) global target("dx.Layout", %S, 8, 0), align 1 +// CHECK-DAG: @s = external hidden addrspace(2) global %S, align 1 struct S { float2 v; @@ -19,8 +28,8 @@ struct S { int a; float b : register(c1); +int4 d : register(c6); double c[4] : register(c2); -int4 d : register(c4); float4 e; S s : register(c7); @@ -32,5 +41,4 @@ void main() { } // CHECK: !hlsl.cbs = !{![[CB:.*]]} -// CHECK: ![[CB]] = !{ptr @"$Globals.cb", ptr addrspace(2) @a, ptr addrspace(2) @b, ptr addrspace(2) @c, -// CHECK-SAME: ptr addrspace(2) @d, ptr addrspace(2) @e, ptr addrspace(2) @s} +// CHECK: ![[CB]] = !{ptr @"$Globals.cb", ptr addrspace(2) @b, ptr addrspace(2) @c, ptr addrspace(2) @d, ptr addrspace(2) @s, ptr addrspace(2) @a, ptr addrspace(2) @e} diff --git a/clang/test/CodeGenHLSL/semantics/DispatchThreadID-noindex.hlsl b/clang/test/CodeGenHLSL/semantics/DispatchThreadID-noindex.hlsl index 9ed5457..b41bb0b 100644 --- a/clang/test/CodeGenHLSL/semantics/DispatchThreadID-noindex.hlsl +++ b/clang/test/CodeGenHLSL/semantics/DispatchThreadID-noindex.hlsl @@ -4,5 +4,5 @@ [shader("compute")] [numthreads(8,8,1)] void foo(uint Idx : SV_DispatchThreadID1) { - // expected-error@-1 {{semantic SV_DispatchThreadID does not allow indexing}} + // expected-error@-1 {{semantic 'SV_DispatchThreadID' does not allow indexing}} } diff --git a/clang/test/CodeGenHLSL/semantics/DispatchThreadID.hlsl b/clang/test/CodeGenHLSL/semantics/DispatchThreadID.hlsl index 7aeb877..b0abaed 100644 --- a/clang/test/CodeGenHLSL/semantics/DispatchThreadID.hlsl +++ b/clang/test/CodeGenHLSL/semantics/DispatchThreadID.hlsl @@ -24,4 +24,3 @@ void foo(uint Idx : SV_DispatchThreadID) {} [shader("compute")] [numthreads(8,8,1)] void bar(uint2 Idx : SV_DispatchThreadID) {} - diff --git a/clang/test/CodeGenHLSL/semantics/SV_GroupID-noindex.hlsl b/clang/test/CodeGenHLSL/semantics/SV_GroupID-noindex.hlsl index 8fa0b07..795e880 100644 --- a/clang/test/CodeGenHLSL/semantics/SV_GroupID-noindex.hlsl +++ b/clang/test/CodeGenHLSL/semantics/SV_GroupID-noindex.hlsl @@ -4,6 +4,11 @@ [shader("compute")] [numthreads(8,8,1)] void foo(uint Idx : SV_GroupID1) { - // expected-error@-1 {{semantic SV_GroupID does not allow indexing}} + // expected-error@-1 {{semantic 'SV_GroupID' does not allow indexing}} } +[shader("compute")] +[numthreads(8,8,1)] +void bar(uint Idx : SV_GROUPID1) { + // expected-error@-1 {{semantic 'SV_GROUPID' does not allow indexing}} +} diff --git a/clang/test/CodeGenHLSL/semantics/SV_GroupThreadID-noindex.hlsl b/clang/test/CodeGenHLSL/semantics/SV_GroupThreadID-noindex.hlsl index da72e85..1fd5ae4 100644 --- a/clang/test/CodeGenHLSL/semantics/SV_GroupThreadID-noindex.hlsl +++ b/clang/test/CodeGenHLSL/semantics/SV_GroupThreadID-noindex.hlsl @@ -4,5 +4,5 @@ [shader("compute")] [numthreads(8,8,1)] void foo(uint Idx : SV_GroupThreadID1) { - // expected-error@-1 {{semantic SV_GroupThreadID does not allow indexing}} + // expected-error@-1 {{semantic 'SV_GroupThreadID' does not allow indexing}} } diff --git a/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl b/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl index 1bba87e..b7d2283 100644 --- a/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl +++ b/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl @@ -1,10 +1,21 @@ -// RUN: %clang_cc1 -triple spirv-unknown-vulkan1.3-pixel -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple spirv-pc-vulkan1.3-pixel -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=CHECK-SPIRV +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-pixel -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=CHECK-DXIL -// CHECK: @SV_Position = external hidden thread_local addrspace(7) externally_initialized constant <4 x float>, !spirv.Decorations !0 +// CHECK-SPIRV: @SV_Position = external hidden thread_local addrspace(7) externally_initialized constant <4 x float>, !spirv.Decorations ![[#MD_0:]] // CHECK: define void @main() {{.*}} { -float4 main(float4 p : SV_Position) { - // CHECK: %[[#P:]] = load <4 x float>, ptr addrspace(7) @SV_Position, align 16 - // CHECK: %[[#R:]] = call spir_func <4 x float> @_Z4mainDv4_f(<4 x float> %[[#P]]) +float4 main(float4 p : SV_Position) : A { + // CHECK-SPIRV: %[[#P:]] = load <4 x float>, ptr addrspace(7) @SV_Position, align 16 + // CHECK-SPIRV: %[[#R:]] = call spir_func <4 x float> @_Z4mainDv4_f(<4 x float> %[[#P]]) + // CHECK-SPIRV: store <4 x float> %[[#R]], ptr addrspace(8) @A0, align 16 + + // CHECK-DXIL: %SV_Position0 = call <4 x float> @llvm.dx.load.input.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison) + // CHECK-DXIL: %[[#TMP:]] = call <4 x float> @_Z4mainDv4_f(<4 x float> %SV_Position0) + // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison, <4 x float> %[[#TMP]]) return p; } + +// CHECK-SPIRV-DAG: ![[#MD_0]] = !{![[#MD_1:]]} +// CHECK-SPIRV-DAG: ![[#MD_1]] = !{i32 11, i32 15} +// | `-> BuiltIn Position +// `-> SPIR-V decoration 'FragCoord' diff --git a/clang/test/CodeGenHLSL/semantics/SV_Position.vs.hlsl b/clang/test/CodeGenHLSL/semantics/SV_Position.vs.hlsl new file mode 100644 index 0000000..0156c0b --- /dev/null +++ b/clang/test/CodeGenHLSL/semantics/SV_Position.vs.hlsl @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -triple dxil-unknown-shadermodel6.8-vertex -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck --check-prefix=CHECK-DXIL %s +// RUN: %clang_cc1 -triple spirv-unknown-vulkan1.3-vertex -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck --check-prefix=CHECK-SPIRV %s + +// CHECK-SPIRV: @SV_Position0 = external hidden thread_local addrspace(7) externally_initialized constant <4 x float>, !spirv.Decorations ![[#MD_0:]] +// CHECK-SPIRV: @SV_Position = external hidden thread_local addrspace(8) global <4 x float>, !spirv.Decorations ![[#MD_2:]] + +// CHECK: define void @main() {{.*}} { +float4 main(float4 p : SV_Position) : SV_Position { + // CHECK-SPIRV: %[[#P:]] = load <4 x float>, ptr addrspace(7) @SV_Position0, align 16 + // CHECK-SPIRV: %[[#R:]] = call spir_func <4 x float> @_Z4mainDv4_f(<4 x float> %[[#P]]) + // CHECK-SPIRV: store <4 x float> %[[#R]], ptr addrspace(8) @SV_Position, align 16 + + // CHECK-DXIL: %SV_Position0 = call <4 x float> @llvm.dx.load.input.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison) + // CHECK-DXIL: %[[#TMP:]] = call <4 x float> @_Z4mainDv4_f(<4 x float> %SV_Position0) + // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison, <4 x float> %[[#TMP]]) + return p; +} + +// CHECK-SPIRV-DAG: ![[#MD_0]] = !{![[#MD_1:]]} +// CHECK-SPIRV-DAG: ![[#MD_2]] = !{![[#MD_3:]]} +// CHECK-SPIRV-DAG: ![[#MD_1]] = !{i32 30, i32 0} +// | `-> Location 0 +// `-> SPIR-V decoration 'Location' +// CHECK-SPIRV-DAG: ![[#MD_3]] = !{i32 11, i32 0} +// | `-> BuiltIn Position +// `-> SPIR-V decoration 'BuiltIn' diff --git a/clang/test/CodeGenHLSL/semantics/SV_Target.ps.hlsl b/clang/test/CodeGenHLSL/semantics/SV_Target.ps.hlsl new file mode 100644 index 0000000..4dc622a --- /dev/null +++ b/clang/test/CodeGenHLSL/semantics/SV_Target.ps.hlsl @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple spirv-pc-vulkan1.3-pixel -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=CHECK-SPIRV +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-pixel -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=CHECK-DXIL + +// CHECK-SPIRV: @SV_Target0 = external hidden thread_local addrspace(8) global <4 x float>, !spirv.Decorations ![[#MD_2:]] + +// CHECK: define void @main() {{.*}} { +float4 main(float4 p : SV_Position) : SV_Target { + // CHECK-SPIRV: %[[#R:]] = call spir_func <4 x float> @_Z4mainDv4_f(<4 x float> %[[#]]) + // CHECK-SPIRV: store <4 x float> %[[#R]], ptr addrspace(8) @SV_Target0, align 16 + + // CHECK-DXIL: %[[#TMP:]] = call <4 x float> @_Z4mainDv4_f(<4 x float> %SV_Position0) + // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison, <4 x float> %[[#TMP]]) + return p; +} + +// CHECK-SPIRV-DAG: ![[#MD_2]] = !{![[#MD_3:]]} +// CHECK-SPIRV-DAG: ![[#MD_3]] = !{i32 30, i32 0} +// | `-> Location index +// `-> SPIR-V decoration 'Location' diff --git a/clang/test/CodeGenHLSL/semantics/semantic-struct-2-output.hlsl b/clang/test/CodeGenHLSL/semantics/semantic-struct-2-output.hlsl new file mode 100644 index 0000000..2f8dc97 --- /dev/null +++ b/clang/test/CodeGenHLSL/semantics/semantic-struct-2-output.hlsl @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK-DX,CHECK +// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK-VK,CHECK + + +struct Input { + float Idx : SV_Position0; + float Gid : SV_Position1; +}; + +struct Output { + float a : A; + float b : B; +}; + +// Make sure SV_DispatchThreadID translated into dx.thread.id. + +// CHECK-DX: define hidden void @_Z3foo5Input(ptr dead_on_unwind noalias writable sret(%struct.Output) align 1 %agg.result, ptr noundef byval(%struct.Input) align 1 %input) +// CHECK-VK: define hidden spir_func void @_Z3foo5Input(ptr dead_on_unwind noalias writable sret(%struct.Output) align 1 %agg.result, ptr noundef byval(%struct.Input) align 1 %input) + +// CHECK: %Idx = getelementptr inbounds nuw %struct.Input, ptr %input, i32 0, i32 0 +// CHECK: %[[#tmp:]] = load float, ptr %Idx, align 1 +// CHECK: %a = getelementptr inbounds nuw %struct.Output, ptr %agg.result, i32 0, i32 0 +// CHECK: store float %[[#tmp]], ptr %a, align 1 +// CHECK: %Gid = getelementptr inbounds nuw %struct.Input, ptr %input, i32 0, i32 1 +// CHECK: %[[#tmp:]] = load float, ptr %Gid, align 1 +// CHECK: %b = getelementptr inbounds nuw %struct.Output, ptr %agg.result, i32 0, i32 1 +// CHECK: store float %[[#tmp]], ptr %b, align 1 + +Output foo(Input input) { + Output o; + o.a = input.Idx; + o.b = input.Gid; + return o; +} + diff --git a/clang/test/CodeGenHLSL/semantics/semantic.arbitrary.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.arbitrary.hlsl new file mode 100644 index 0000000..96d5b99 --- /dev/null +++ b/clang/test/CodeGenHLSL/semantics/semantic.arbitrary.hlsl @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -triple spirv-unknown-vulkan-vertex -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV -DTARGET=spv +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-vertex -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL -DTARGET=dx + +// CHECK-SPIRV-DAG: @AAA0 = external hidden thread_local addrspace(7) externally_initialized constant float, !spirv.Decorations ![[#METADATA_0:]] +// CHECK-SPIRV-DAG: @B0 = external hidden thread_local addrspace(7) externally_initialized constant i32, !spirv.Decorations ![[#METADATA_2:]] +// CHECK-SPIRV-DAG: @CC0 = external hidden thread_local addrspace(7) externally_initialized constant <2 x float>, !spirv.Decorations ![[#METADATA_4:]] + + +// FIXME: replace `float2 c` with a matrix when available. +void main(float a : AAA, int b : B, float2 c : CC) { + float tmp = a + b + c.x + c.y; +} +// CHECK-SPIRV: define internal spir_func void @_Z4mainfiDv2_f(float noundef nofpclass(nan inf) %a, i32 noundef %b, <2 x float> noundef nofpclass(nan inf) %c) #0 { + +// CHECK: define void @main() + +// CHECK-DXIL: %AAA0 = call float @llvm.dx.load.input.f32(i32 4, i32 0, i32 0, i8 0, i32 poison) +// CHECK-DXIL: %B0 = call i32 @llvm.dx.load.input.i32(i32 4, i32 0, i32 0, i8 0, i32 poison) +// CHECK-DXIL %CC0 = call <2 x float> @llvm.dx.load.input.v2f32(i32 4, i32 0, i32 0, i8 0, i32 poison) +// CHECK-DXIL: call void @_Z4mainfiDv2_f(float %AAA0, i32 %B0, <2 x float> %CC0) + +// CHECK-SPIRV: %[[#AAA0:]] = load float, ptr addrspace(7) @AAA0, align 4 +// CHECK-SPIRV: %[[#B0:]] = load i32, ptr addrspace(7) @B0, align 4 +// CHECK-SPIRV: %[[#CC0:]] = load <2 x float>, ptr addrspace(7) @CC0, align 8 +// CHECK-SPIRV: call spir_func void @_Z4mainfiDv2_f(float %[[#AAA0]], i32 %[[#B0]], <2 x float> %[[#CC0]]) [ "convergencectrl"(token %0) ] + + +// CHECK-SPIRV-DAG: ![[#METADATA_0]] = !{![[#METADATA_1:]]} +// CHECK-SPIRV-DAG: ![[#METADATA_2]] = !{![[#METADATA_3:]]} +// CHECK-SPIRV-DAG: ![[#METADATA_4]] = !{![[#METADATA_5:]]} + +// CHECK-SPIRV-DAG: ![[#METADATA_1]] = !{i32 30, i32 0} +// CHECK-SPIRV-DAG: ![[#METADATA_3]] = !{i32 30, i32 1} +// CHECK-SPIRV-DAG: ![[#METADATA_5]] = !{i32 30, i32 2} +// | `- Location index +// `-> Decoration "Location" diff --git a/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl new file mode 100644 index 0000000..f57ac607 --- /dev/null +++ b/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV -DTARGET=spv +// RUN: %clang_cc1 -triple dxil-px-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL -DTARGET=dx + +struct S0 { + float4 position[2]; + float4 color; +}; + +// CHECK: %struct.S0 = type { [2 x <4 x float>], <4 x float> } + +// CHECK-SPIRV: @A0 = external hidden thread_local addrspace(7) externally_initialized constant [2 x <4 x float>], !spirv.Decorations ![[#MD_0:]] +// CHECK-SPIRV: @A2 = external hidden thread_local addrspace(7) externally_initialized constant <4 x float>, !spirv.Decorations ![[#MD_2:]] + +// CHECK: define void @main0() +// CHECK-DXIL: %A0 = call [2 x <4 x float>] @llvm.dx.load.input.a2v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison) +// CHECK-DXIL: %[[#TMP0:]] = insertvalue %struct.S0 poison, [2 x <4 x float>] %A0, 0 +// CHECK-DXIL: %A2 = call <4 x float> @llvm.dx.load.input.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison) +// CHECK-DXIL: %[[#TMP1:]] = insertvalue %struct.S0 %[[#TMP0]], <4 x float> %A2, 1 + +// CHECK-SPIRV: %[[#A0:]] = load [2 x <4 x float>], ptr addrspace(7) @A0, align 16 +// CHECK-SPIRV: %[[#TMP0:]] = insertvalue %struct.S0 poison, [2 x <4 x float>] %[[#A0]], 0 +// CHECK-SPIRV: %[[#A01:]] = load <4 x float>, ptr addrspace(7) @A2, align 16 +// CHECK-SPIRV: %[[#TMP1:]] = insertvalue %struct.S0 %[[#TMP0]], <4 x float> %[[#A01]], 1 + +// CHECK: %[[#ARG:]] = alloca %struct.S0, align 16 +// CHECK: store %struct.S0 %[[#TMP1]], ptr %[[#ARG]], align 16 +// CHECK-DXIL: call void @{{.*}}main0{{.*}}(ptr %[[#ARG]]) +// CHECK-SPIRV: call spir_func void @{{.*}}main0{{.*}}(ptr %[[#ARG]]) +[shader("pixel")] +void main0(S0 p : A) { + float tmp = p.position[0] + p.position[1] + p.color; +} + +// CHECK-SPIRV: ![[#MD_0]] = !{![[#MD_1:]]} +// CHECK-SPIRV: ![[#MD_1]] = !{i32 30, i32 0} +// CHECK-SPIRV: ![[#MD_2]] = !{![[#MD_3:]]} +// CHECK-SPIRV: ![[#MD_3]] = !{i32 30, i32 2} diff --git a/clang/test/CodeGenHLSL/semantics/semantic.array.output.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.array.output.hlsl new file mode 100644 index 0000000..d75f4e0 --- /dev/null +++ b/clang/test/CodeGenHLSL/semantics/semantic.array.output.hlsl @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV -DTARGET=spv +// RUN: %clang_cc1 -triple dxil-px-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL -DTARGET=dx + +struct S0 { + float4 position[2]; + float4 color; +}; + +// CHECK-SPIRV-DAG: @A0 = external hidden thread_local addrspace(7) externally_initialized constant <4 x float>, !spirv.Decorations ![[#METADATA_0:]] + +[shader("pixel")] +S0 main1(float4 input : A) : B { +// CHECK: %[[#ARG:]] = alloca %struct.S0, align 16 +// CHECK-SPIRV: %[[#INPUT:]] = load <4 x float>, ptr addrspace(7) @A0, align 16 +// CHECK-DXIL: %A0 = call <4 x float> @llvm.dx.load.input.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison) +// CHECK-DXIL: call void @{{.*}}main1{{.*}}(ptr %[[#ARG]], <4 x float> %A0) +// CHECK-SPIRV: call spir_func void @{{.*}}main1{{.*}}(ptr %[[#ARG]], <4 x float> %[[#INPUT]]) + + // CHECK: %[[#ST:]] = load %struct.S0, ptr %[[#ARG]], align 16 + // CHECK: %[[#TMP:]] = extractvalue %struct.S0 %[[#ST]], 0 + // CHECK-SPIRV: store [2 x <4 x float>] %[[#TMP]], ptr addrspace(8) @B0, align 16 + // CHECK-DXIL: call void @llvm.dx.store.output.a2v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison, [2 x <4 x float>] %[[#TMP]]) + // CHECK: %[[#TMP:]] = extractvalue %struct.S0 %[[#ST]], 1 + // CHECK-SPIRV: store <4 x float> %[[#TMP]], ptr addrspace(8) @B2, align 16 + // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison, <4 x float> %[[#TMP]]) + + S0 output; + output.position[0] = input; + output.position[1] = input; + output.color = input; + return output; +} + +// CHECK-SPIRV-DAG: ![[#METADATA_0]] = !{![[#METADATA_1:]]} +// CHECK-SPIRV-DAG: ![[#METADATA_1]] = !{i32 30, i32 0} +// | `- Location index +// `-> Decoration "Location" diff --git a/clang/test/CodeGenHLSL/semantics/semantic.explicit-location-output-struct.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.explicit-location-output-struct.hlsl new file mode 100644 index 0000000..c5d8663 --- /dev/null +++ b/clang/test/CodeGenHLSL/semantics/semantic.explicit-location-output-struct.hlsl @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -triple spirv-pc-vulkan1.3-pixel -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-pixel -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL + +// CHECK-SPIRV: @SV_Position = external hidden thread_local addrspace(7) externally_initialized constant <4 x float>, !spirv.Decorations ![[#MD_0:]] +// CHECK-SPIRV: @SV_Target0 = external hidden thread_local addrspace(8) global <4 x float>, !spirv.Decorations ![[#MD_2:]] + +struct Output { + [[vk::location(2)]] float4 field : SV_Target; +}; + +// CHECK: define void @main() {{.*}} { +Output main(float4 p : SV_Position) { + // CHECK: %[[#OUT:]] = alloca %struct.Output, align 16 + + // CHECK-SPIRV: %[[#IN:]] = load <4 x float>, ptr addrspace(7) @SV_Position, align 16 + // CHECK-SPIRV: call spir_func void @_Z4mainDv4_f(ptr %[[#OUT]], <4 x float> %[[#IN]]) + + // CHECK-DXIL: call void @_Z4mainDv4_f(ptr %[[#OUT]], <4 x float> %SV_Position0) + + // CHECK: %[[#TMP:]] = load %struct.Output, ptr %[[#OUT]], align 16 + // CHECK: %[[#FIELD:]] = extractvalue %struct.Output %[[#TMP]], 0 + + // CHECK-SPIRV: store <4 x float> %[[#FIELD]], ptr addrspace(8) @SV_Target0, align 16 + // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison, <4 x float> %[[#FIELD]]) + Output o; + o.field = p; + return o; +} + +// CHECK-SPIRV-DAG: ![[#MD_0]] = !{![[#MD_1:]]} +// CHECK-SPIRV-DAG: ![[#MD_1]] = !{i32 11, i32 15} +// | `-> BuiltIn 'FragCoord' +// `-> SPIR-V decoration 'BuiltIn' +// CHECK-SPIRV-DAG: ![[#MD_2]] = !{![[#MD_3:]]} +// CHECK-SPIRV-DAG: ![[#MD_3]] = !{i32 30, i32 2} +// | `-> Location index +// `-> SPIR-V decoration 'Location' diff --git a/clang/test/CodeGenHLSL/semantics/semantic.explicit-location.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.explicit-location.hlsl new file mode 100644 index 0000000..41e28bf --- /dev/null +++ b/clang/test/CodeGenHLSL/semantics/semantic.explicit-location.hlsl @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple spirv-pc-vulkan1.3-pixel -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=CHECK-SPIRV +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-pixel -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=CHECK-DXIL + +// CHECK-SPIRV: @SV_Target0 = external hidden thread_local addrspace(8) global <4 x float>, !spirv.Decorations ![[#MD_2:]] + +// CHECK: define void @main() {{.*}} { +[[vk::location(2)]] float4 main(float4 p : SV_Position) : SV_Target { + // CHECK-SPIRV: %[[#R:]] = call spir_func <4 x float> @_Z4mainDv4_f(<4 x float> %[[#]]) + // CHECK-SPIRV: store <4 x float> %[[#R]], ptr addrspace(8) @SV_Target0, align 16 + + // CHECK-DXIL: %[[#TMP:]] = call <4 x float> @_Z4mainDv4_f(<4 x float> %SV_Position0) + // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison, <4 x float> %[[#TMP]]) + return p; +} + +// CHECK-SPIRV-DAG: ![[#MD_2]] = !{![[#MD_3:]]} +// CHECK-SPIRV-DAG: ![[#MD_3]] = !{i32 30, i32 2} +// | `-> Location index +// `-> SPIR-V decoration 'Location' diff --git a/clang/test/CodeGenHLSL/semantics/semantic.explicit-mix-builtin.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.explicit-mix-builtin.hlsl new file mode 100644 index 0000000..bc2ecd9 --- /dev/null +++ b/clang/test/CodeGenHLSL/semantics/semantic.explicit-mix-builtin.hlsl @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -triple spirv-linux-vulkan-pixel -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV + +// The following code is allowed because the `SV_Position` semantic is here +// translated into a SPIR-V builtin. Meaning there is no implicit `Location` +// assignment. + +struct S2 { + float4 a; + float4 b; +}; + +struct S1 { + float4 position : SV_Position; + [[vk::location(3)]] float4 color0 : COLOR0; +}; + +// CHECK-SPIRV: @SV_Position = external hidden thread_local addrspace(7) externally_initialized constant <4 x float>, !spirv.Decorations ![[#MD_0:]] +// CHECK-SPIRV: @COLOR0 = external hidden thread_local addrspace(7) externally_initialized constant <4 x float>, !spirv.Decorations ![[#MD_2:]] +// CHECK-SPIRV: @SV_Target0 = external hidden thread_local addrspace(8) global <4 x float>, !spirv.Decorations ![[#MD_4:]] + +[shader("pixel")] +float4 main(S1 p) : SV_Target { + return p.position + p.color0; +} +// CHECK-SPIRV: %[[#SV_POS:]] = load <4 x float>, ptr addrspace(7) @SV_Position, align 16 +// CHECK: %[[#TMP1:]] = insertvalue %struct.S1 poison, <4 x float> %[[#SV_POS]], 0 +// CHECK-SPIRV: %[[#A0:]] = load <4 x float>, ptr addrspace(7) @COLOR0, align 16 +// CHECK: %[[#TMP2:]] = insertvalue %struct.S1 %[[#TMP1]], <4 x float> %[[#A0]], 1 +// CHECK: %[[#P:]] = alloca %struct.S1, align 16 +// CHECK: store %struct.S1 %[[#TMP2]], ptr %[[#P]], align 16 +// CHECK-SPIRV: %[[#R:]] = call spir_func <4 x float> @_Z4main2S1(ptr %[[#P]]) +// CHECK-SPIRV: store <4 x float> %[[#R]], ptr addrspace(8) @SV_Target0, align 16 + +// CHECK-SPIRV: ![[#MD_0]] = !{![[#MD_1:]]} +// CHECK-SPIRV: ![[#MD_1]] = !{i32 11, i32 15} +// CHECK-SPIRV: ![[#MD_2]] = !{![[#MD_3:]]} +// CHECK-SPIRV: ![[#MD_3]] = !{i32 30, i32 3} +// CHECK-SPIRV: ![[#MD_4]] = !{![[#MD_5:]]} +// CHECK-SPIRV: ![[#MD_5]] = !{i32 30, i32 0} diff --git a/clang/test/CodeGenHLSL/semantics/semantic.explicit-mix-builtin.vs.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.explicit-mix-builtin.vs.hlsl new file mode 100644 index 0000000..43dc30f --- /dev/null +++ b/clang/test/CodeGenHLSL/semantics/semantic.explicit-mix-builtin.vs.hlsl @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -triple spirv-linux-vulkan-vertex -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s + +// This is almost the same as semantic.explicit-mix-builtin.hlsl, except this +// time we build a vertex shader. This means the SV_Position semantic output +// is also a BuiltIn, This means we can mix implicit and explicit location +// assignment. +struct S1 { + float4 position : SV_Position; + [[vk::location(3)]] float4 color : A; +}; + +// CHECK: @SV_Position0 = external hidden thread_local addrspace(7) externally_initialized constant <4 x float>, !spirv.Decorations ![[#MD_0:]] +// CHECK: @SV_Position = external hidden thread_local addrspace(8) global <4 x float>, !spirv.Decorations ![[#MD_2:]] +// CHECK: @A0 = external hidden thread_local addrspace(8) global <4 x float>, !spirv.Decorations ![[#MD_0]] + +[shader("vertex")] +S1 main1(float4 position : SV_Position) { + S1 output; + output.position = position; + output.color = position; + return output; +} + +// CHECK: ![[#MD_0]] = !{![[#MD_1:]]} +// CHECK: ![[#MD_1]] = !{i32 30, i32 0} +// | `-> Location index +// `-> SPIR-V decoration 'Location' +// CHECK: ![[#MD_2]] = !{![[#MD_3:]]} +// CHECK: ![[#MD_3]] = !{i32 11, i32 0} +// | `-> BuiltIn 'Position' +// `-> SPIR-V decoration 'BuiltIn' diff --git a/clang/test/CodeGenHLSL/semantics/semantic.explicit-mix.lib.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.explicit-mix.lib.hlsl new file mode 100644 index 0000000..456c9bf --- /dev/null +++ b/clang/test/CodeGenHLSL/semantics/semantic.explicit-mix.lib.hlsl @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK + +// The followiong file contains both implicit and explicit vk::location, but +// because each entrypoint has only one kind, this is allowed. + +[shader("vertex")] +float4 vs_main(float4 p : SV_Position) : A { + return p; +} + +[shader("pixel")] +float4 ps_main([[vk::location(0)]] float4 p : A) : SV_Target { + return p; +} + +// The following function is not marked as being a shader entrypoint, this +// means the semantics and [[vk::location]] attributes are ignored. +// Otherwise, the partial explicit location assignment would be illegal. +float4 not_an_entry([[vk::location(0)]] float4 a : A, float4 b : B) : C { + return a + b; +} + +// CHECK: @SV_Position0 = external hidden thread_local addrspace(7) externally_initialized constant <4 x float>, !spirv.Decorations ![[#MD_0:]] +// CHECK: @A0 = external hidden thread_local addrspace(8) global <4 x float>, !spirv.Decorations ![[#MD_0:]] +// CHECK: @A0.1 = external hidden thread_local addrspace(7) externally_initialized constant <4 x float>, !spirv.Decorations ![[#MD_0:]] +// CHECK: @SV_Target0 = external hidden thread_local addrspace(8) global <4 x float>, !spirv.Decorations ![[#MD_2:]] + + +// CHECK: define void @vs_main() +// CHECK: %[[#]] = load <4 x float>, ptr addrspace(7) @SV_Position0, align 16 +// CHECK: store <4 x float> %[[#]], ptr addrspace(8) @A0, align 16 + +// CHECK: define void @ps_main() +// CHECK: %[[#]] = load <4 x float>, ptr addrspace(7) @A0.1, align 16 +// CHECK: store <4 x float> %[[#]], ptr addrspace(8) @SV_Target0, align 16 + +// CHECK: ![[#MD_0]] = !{![[#MD_1:]]} +// CHECK: ![[#MD_1]] = !{i32 30, i32 0} +// CHECK: ![[#MD_2]] = !{![[#MD_3:]]} +// CHECK: ![[#MD_3]] = !{i32 30, i32 1} diff --git a/clang/test/CodeGenHLSL/semantics/semantic.struct.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.struct.hlsl new file mode 100644 index 0000000..733cf3a --- /dev/null +++ b/clang/test/CodeGenHLSL/semantics/semantic.struct.hlsl @@ -0,0 +1,77 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL -DTARGET=dx +// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV -DTARGET=spv + +struct S0 { + uint Idx : SV_DispatchThreadID; +}; + +// CHECK: define void @main0() +// CHECK-DXIL: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id(i32 0) +// CHECK-SPIRV: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id.i32(i32 0) +// CHECK: %[[#TMP:]] = insertvalue %struct.S0 poison, i32 %[[#ID:]], 0 +// CHECK: %[[#ARG:]] = alloca %struct.S0, align 8 +// CHECK: store %struct.S0 %[[#TMP]], ptr %[[#ARG]], align 4 +// CHECK-DXIL: call void @{{.*}}main0{{.*}}(ptr %[[#ARG]]) +// CHECK-SPIRV: call spir_func void @{{.*}}main0{{.*}}(ptr %[[#ARG]]) +[shader("compute")] +[numthreads(8,8,1)] +void main0(S0 p) {} + +struct S1 { + uint2 a : SV_DispatchThreadID; + uint2 b : SV_GroupThreadID; +}; + +// CHECK: define void @main1() +// CHECK-DXIL: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id(i32 0) +// CHECK-SPIRV: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id.i32(i32 0) +// CHECK: %[[#AX_:]] = insertelement <2 x i32> poison, i32 %[[#ID]], i64 0 +// CHECK-DXIL: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id(i32 1) +// CHECK-SPIRV: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id.i32(i32 1) +// CHECK: %[[#AXY:]] = insertelement <2 x i32> %[[#AX_]], i32 %[[#ID]], i64 1 +// CHECK: %[[#S1A_:]] = insertvalue %struct.S1 poison, <2 x i32> %[[#AXY]], 0 +// CHECK-DXIL: %[[#ID_X:]] = call i32 @llvm.[[TARGET]].thread.id.in.group(i32 0) +// CHECK-SPIRV: %[[#ID_X:]] = call i32 @llvm.[[TARGET]].thread.id.in.group.i32(i32 0) +// CHECK: %[[#ID_X_:]] = insertelement <2 x i32> poison, i32 %[[#ID_X]], i64 0 +// CHECK-DXIL: %[[#ID_Y:]] = call i32 @llvm.[[TARGET]].thread.id.in.group(i32 1) +// CHECK-SPIRV: %[[#ID_Y:]] = call i32 @llvm.[[TARGET]].thread.id.in.group.i32(i32 1) +// CHECK: %[[#ID_XY:]] = insertelement <2 x i32> %[[#ID_X_]], i32 %[[#ID_Y]], i64 1 +// CHECK: %[[#S1AB:]] = insertvalue %struct.S1 %[[#S1A_]], <2 x i32> %[[#ID_XYZ:]], 1 +// CHECK: %[[#ARG:]] = alloca %struct.S1, align 8 +// CHECK: store %struct.S1 %[[#S1AB]], ptr %[[#ARG]], align 8 +// CHECK-DXIL: call void @{{.*}}main1{{.*}}(ptr %[[#ARG]]) +// CHECK-SPIRV: call spir_func void @{{.*}}main1{{.*}}(ptr %[[#ARG]]) +[shader("compute")] +[numthreads(8,8,1)] +void main1(S1 p) {} + +struct S2C { + uint2 b : SV_GroupThreadID; +}; + +struct S2 { + uint a : SV_DispatchThreadID; + S2C child; +}; + +// CHECK: define void @main2() +// CHECK-DXIL: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id(i32 0) +// CHECK-SPIRV: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id.i32(i32 0) +// CHECK: %[[#S2A_:]] = insertvalue %struct.S2 poison, i32 %[[#ID:]], 0 + +// CHECK-DXIL: %[[#ID_X:]] = call i32 @llvm.[[TARGET]].thread.id.in.group(i32 0) +// CHECK-SPIRV: %[[#ID_X:]] = call i32 @llvm.[[TARGET]].thread.id.in.group.i32(i32 0) +// CHECK: %[[#ID_X_:]] = insertelement <2 x i32> poison, i32 %[[#ID_X]], i64 0 +// CHECK-DXIL: %[[#ID_Y:]] = call i32 @llvm.[[TARGET]].thread.id.in.group(i32 1) +// CHECK-SPIRV: %[[#ID_Y:]] = call i32 @llvm.[[TARGET]].thread.id.in.group.i32(i32 1) +// CHECK: %[[#ID_XY:]] = insertelement <2 x i32> %[[#ID_X_]], i32 %[[#ID_Y]], i64 1 +// CHECK: %[[#S2C:]] = insertvalue %struct.S2C poison, <2 x i32> %[[#ID_XY:]], 0 + +// CHECK: %[[#S2AB:]] = insertvalue %struct.S2 %[[#S2A_]], %struct.S2C %[[#S2V:]], 1 +// CHECK: %[[#ARG:]] = alloca %struct.S2, align 8 +// CHECK: store %struct.S2 %[[#S2AB]], ptr %[[#ARG]], align 1 +// CHECK-DXIL: call void @{{.*}}main2{{.*}}(ptr %[[#ARG]]) +// CHECK-SPIRV: call spir_func void @{{.*}}main2{{.*}}(ptr %[[#ARG]]) +[shader("compute")] +[numthreads(8,8,1)] +void main2(S2 p) {} diff --git a/clang/test/CodeGenHLSL/semantics/semantic.struct.output.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.struct.output.hlsl new file mode 100644 index 0000000..0f2444d --- /dev/null +++ b/clang/test/CodeGenHLSL/semantics/semantic.struct.output.hlsl @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-vertex -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK-DXIL,CHECK +// RUN: %clang_cc1 -triple spirv-linux-vulkan-vertex -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK-SPIRV,CHECK + + +struct Input { + // FIXME: change this once we have a valid system semantic as input for VS. + float Idx : B2; +}; + +struct Output { + float a : A4; + float b : A2; +}; + +// CHECK-SPIRV-DAG: @B2 = external hidden thread_local addrspace(7) externally_initialized constant float, !spirv.Decorations ![[#METADATA_0:]] +// CHECK-SPIRV-DAG: @A4 = external hidden thread_local addrspace(8) global float, !spirv.Decorations ![[#METADATA_0:]] +// CHECK-SPIRV-DAG: @A2 = external hidden thread_local addrspace(8) global float, !spirv.Decorations ![[#METADATA_2:]] + +// CHECK: %Idx = getelementptr inbounds nuw %struct.Input, ptr %input, i32 0, i32 0 +// CHECK: %[[#tmp:]] = load float, ptr %Idx, align 1 +// CHECK: %a = getelementptr inbounds nuw %struct.Output, ptr %agg.result, i32 0, i32 0 +// CHECK: store float %[[#tmp]], ptr %a, align 1 + +// CHECK: %Idx1 = getelementptr inbounds nuw %struct.Input, ptr %input, i32 0, i32 0 +// CHECK: %[[#tmp:]] = load float, ptr %Idx1, align 1 +// CHECK: %b = getelementptr inbounds nuw %struct.Output, ptr %agg.result, i32 0, i32 1 +// CHECK: store float %[[#tmp]], ptr %b, align 1 + +Output main(Input input) { + Output o; + o.a = input.Idx; + o.b = input.Idx; + return o; +} + +// Code generated in the entrypoint wrapper: + +// CHECK: %[[#OUTPUT:]] = alloca %struct.Output, align 8 + +// CHECK-SPIRV: call spir_func void @_Z4main5Input(ptr %[[#OUTPUT]], ptr %[[#]]) +// CHECK-DXIL: call void @_Z4main5Input(ptr %[[#OUTPUT]], ptr %[[#]]) + +// CHECK: %[[#TMP:]] = load %struct.Output, ptr %[[#OUTPUT]], align 4 +// CHECK: %[[#VAL:]] = extractvalue %struct.Output %[[#TMP]], 0 +// CHECK-SPIRV: store float %[[#VAL]], ptr addrspace(8) @A4, align 4 +// CHECK-DXIL: call void @llvm.dx.store.output.f32(i32 4, i32 0, i32 0, i8 0, i32 poison, float %[[#VAL]]) +// CHECK: %[[#VAL:]] = extractvalue %struct.Output %[[#TMP]], 1 +// CHECK-SPIRV: store float %[[#VAL]], ptr addrspace(8) @A2, align 4 +// CHECK-DXIL: call void @llvm.dx.store.output.f32(i32 4, i32 0, i32 0, i8 0, i32 poison, float %[[#VAL]]) + +// CHECK-SPIRV-DAG: ![[#METADATA_0]] = !{![[#METADATA_1:]]} +// CHECK-SPIRV-DAG: ![[#METADATA_2]] = !{![[#METADATA_3:]]} +// CHECK-SPIRV-DAG: ![[#METADATA_1]] = !{i32 30, i32 0} +// CHECK-SPIRV-DAG: ![[#METADATA_3]] = !{i32 30, i32 1} +// | `- Location index +// `-> Decoration "Location" diff --git a/clang/test/CodeGenHLSL/sret_output.hlsl b/clang/test/CodeGenHLSL/sret_output.hlsl index eefc9da..e1aa097 100644 --- a/clang/test/CodeGenHLSL/sret_output.hlsl +++ b/clang/test/CodeGenHLSL/sret_output.hlsl @@ -1,21 +1,33 @@ // RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -triple dxil-pc-shadermodel6.3-library %s \ -// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s --check-prefixes=CHECK-DX,CHECK +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -triple spirv-pc-vulkan-library %s \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s --check-prefixes=CHECK-VK,CHECK -// FIXME: add semantic to a. -// See https://github.com/llvm/llvm-project/issues/57874 struct S { - float a; + float a : A4; }; +// CHECK-VK: @A4 = external hidden thread_local addrspace(8) global float, !spirv.Decorations ![[#ATTR0:]] // Make sure sret parameter is generated. -// CHECK:define internal void @_Z7ps_mainv(ptr dead_on_unwind noalias writable sret(%struct.S) align 1 %agg.result) -// FIXME: change it to real value instead of poison value once semantic is add to a. -// Make sure the function with sret is called. -// CHECK:call void @_Z7ps_mainv(ptr poison) -[shader("pixel")] -S ps_main() { +// CHECK-DX: define internal void @_Z7vs_mainv(ptr dead_on_unwind noalias writable sret(%struct.S) align 1 %agg.result) +// CHECK-VK: define internal spir_func void @_Z7vs_mainv(ptr dead_on_unwind noalias writable sret(%struct.S) align 1 %agg.result) + +[shader("vertex")] +S vs_main() { S s; s.a = 0; return s; }; + +// CHECK: %[[#alloca:]] = alloca %struct.S, align 8 +// CHECK-DX: call void @_Z7vs_mainv(ptr %[[#alloca]]) +// CHECK-VK: call spir_func void @_Z7vs_mainv(ptr %[[#alloca]]) +// CHECK: %[[#a:]] = load %struct.S, ptr %[[#alloca]], align 4 +// CHECK: %[[#b:]] = extractvalue %struct.S %[[#a]], 0 +// CHECK-DX: call void @llvm.dx.store.output.f32(i32 4, i32 0, i32 0, i8 0, i32 poison, float %[[#b]]) +// CHECK-VK: store float %3, ptr addrspace(8) @A4, align 4 +// CHECK: ret void + +// CHECK-VK: ![[#ATTR0]] = !{![[#ATTR1:]]} +// CHECK-VK: ![[#ATTR1]] = !{i32 30, i32 0} |
