xref: /llvm-project/llvm/test/CodeGen/DirectX/flatten-array.ll (revision e0b522dd94e48229d587a54a3103ba1c198b16a7)
1
2; RUN: opt -S -dxil-flatten-arrays  %s | FileCheck %s
3
4; CHECK-LABEL: alloca_2d_test
5define void @alloca_2d_test ()  {
6; CHECK-NEXT:    alloca [9 x i32], align 4
7; CHECK-NEXT:    ret void
8;
9  %1 = alloca [3 x [3 x i32]], align 4
10  ret void
11}
12
13; CHECK-LABEL: alloca_3d_test
14define void @alloca_3d_test ()  {
15; CHECK-NEXT:    alloca [8 x i32], align 4
16; CHECK-NEXT:    ret void
17;
18  %1 = alloca [2 x[2 x [2 x i32]]], align 4
19  ret void
20}
21
22; CHECK-LABEL: alloca_4d_test
23define void @alloca_4d_test ()  {
24; CHECK-NEXT:    alloca [16 x i32], align 4
25; CHECK-NEXT:    ret void
26;
27  %1 = alloca [2x[2 x[2 x [2 x i32]]]], align 4
28  ret void
29}
30
31; CHECK-LABEL: gep_2d_test
32define void @gep_2d_test ()  {
33    ; CHECK: [[a:%.*]] = alloca [9 x i32], align 4
34    ; CHECK-COUNT-9: getelementptr inbounds [9 x i32], ptr [[a]], i32 {{[0-8]}}
35    ; CHECK-NEXT:    ret void
36    %1 = alloca [3 x [3 x i32]], align 4
37    %g2d0 = getelementptr inbounds [3 x [3 x i32]], [3 x [3 x i32]]* %1, i32 0, i32 0
38    %g1d_1 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d0, i32 0, i32 0
39    %g1d_2 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d0, i32 0, i32 1
40    %g1d_3 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d0, i32 0, i32 2
41    %g2d1 = getelementptr inbounds [3 x [3 x i32]], [3 x [3 x i32]]* %1, i32 0, i32 1
42    %g1d1_1 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d1, i32 0, i32 0
43    %g1d1_2 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d1, i32 0, i32 1
44    %g1d1_3 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d1, i32 0, i32 2
45    %g2d2 = getelementptr inbounds [3 x [3 x i32]], [3 x [3 x i32]]* %1, i32 0, i32 2
46    %g1d2_1 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d2, i32 0, i32 0
47    %g1d2_2 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d2, i32 0, i32 1
48    %g1d2_3 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d2, i32 0, i32 2
49
50    ret void
51}
52
53; CHECK-LABEL: gep_3d_test
54define void @gep_3d_test ()  {
55    ; CHECK: [[a:%.*]] = alloca [8 x i32], align 4
56    ; CHECK-COUNT-8: getelementptr inbounds [8 x i32], ptr [[a]], i32 {{[0-7]}}
57    ; CHECK-NEXT:    ret void
58    %1 = alloca [2 x[2 x [2 x i32]]], align 4
59    %g3d0 = getelementptr inbounds [2 x[2 x [2 x i32]]], [2 x[2 x [2 x i32]]]* %1, i32 0, i32 0
60    %g2d0 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d0, i32 0, i32 0
61    %g1d_1 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0, i32 0, i32 0
62    %g1d_2 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0, i32 0, i32 1
63    %g2d1 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d0, i32 0, i32 1
64    %g1d1_1 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d1, i32 0, i32 0
65    %g1d1_2 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d1, i32 0, i32 1
66    %g3d1 = getelementptr inbounds [2 x[2 x [2 x i32]]], [2 x[2 x [2 x i32]]]* %1, i32 0, i32 1
67    %g2d2 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d1, i32 0, i32 0
68    %g1d2_1 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d2, i32 0, i32 0
69    %g1d2_2 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d2, i32 0, i32 1
70    %g2d3 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d1, i32 0, i32 1
71    %g1d3_1 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d3, i32 0, i32 0
72    %g1d3_2 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d3, i32 0, i32 1
73    ret void
74}
75
76; CHECK-LABEL: gep_4d_test
77define void @gep_4d_test ()  {
78    ; CHECK: [[a:%.*]] = alloca [16 x i32], align 4
79    ; CHECK-COUNT-16: getelementptr inbounds [16 x i32], ptr [[a]], i32 {{[0-9]|1[0-5]}}
80    ; CHECK-NEXT:    ret void
81    %1 = alloca [2x[2 x[2 x [2 x i32]]]], align 4
82    %g4d0 = getelementptr inbounds [2x[2 x[2 x [2 x i32]]]], [2x[2 x[2 x [2 x i32]]]]* %1, i32 0, i32 0
83    %g3d0 = getelementptr inbounds [2 x[2 x [2 x i32]]], [2 x[2 x [2 x i32]]]* %g4d0, i32 0, i32 0
84    %g2d0_0 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d0, i32 0, i32 0
85    %g1d_0 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_0, i32 0, i32 0
86    %g1d_1 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_0, i32 0, i32 1
87    %g2d0_1 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d0, i32 0, i32 1
88    %g1d_2 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_1, i32 0, i32 0
89    %g1d_3 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_1, i32 0, i32 1
90    %g3d1 = getelementptr inbounds [2 x[2 x [2 x i32]]], [2 x[2 x [2 x i32]]]* %g4d0, i32 0, i32 1
91    %g2d0_2 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d1, i32 0, i32 0
92    %g1d_4 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_2, i32 0, i32 0
93    %g1d_5 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_2, i32 0, i32 1
94    %g2d1_2 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d1, i32 0, i32 1
95    %g1d_6 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d1_2, i32 0, i32 0
96    %g1d_7 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d1_2, i32 0, i32 1
97    %g4d1 = getelementptr inbounds [2x[2 x[2 x [2 x i32]]]], [2x[2 x[2 x [2 x i32]]]]* %1, i32 0, i32 1
98    %g3d0_1 = getelementptr inbounds [2 x[2 x [2 x i32]]], [2 x[2 x [2 x i32]]]* %g4d1, i32 0, i32 0
99    %g2d0_3 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d0_1, i32 0, i32 0
100    %g1d_8 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_3, i32 0, i32 0
101    %g1d_9 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_3, i32 0, i32 1
102    %g2d0_4 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d0_1, i32 0, i32 1
103    %g1d_10 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_4, i32 0, i32 0
104    %g1d_11 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_4, i32 0, i32 1
105    %g3d1_1 = getelementptr inbounds [2 x[2 x [2 x i32]]], [2 x[2 x [2 x i32]]]* %g4d1, i32 0, i32 1
106    %g2d0_5 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d1_1, i32 0, i32 0
107    %g1d_12 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_5, i32 0, i32 0
108    %g1d_13 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_5, i32 0, i32 1
109    %g2d1_3 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d1_1, i32 0, i32 1
110    %g1d_14 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d1_3, i32 0, i32 0
111    %g1d_15 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d1_3, i32 0, i32 1
112    ret void
113}
114
115
116@a = internal global [2 x [3 x [4 x i32]]] [[3 x [4 x i32]] [[4 x i32] [i32 0, i32 1, i32 2, i32 3],
117                                                             [4 x i32] [i32 4, i32 5, i32 6, i32 7],
118                                                             [4 x i32] [i32 8, i32 9, i32 10, i32 11]],
119                                            [3 x [4 x i32]] [[4 x i32] [i32 12, i32 13, i32 14, i32 15],
120                                                             [4 x i32] [i32 16, i32 17, i32 18, i32 19],
121                                                             [4 x i32] [i32 20, i32 21, i32 22, i32 23]]], align 4
122
123@b = internal global [2 x [3 x [4 x i32]]] zeroinitializer, align 16
124
125define void @global_gep_load() {
126  ; CHECK: [[GEP_PTR:%.*]] = getelementptr inbounds [24 x i32], ptr @a.1dim, i32 6
127  ; CHECK: load i32, ptr [[GEP_PTR]], align 4
128  ; CHECK-NEXT:    ret void
129  %1 = getelementptr inbounds [2 x [3 x [4 x i32]]], [2 x [3 x [4 x i32]]]* @a, i32 0, i32 0
130  %2 = getelementptr inbounds [3 x [4 x i32]], [3 x [4 x i32]]* %1, i32 0, i32 1
131  %3 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i32 0, i32 2
132  %4 = load i32, i32* %3, align 4
133  ret void
134}
135
136define void @global_gep_load_index(i32 %row, i32 %col, i32 %timeIndex) {
137; CHECK-LABEL: define void @global_gep_load_index(
138; CHECK-SAME: i32 [[ROW:%.*]], i32 [[COL:%.*]], i32 [[TIMEINDEX:%.*]]) {
139; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[TIMEINDEX]], 1
140; CHECK-NEXT:    [[TMP2:%.*]] = add i32 0, [[TMP1]]
141; CHECK-NEXT:    [[TMP3:%.*]] = mul i32 [[COL]], 4
142; CHECK-NEXT:    [[TMP4:%.*]] = add i32 [[TMP2]], [[TMP3]]
143; CHECK-NEXT:    [[TMP5:%.*]] = mul i32 [[ROW]], 12
144; CHECK-NEXT:    [[TMP6:%.*]] = add i32 [[TMP4]], [[TMP5]]
145; CHECK-NEXT:    [[DOTFLAT:%.*]] = getelementptr inbounds [24 x i32], ptr @a.1dim, i32 [[TMP6]]
146; CHECK-NOT: getelementptr inbounds [2 x [3 x [4 x i32]]]{{.*}}
147; CHECK-NOT: getelementptr inbounds [3 x [4 x i32]]{{.*}}
148; CHECK-NOT: getelementptr inbounds [4 x i32]{{.*}}
149; CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLAT]], align 4
150; CHECK-NEXT:    ret void
151;
152  %1 = getelementptr inbounds [2 x [3 x [4 x i32]]], [2 x [3 x [4 x i32]]]* @a, i32 0, i32 %row
153  %2 = getelementptr inbounds [3 x [4 x i32]], [3 x [4 x i32]]* %1, i32 0, i32 %col
154  %3 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i32 0, i32 %timeIndex
155  %4 = load i32, i32* %3, align 4
156  ret void
157}
158
159define void @global_incomplete_gep_chain(i32 %row, i32 %col) {
160; CHECK-LABEL: define void @global_incomplete_gep_chain(
161; CHECK-SAME: i32 [[ROW:%.*]], i32 [[COL:%.*]]) {
162; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[COL]], 1
163; CHECK-NEXT:    [[TMP2:%.*]] = add i32 0, [[TMP1]]
164; CHECK-NEXT:    [[TMP3:%.*]] = mul i32 [[ROW]], 3
165; CHECK-NEXT:    [[TMP4:%.*]] = add i32 [[TMP2]], [[TMP3]]
166; CHECK-NEXT:    [[DOTFLAT:%.*]] = getelementptr inbounds [24 x i32], ptr @a.1dim, i32 [[TMP4]]
167; CHECK-NOT: getelementptr inbounds [2 x [3 x [4 x i32]]]{{.*}}
168; CHECK-NOT: getelementptr inbounds [3 x [4 x i32]]{{.*}}
169; CHECK-NOT: getelementptr inbounds [4 x i32]{{.*}}
170; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTFLAT]], align 4
171; CHECK-NEXT:    ret void
172;
173  %1 = getelementptr inbounds [2 x [3 x [4 x i32]]], [2 x [3 x [4 x i32]]]* @a, i32 0, i32 %row
174  %2 = getelementptr inbounds [3 x [4 x i32]], [3 x [4 x i32]]* %1, i32 0, i32 %col
175  %4 = load i32, i32* %2, align 4
176  ret void
177}
178
179define void @global_gep_store() {
180  ; CHECK: [[GEP_PTR:%.*]] = getelementptr inbounds [24 x i32], ptr @b.1dim, i32 13
181  ; CHECK:  store i32 1, ptr [[GEP_PTR]], align 4
182  ; CHECK-NEXT:    ret void
183  %1 = getelementptr inbounds [2 x [3 x [4 x i32]]], [2 x [3 x [4 x i32]]]* @b, i32 0, i32 1
184  %2 = getelementptr inbounds [3 x [4 x i32]], [3 x [4 x i32]]* %1, i32 0, i32 0
185  %3 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i32 0, i32 1
186  store i32 1, i32* %3, align 4
187  ret void
188}
189
190; Make sure we don't try to walk the body of a function declaration.
191declare void @opaque_function()
192