1// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s 2 3void fn(float x[2]) { } 4 5// CHECK-LABEL: define void {{.*}}call{{.*}} 6// CHECK: [[Arr:%.*]] = alloca [2 x float] 7// CHECK: [[Tmp:%.*]] = alloca [2 x float] 8// CHECK: call void @llvm.memset.p0.i32(ptr align 4 [[Arr]], i8 0, i32 8, i1 false) 9// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[Arr]], i32 8, i1 false) 10// CHECK: call void {{.*}}fn{{.*}}(ptr noundef byval([2 x float]) align 4 [[Tmp]]) 11void call() { 12 float Arr[2] = {0, 0}; 13 fn(Arr); 14} 15 16struct Obj { 17 float V; 18 int X; 19}; 20 21void fn2(Obj O[4]) { } 22 23// CHECK-LABEL: define void {{.*}}call2{{.*}} 24// CHECK: [[Arr:%.*]] = alloca [4 x %struct.Obj] 25// CHECK: [[Tmp:%.*]] = alloca [4 x %struct.Obj] 26// CHECK: call void @llvm.memset.p0.i32(ptr align 4 [[Arr]], i8 0, i32 32, i1 false) 27// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[Arr]], i32 32, i1 false) 28// CHECK: call void {{.*}}fn2{{.*}}(ptr noundef byval([4 x %struct.Obj]) align 4 [[Tmp]]) 29void call2() { 30 Obj Arr[4] = {}; 31 fn2(Arr); 32} 33 34 35void fn3(float x[2][2]) { } 36 37// CHECK-LABEL: define void {{.*}}call3{{.*}} 38// CHECK: [[Arr:%.*]] = alloca [2 x [2 x float]] 39// CHECK: [[Tmp:%.*]] = alloca [2 x [2 x float]] 40// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr]], ptr align 4 {{.*}}, i32 16, i1 false) 41// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[Arr]], i32 16, i1 false) 42// CHECK: call void {{.*}}fn3{{.*}}(ptr noundef byval([2 x [2 x float]]) align 4 [[Tmp]]) 43void call3() { 44 float Arr[2][2] = {{0, 0}, {1,1}}; 45 fn3(Arr); 46} 47 48// CHECK-LABEL: define void {{.*}}call4{{.*}}(ptr 49// CHECK-SAME: noundef byval([2 x [2 x float]]) align 4 [[Arr:%.*]]) 50// CHECK: [[Tmp:%.*]] = alloca [2 x [2 x float]] 51// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[Arr]], i32 16, i1 false) 52// CHECK: call void {{.*}}fn3{{.*}}(ptr noundef byval([2 x [2 x float]]) align 4 [[Tmp]]) 53 54void call4(float Arr[2][2]) { 55 fn3(Arr); 56} 57 58// Verify that each template instantiation codegens to a unique and correctly 59// mangled function name. 60 61// CHECK-LABEL: define void {{.*}}template_call{{.*}}(ptr 62 63// CHECK-SAME: noundef byval([2 x float]) align 4 [[FA2:%[0-9A-Z]+]], 64// CHECK-SAME: ptr noundef byval([4 x float]) align 4 [[FA4:%[0-9A-Z]+]], 65// CHECK-SAME: ptr noundef byval([3 x i32]) align 4 [[IA3:%[0-9A-Z]+]] 66 67// CHECK: [[Tmp1:%.*]] = alloca [2 x float] 68// CHECK: [[Tmp2:%.*]] = alloca [4 x float] 69// CHECK: [[Tmp3:%.*]] = alloca [3 x i32] 70// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp1]], ptr align 4 [[FA2]], i32 8, i1 false) 71// CHECK: call void @_Z11template_fnIA2_fEvT_(ptr noundef byval([2 x float]) align 4 [[Tmp1]]) 72// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp2]], ptr align 4 [[FA4]], i32 16, i1 false) 73// CHECK: call void @_Z11template_fnIA4_fEvT_(ptr noundef byval([4 x float]) align 4 [[Tmp2]]) 74// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp3]], ptr align 4 [[IA3]], i32 12, i1 false) 75// CHECK: call void @_Z11template_fnIA3_iEvT_(ptr noundef byval([3 x i32]) align 4 [[Tmp3]]) 76 77template<typename T> 78void template_fn(T Val) {} 79 80void template_call(float FA2[2], float FA4[4], int IA3[3]) { 81 template_fn(FA2); 82 template_fn(FA4); 83 template_fn(IA3); 84} 85 86 87// Verify that Array parameter element access correctly codegens. 88// CHECK-LABEL: define void {{.*}}element_access{{.*}}(ptr 89// CHECK-SAME: noundef byval([2 x float]) align 4 [[FA2:%[0-9A-Z]+]] 90 91// CHECK: [[Addr:%.*]] = getelementptr inbounds [2 x float], ptr [[FA2]], i32 0, i32 0 92// CHECK: [[Tmp:%.*]] = load float, ptr [[Addr]] 93// CHECK: call void @_Z11template_fnIfEvT_(float noundef nofpclass(nan inf) [[Tmp]]) 94 95// CHECK: [[Idx0:%.*]] = getelementptr inbounds [2 x float], ptr [[FA2]], i32 0, i32 0 96// CHECK: [[Val0:%.*]] = load float, ptr [[Idx0]] 97// CHECK: [[Sum:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[Val0]], 5.000000e+00 98// CHECK: [[Idx1:%.*]] = getelementptr inbounds [2 x float], ptr [[FA2]], i32 0, i32 1 99// CHECK: store float [[Sum]], ptr [[Idx1]] 100 101void element_access(float FA2[2]) { 102 template_fn(FA2[0]); 103 FA2[1] = FA2[0] + 5; 104} 105