xref: /llvm-project/llvm/test/Transforms/SeparateConstOffsetFromGEP/AMDGPU/reorder-gep.ll (revision 9c7848171779dffb2e23cc7db6b518612e804a74)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx90a --passes=separate-const-offset-from-gep < %s | FileCheck %s
3
4define void @sink_addr(ptr addrspace(3) %in.ptr, i64 %in.idx0, i64 %in.idx1) {
5; CHECK-LABEL: define void @sink_addr(
6; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0:[0-9]+]] {
7; CHECK-NEXT:  entry:
8; CHECK-NEXT:    [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32
9; CHECK-NEXT:    [[BASE:%.*]] = getelementptr half, ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]]
10; CHECK-NEXT:    [[IDXPROM1:%.*]] = trunc i64 [[IN_IDX1]] to i32
11; CHECK-NEXT:    [[IDX0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM1]]
12; CHECK-NEXT:    [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX1]] to i32
13; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM2]]
14; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr half, ptr addrspace(3) [[TMP0]], i64 256
15; CHECK-NEXT:    [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX1]] to i32
16; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM3]]
17; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr half, ptr addrspace(3) [[TMP2]], i64 512
18; CHECK-NEXT:    [[IDXPROM4:%.*]] = trunc i64 [[IN_IDX1]] to i32
19; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM4]]
20; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr half, ptr addrspace(3) [[TMP4]], i64 768
21; CHECK-NEXT:    ret void
22;
23entry:
24  %base = getelementptr half, ptr addrspace(3) %in.ptr, i64 %in.idx0
25  %idx0 = getelementptr half, ptr addrspace(3) %base, i64 %in.idx1
26  %const1 = getelementptr half, ptr addrspace(3) %base, i64 256
27  %idx1 = getelementptr half, ptr addrspace(3) %const1, i64 %in.idx1
28  %const2 = getelementptr half, ptr addrspace(3) %base, i64 512
29  %idx2 = getelementptr half, ptr addrspace(3) %const2, i64 %in.idx1
30  %const3 = getelementptr half, ptr addrspace(3) %base, i64 768
31  %idx3 = getelementptr half, ptr addrspace(3) %const3, i64 %in.idx1
32  ret void
33}
34
35define void @illegal_addr_mode(ptr addrspace(3) %in.ptr, i64 %in.idx0, i64 %in.idx1) {
36; CHECK-LABEL: define void @illegal_addr_mode(
37; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
38; CHECK-NEXT:  entry:
39; CHECK-NEXT:    [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32
40; CHECK-NEXT:    [[BASE:%.*]] = getelementptr half, ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]]
41; CHECK-NEXT:    [[IDXPROM1:%.*]] = trunc i64 [[IN_IDX1]] to i32
42; CHECK-NEXT:    [[IDX0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM1]]
43; CHECK-NEXT:    [[CONST1:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i64 38192
44; CHECK-NEXT:    [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX1]] to i32
45; CHECK-NEXT:    [[IDX1:%.*]] = getelementptr half, ptr addrspace(3) [[CONST1]], i32 [[IDXPROM2]]
46; CHECK-NEXT:    [[CONST2:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i64 38448
47; CHECK-NEXT:    [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX1]] to i32
48; CHECK-NEXT:    [[IDX2:%.*]] = getelementptr half, ptr addrspace(3) [[CONST2]], i32 [[IDXPROM3]]
49; CHECK-NEXT:    [[CONST3:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i64 38764
50; CHECK-NEXT:    [[IDXPROM4:%.*]] = trunc i64 [[IN_IDX1]] to i32
51; CHECK-NEXT:    [[IDX3:%.*]] = getelementptr half, ptr addrspace(3) [[CONST3]], i32 [[IDXPROM4]]
52; CHECK-NEXT:    ret void
53;
54entry:
55  %base = getelementptr half, ptr addrspace(3) %in.ptr, i64 %in.idx0
56  %idx0 = getelementptr half, ptr addrspace(3) %base, i64 %in.idx1
57  %const1 = getelementptr half, ptr addrspace(3) %base, i64 38192
58  %idx1 = getelementptr half, ptr addrspace(3) %const1, i64 %in.idx1
59  %const2 = getelementptr half, ptr addrspace(3) %base, i64 38448
60  %idx2 = getelementptr half, ptr addrspace(3) %const2, i64 %in.idx1
61  %const3 = getelementptr half, ptr addrspace(3) %base, i64 38764
62  %idx3 = getelementptr half, ptr addrspace(3) %const3, i64 %in.idx1
63  ret void
64}
65
66
67define void @reorder_i8half(ptr addrspace(3) %in.ptr, i64 %in.idx0, i64 %in.idx1) {
68; CHECK-LABEL: define void @reorder_i8half(
69; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
70; CHECK-NEXT:  entry:
71; CHECK-NEXT:    [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32
72; CHECK-NEXT:    [[BASE:%.*]] = getelementptr i8, ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]]
73; CHECK-NEXT:    [[IDXPROM1:%.*]] = trunc i64 [[IN_IDX1]] to i32
74; CHECK-NEXT:    [[IDX0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM1]]
75; CHECK-NEXT:    [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX1]] to i32
76; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM2]]
77; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP0]], i64 256
78; CHECK-NEXT:    [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX1]] to i32
79; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM3]]
80; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP2]], i64 512
81; CHECK-NEXT:    [[IDXPROM4:%.*]] = trunc i64 [[IN_IDX1]] to i32
82; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM4]]
83; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP4]], i64 768
84; CHECK-NEXT:    ret void
85;
86entry:
87  %base = getelementptr i8, ptr addrspace(3) %in.ptr, i64 %in.idx0
88  %idx0 = getelementptr half, ptr addrspace(3) %base, i64 %in.idx1
89  %const1 = getelementptr i8, ptr addrspace(3) %base, i64 256
90  %idx1 = getelementptr half, ptr addrspace(3) %const1, i64 %in.idx1
91  %const2 = getelementptr i8, ptr addrspace(3) %base, i64 512
92  %idx2 = getelementptr half, ptr addrspace(3) %const2, i64 %in.idx1
93  %const3 = getelementptr i8, ptr addrspace(3) %base, i64 768
94  %idx3 = getelementptr half, ptr addrspace(3) %const3, i64 %in.idx1
95  ret void
96}
97
98define void @reorder_i64half(ptr addrspace(3) %in.ptr, i64 %in.idx0, i64 %in.idx1) {
99; CHECK-LABEL: define void @reorder_i64half(
100; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
101; CHECK-NEXT:  entry:
102; CHECK-NEXT:    [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32
103; CHECK-NEXT:    [[BASE:%.*]] = getelementptr i64, ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]]
104; CHECK-NEXT:    [[IDXPROM1:%.*]] = trunc i64 [[IN_IDX1]] to i32
105; CHECK-NEXT:    [[IDX0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM1]]
106; CHECK-NEXT:    [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX1]] to i32
107; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM2]]
108; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i64, ptr addrspace(3) [[TMP0]], i64 256
109; CHECK-NEXT:    [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX1]] to i32
110; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM3]]
111; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr i64, ptr addrspace(3) [[TMP2]], i64 512
112; CHECK-NEXT:    [[IDXPROM4:%.*]] = trunc i64 [[IN_IDX1]] to i32
113; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM4]]
114; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr i64, ptr addrspace(3) [[TMP4]], i64 768
115; CHECK-NEXT:    ret void
116;
117entry:
118  %base = getelementptr i64, ptr addrspace(3) %in.ptr, i64 %in.idx0
119  %idx0 = getelementptr half, ptr addrspace(3) %base, i64 %in.idx1
120  %const1 = getelementptr i64, ptr addrspace(3) %base, i64 256
121  %idx1 = getelementptr half, ptr addrspace(3) %const1, i64 %in.idx1
122  %const2 = getelementptr i64, ptr addrspace(3) %base, i64 512
123  %idx2 = getelementptr half, ptr addrspace(3) %const2, i64 %in.idx1
124  %const3 = getelementptr i64, ptr addrspace(3) %base, i64 768
125  %idx3 = getelementptr half, ptr addrspace(3) %const3, i64 %in.idx1
126  ret void
127}
128
129define void @reorder_halfi8(ptr addrspace(3) %in.ptr, i64 %in.idx0, i64 %in.idx1) {
130; CHECK-LABEL: define void @reorder_halfi8(
131; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
132; CHECK-NEXT:  entry:
133; CHECK-NEXT:    [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32
134; CHECK-NEXT:    [[BASE:%.*]] = getelementptr half, ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]]
135; CHECK-NEXT:    [[IDXPROM1:%.*]] = trunc i64 [[IN_IDX1]] to i32
136; CHECK-NEXT:    [[IDX0:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM1]]
137; CHECK-NEXT:    [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX1]] to i32
138; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM2]]
139; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr half, ptr addrspace(3) [[TMP0]], i64 256
140; CHECK-NEXT:    [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX1]] to i32
141; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM3]]
142; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr half, ptr addrspace(3) [[TMP2]], i64 512
143; CHECK-NEXT:    [[IDXPROM4:%.*]] = trunc i64 [[IN_IDX1]] to i32
144; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM4]]
145; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr half, ptr addrspace(3) [[TMP4]], i64 768
146; CHECK-NEXT:    ret void
147;
148entry:
149  %base = getelementptr half, ptr addrspace(3) %in.ptr, i64 %in.idx0
150  %idx0 = getelementptr i8, ptr addrspace(3) %base, i64 %in.idx1
151  %const1 = getelementptr half, ptr addrspace(3) %base, i64 256
152  %idx1 = getelementptr i8, ptr addrspace(3) %const1, i64 %in.idx1
153  %const2 = getelementptr half, ptr addrspace(3) %base, i64 512
154  %idx2 = getelementptr i8, ptr addrspace(3) %const2, i64 %in.idx1
155  %const3 = getelementptr half, ptr addrspace(3) %base, i64 768
156  %idx3 = getelementptr i8, ptr addrspace(3) %const3, i64 %in.idx1
157  ret void
158}
159
160
161
162define void @bad_index(ptr addrspace(3) %in.ptr, i64 %in.idx0, i64 %in.idx1) {
163; CHECK-LABEL: define void @bad_index(
164; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
165; CHECK-NEXT:  entry:
166; CHECK-NEXT:    [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32
167; CHECK-NEXT:    [[BASE:%.*]] = getelementptr half, ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]]
168; CHECK-NEXT:    [[IDXPROM1:%.*]] = trunc i64 [[IN_IDX1]] to i32
169; CHECK-NEXT:    [[IDX0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM1]]
170; CHECK-NEXT:    [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX1]] to i32
171; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM2]]
172; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP4]], i64 1
173; CHECK-NEXT:    [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX1]] to i32
174; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM3]]
175; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP2]], i64 2
176; CHECK-NEXT:    [[IDXPROM4:%.*]] = trunc i64 [[IN_IDX1]] to i32
177; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM4]]
178; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP0]], i64 3
179; CHECK-NEXT:    ret void
180;
181entry:
182  %base = getelementptr half, ptr addrspace(3) %in.ptr, i64 %in.idx0
183  %idx0 = getelementptr half, ptr addrspace(3) %base, i64 %in.idx1
184  %const1 = getelementptr i8, ptr addrspace(3) %base, i64 1
185  %idx1 = getelementptr half, ptr addrspace(3) %const1, i64 %in.idx1
186  %const2 = getelementptr i8, ptr addrspace(3) %base, i64 2
187  %idx2 = getelementptr half, ptr addrspace(3) %const2, i64 %in.idx1
188  %const3 = getelementptr i8, ptr addrspace(3) %base, i64 3
189  %idx3 = getelementptr half, ptr addrspace(3) %const3, i64 %in.idx1
190  ret void
191}
192
193
194%struct.vec = type { [8 x i8], [4 x half] }
195define void @vector_struct_type(ptr addrspace(3) %in.ptr, i64 %in.idx0, i64 %in.idx1) {
196; CHECK-LABEL: define void @vector_struct_type(
197; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
198; CHECK-NEXT:  entry:
199; CHECK-NEXT:    [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32
200; CHECK-NEXT:    [[BASE:%.*]] = getelementptr [1024 x %struct.vec], ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]]
201; CHECK-NEXT:    [[IDXPROM1:%.*]] = trunc i64 [[IN_IDX1]] to i32
202; CHECK-NEXT:    [[IDX0:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM1]]
203; CHECK-NEXT:    [[CONST1:%.*]] = getelementptr [1024 x %struct.vec], ptr addrspace(3) [[BASE]], i64 256
204; CHECK-NEXT:    [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX1]] to i32
205; CHECK-NEXT:    [[IDX1:%.*]] = getelementptr i8, ptr addrspace(3) [[CONST1]], i32 [[IDXPROM2]]
206; CHECK-NEXT:    [[CONST2:%.*]] = getelementptr [1024 x %struct.vec], ptr addrspace(3) [[BASE]], i64 512
207; CHECK-NEXT:    [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX1]] to i32
208; CHECK-NEXT:    [[IDX2:%.*]] = getelementptr i8, ptr addrspace(3) [[CONST2]], i32 [[IDXPROM3]]
209; CHECK-NEXT:    [[CONST3:%.*]] = getelementptr [1024 x %struct.vec], ptr addrspace(3) [[BASE]], i64 768
210; CHECK-NEXT:    [[IDXPROM4:%.*]] = trunc i64 [[IN_IDX1]] to i32
211; CHECK-NEXT:    [[IDX3:%.*]] = getelementptr i8, ptr addrspace(3) [[CONST3]], i32 [[IDXPROM4]]
212; CHECK-NEXT:    ret void
213;
214entry:
215  %base = getelementptr [1024 x %struct.vec], ptr addrspace(3) %in.ptr, i64 %in.idx0
216  %idx0 = getelementptr i8, ptr addrspace(3) %base, i64 %in.idx1
217  %const1 = getelementptr [1024 x %struct.vec], ptr addrspace(3) %base, i64 256
218  %idx1 = getelementptr i8, ptr addrspace(3) %const1, i64 %in.idx1
219  %const2 = getelementptr [1024 x %struct.vec], ptr addrspace(3) %base, i64 512
220  %idx2 = getelementptr i8, ptr addrspace(3) %const2, i64 %in.idx1
221  %const3 = getelementptr [1024 x %struct.vec], ptr addrspace(3) %base, i64 768
222  %idx3 = getelementptr i8, ptr addrspace(3) %const3, i64 %in.idx1
223  ret void
224}
225
226define void @struct_type(ptr addrspace(3) %in.ptr, i64 %in.idx0, i64 %in.idx1) {
227; CHECK-LABEL: define void @struct_type(
228; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
229; CHECK-NEXT:  entry:
230; CHECK-NEXT:    [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32
231; CHECK-NEXT:    [[BASE:%.*]] = getelementptr [[STRUCT_VEC:%.*]], ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]]
232; CHECK-NEXT:    [[IDXPROM1:%.*]] = trunc i64 [[IN_IDX1]] to i32
233; CHECK-NEXT:    [[IDX0:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM1]]
234; CHECK-NEXT:    [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX1]] to i32
235; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM2]]
236; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr [[STRUCT_VEC]], ptr addrspace(3) [[TMP0]], i64 256
237; CHECK-NEXT:    [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX1]] to i32
238; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM3]]
239; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr [[STRUCT_VEC]], ptr addrspace(3) [[TMP2]], i64 512
240; CHECK-NEXT:    [[IDXPROM4:%.*]] = trunc i64 [[IN_IDX1]] to i32
241; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM4]]
242; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr [[STRUCT_VEC]], ptr addrspace(3) [[TMP4]], i64 768
243; CHECK-NEXT:    ret void
244;
245entry:
246  %base = getelementptr %struct.vec, ptr addrspace(3) %in.ptr, i64 %in.idx0
247  %idx0 = getelementptr i8, ptr addrspace(3) %base, i64 %in.idx1
248  %const1 = getelementptr %struct.vec, ptr addrspace(3) %base, i64 256
249  %idx1 = getelementptr i8, ptr addrspace(3) %const1, i64 %in.idx1
250  %const2 = getelementptr %struct.vec, ptr addrspace(3) %base, i64 512
251  %idx2 = getelementptr i8, ptr addrspace(3) %const2, i64 %in.idx1
252  %const3 = getelementptr %struct.vec, ptr addrspace(3) %base, i64 768
253  %idx3 = getelementptr i8, ptr addrspace(3) %const3, i64 %in.idx1
254  ret void
255}
256
257define void @struct_type_multiindex(ptr addrspace(3) %in.ptr, i64 %in.idx0, i32 %in.idx1, i64 %in.idx2) {
258; CHECK-LABEL: define void @struct_type_multiindex(
259; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i32 [[IN_IDX1:%.*]], i64 [[IN_IDX2:%.*]]) #[[ATTR0]] {
260; CHECK-NEXT:  entry:
261; CHECK-NEXT:    [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32
262; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr [[STRUCT_VEC:%.*]], ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]], i32 0, i32 0
263; CHECK-NEXT:    [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX2]] to i32
264; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP0]], i32 [[IDXPROM2]]
265; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP1]], i32 2
266; CHECK-NEXT:    [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX0]] to i32
267; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr [[STRUCT_VEC]], ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM3]], i32 0, i32 0
268; CHECK-NEXT:    [[IDXPROM5:%.*]] = trunc i64 [[IN_IDX2]] to i32
269; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP3]], i32 [[IDXPROM5]]
270; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP4]], i32 4
271; CHECK-NEXT:    [[IDXPROM6:%.*]] = trunc i64 [[IN_IDX0]] to i32
272; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr [[STRUCT_VEC]], ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM6]], i32 0, i32 0
273; CHECK-NEXT:    [[IDXPROM8:%.*]] = trunc i64 [[IN_IDX2]] to i32
274; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP6]], i32 [[IDXPROM8]]
275; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP7]], i32 6
276; CHECK-NEXT:    ret void
277;
278entry:
279  %const1 = getelementptr %struct.vec, ptr addrspace(3) %in.ptr, i64 %in.idx0, i32 0, i32 2
280  %idx1 = getelementptr i8, ptr addrspace(3) %const1, i64 %in.idx2
281  %const2 = getelementptr %struct.vec, ptr addrspace(3) %in.ptr, i64 %in.idx0, i32 0, i32 4
282  %idx2 = getelementptr i8, ptr addrspace(3) %const2, i64 %in.idx2
283  %const3 = getelementptr %struct.vec, ptr addrspace(3) %in.ptr, i64 %in.idx0, i32 0, i32 6
284  %idx3 = getelementptr i8, ptr addrspace(3) %const3, i64 %in.idx2
285  ret void
286}
287
288define void @multiple_index_maybe_neg(ptr %in.ptr, i64 %in.idx1) {
289; CHECK-LABEL: define void @multiple_index_maybe_neg(
290; CHECK-SAME: ptr [[IN_PTR:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
291; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr [2 x <2 x i8>], ptr [[IN_PTR]], i64 0, i64 [[IN_IDX1]]
292; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr [2 x <2 x i8>], ptr [[TMP1]], i64 0, i64 1
293; CHECK-NEXT:    ret void
294;
295  %const1 = getelementptr inbounds [2 x <2 x i8>], ptr %in.ptr, i64 0, i64 1
296  %idx1 = getelementptr inbounds [2 x <2 x i8>], ptr %const1, i64 0, i64 %in.idx1
297  ret void
298}
299
300define void @multiple_index_nonneg(ptr %in.ptr, i64 %in.idx1) {
301; CHECK-LABEL: define void @multiple_index_nonneg(
302; CHECK-SAME: ptr [[IN_PTR:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
303; CHECK-NEXT:    [[IN_IDX1_NNEG:%.*]] = and i64 [[IN_IDX1]], 9223372036854775807
304; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [2 x <2 x i8>], ptr [[IN_PTR]], i64 0, i64 [[IN_IDX1_NNEG]]
305; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds [2 x <2 x i8>], ptr [[TMP1]], i64 0, i64 1
306; CHECK-NEXT:    ret void
307;
308  %in.idx1.nneg = and i64 %in.idx1, 9223372036854775807
309  %const1 = getelementptr inbounds [2 x <2 x i8>], ptr %in.ptr, i64 0, i64 1
310  %idx1 = getelementptr inbounds [2 x <2 x i8>], ptr %const1, i64 0, i64 %in.idx1.nneg
311  ret void
312}
313