xref: /llvm-project/clang/test/CodeGenHLSL/ArrayTemporary.hlsl (revision 762f1b17b2815ccdfb4e5cb5412cb6210db92f73)
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