]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CodeGen/WebAssembly/address-offsets.ll
Vendor import of llvm trunk r338150:
[FreeBSD/FreeBSD.git] / test / CodeGen / WebAssembly / address-offsets.ll
1 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
2
3 ; Test folding constant offsets and symbols into load and store addresses under
4 ; a variety of circumstances.
5
6 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
7 target triple = "wasm32-unknown-unknown"
8
9 @g = external global [0 x i32], align 4
10
11 ; CHECK-LABEL: load_test0:
12 ; CHECK-NEXT: result    i32{{$}}
13 ; CHECK-NEXT: i32.const $push0=, 0{{$}}
14 ; CHECK-NEXT: i32.load  $push1=, g+40($pop0){{$}}
15 ; CHECK-NEXT: return    $pop1{{$}}
16 define i32 @load_test0() {
17   %t = load i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), align 4
18   ret i32 %t
19 }
20
21 ; CHECK-LABEL: load_test0_noinbounds:
22 ; CHECK-NEXT: result    i32{{$}}
23 ; CHECK-NEXT: i32.const $push0=, 0{{$}}
24 ; CHECK-NEXT: i32.load  $push1=, g+40($pop0){{$}}
25 ; CHECK-NEXT: return    $pop1{{$}}
26 define i32 @load_test0_noinbounds() {
27   %t = load i32, i32* getelementptr ([0 x i32], [0 x i32]* @g, i32 0, i32 10), align 4
28   ret i32 %t
29 }
30
31 ; TODO: load_test1 - load_test8 are disabled because folding GA+reg is disabled
32 ; (there are cases where the value in the reg can be negative).
33 ; Likewise for stores.
34
35 ; CHECK-LABEL: load_test1:
36 ; CHECK-NEXT: param     i32{{$}}
37 ; CHECK-NEXT: result    i32{{$}}
38 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
39 ; CHECK-NEX T: i32.shl   $push1=, $0, $pop0{{$}}
40 ; CHECK-NEX T: i32.load  $push2=, g+40($pop1){{$}}
41 ; CHECK-NEX T: return    $pop2{{$}}
42 define i32 @load_test1(i32 %n) {
43   %add = add nsw i32 %n, 10
44   %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
45   %t = load i32, i32* %arrayidx, align 4
46   ret i32 %t
47 }
48
49 ; CHECK-LABEL: load_test2:
50 ; CHECK-NEXT: param     i32{{$}}
51 ; CHECK-NEXT: result    i32{{$}}
52 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
53 ; CHECK-NEX T: i32.shl   $push1=, $0, $pop0{{$}}
54 ; CHECK-NEX T: i32.load  $push2=, g+40($pop1){{$}}
55 ; CHECK-NEX T: return    $pop2{{$}}
56 define i32 @load_test2(i32 %n) {
57   %add = add nsw i32 10, %n
58   %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
59   %t = load i32, i32* %arrayidx, align 4
60   ret i32 %t
61 }
62
63 ; CHECK-LABEL: load_test3:
64 ; CHECK-NEXT: param     i32{{$}}
65 ; CHECK-NEXT: result    i32{{$}}
66 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
67 ; CHECK-NEX T: i32.shl   $push1=, $0, $pop0{{$}}
68 ; CHECK-NEX T: i32.load  $push2=, g+40($pop1){{$}}
69 ; CHECK-NEX T: return    $pop2{{$}}
70 define i32 @load_test3(i32 %n) {
71   %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %n
72   %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10
73   %t = load i32, i32* %add.ptr1, align 4
74   ret i32 %t
75 }
76
77 ; CHECK-LABEL: load_test4:
78 ; CHECK-NEXT: param     i32{{$}}
79 ; CHECK-NEXT: result    i32{{$}}
80 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
81 ; CHECK-NEX T: i32.shl   $push1=, $0, $pop0{{$}}
82 ; CHECK-NEX T: i32.load  $push2=, g+40($pop1){{$}}
83 ; CHECK-NEX T: return    $pop2{{$}}
84 define i32 @load_test4(i32 %n) {
85   %add.ptr = getelementptr inbounds i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), i32 %n
86   %t = load i32, i32* %add.ptr, align 4
87   ret i32 %t
88 }
89
90 ; CHECK-LABEL: load_test5:
91 ; CHECK-NEXT: param     i32{{$}}
92 ; CHECK-NEXT: result    i32{{$}}
93 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
94 ; CHECK-NEX T: i32.shl   $push1=, $0, $pop0{{$}}
95 ; CHECK-NEX T: i32.load  $push2=, g+40($pop1){{$}}
96 ; CHECK-NEX T: return    $pop2{{$}}
97 define i32 @load_test5(i32 %n) {
98   %add.ptr = getelementptr inbounds i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), i32 %n
99   %t = load i32, i32* %add.ptr, align 4
100   ret i32 %t
101 }
102
103 ; CHECK-LABEL: load_test6:
104 ; CHECK-NEXT: param     i32{{$}}
105 ; CHECK-NEXT: result    i32{{$}}
106 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
107 ; CHECK-NEX T: i32.shl   $push1=, $0, $pop0{{$}}
108 ; CHECK-NEX T: i32.load  $push2=, g+40($pop1){{$}}
109 ; CHECK-NEX T: return    $pop2{{$}}
110 define i32 @load_test6(i32 %n) {
111   %add = add nsw i32 %n, 10
112   %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
113   %t = load i32, i32* %add.ptr, align 4
114   ret i32 %t
115 }
116
117 ; CHECK-LABEL: load_test7:
118 ; CHECK-NEXT: param     i32{{$}}
119 ; CHECK-NEXT: result    i32{{$}}
120 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
121 ; CHECK-NEX T: i32.shl   $push1=, $0, $pop0{{$}}
122 ; CHECK-NEX T: i32.load  $push2=, g+40($pop1){{$}}
123 ; CHECK-NEX T: return    $pop2{{$}}
124 define i32 @load_test7(i32 %n) {
125   %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %n
126   %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10
127   %t = load i32, i32* %add.ptr1, align 4
128   ret i32 %t
129 }
130
131 ; CHECK-LABEL: load_test8:
132 ; CHECK-NEXT: param     i32{{$}}
133 ; CHECK-NEXT: result    i32{{$}}
134 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
135 ; CHECK-NEX T: i32.shl   $push1=, $0, $pop0{{$}}
136 ; CHECK-NEX T: i32.load  $push2=, g+40($pop1){{$}}
137 ; CHECK-NEX T: return    $pop2{{$}}
138 define i32 @load_test8(i32 %n) {
139   %add = add nsw i32 10, %n
140   %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
141   %t = load i32, i32* %add.ptr, align 4
142   ret i32 %t
143 }
144
145 ; CHECK-LABEL: load_test9:
146 ; CHECK-NEXT: result    i32{{$}}
147 ; CHECK-NEXT: i32.const $push0=, 0{{$}}
148 ; CHECK-NEXT: i32.load  $push1=, g-40($pop0){{$}}
149 ; CHECK-NEXT: return    $pop1{{$}}
150 define i32 @load_test9() {
151   %t = load i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 1073741814), align 4
152   ret i32 %t
153 }
154
155 ; CHECK-LABEL: load_test10:
156 ; CHECK-NEXT: param     i32{{$}}
157 ; CHECK-NEXT: result    i32{{$}}
158 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
159 ; CHECK-NEXT: i32.shl   $push1=, $0, $pop0{{$}}
160 ; CHECK-NEXT: i32.const $push2=, g-40{{$}}
161 ; CHECK-NEXT: i32.add   $push3=, $pop1, $pop2{{$}}
162 ; CHECK-NEXT: i32.load  $push4=, 0($pop3){{$}}
163 ; CHECK-NEXT: return    $pop4{{$}}
164 define i32 @load_test10(i32 %n) {
165   %add = add nsw i32 %n, -10
166   %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
167   %t = load i32, i32* %arrayidx, align 4
168   ret i32 %t
169 }
170
171 ; CHECK-LABEL: load_test11:
172 ; CHECK-NEXT: param     i32{{$}}
173 ; CHECK-NEXT: result    i32{{$}}
174 ; CHECK-NEXT: i32.load  $push0=, 40($0){{$}}
175 ; CHECK-NEXT: return    $pop0{{$}}
176 define i32 @load_test11(i32* %p) {
177   %arrayidx = getelementptr inbounds i32, i32* %p, i32 10
178   %t = load i32, i32* %arrayidx, align 4
179   ret i32 %t
180 }
181
182 ; CHECK-LABEL: load_test11_noinbounds:
183 ; CHECK-NEXT: param     i32{{$}}
184 ; CHECK-NEXT: result    i32{{$}}
185 ; CHECK-NEXT: i32.const $push0=, 40{{$}}
186 ; CHECK-NEXT: i32.add   $push1=, $0, $pop0{{$}}
187 ; CHECK-NEXT: i32.load  $push2=, 0($pop1){{$}}
188 ; CHECK-NEXT: return    $pop2{{$}}
189 define i32 @load_test11_noinbounds(i32* %p) {
190   %arrayidx = getelementptr i32, i32* %p, i32 10
191   %t = load i32, i32* %arrayidx, align 4
192   ret i32 %t
193 }
194
195 ; CHECK-LABEL: load_test12:
196 ; CHECK-NEXT: param     i32, i32{{$}}
197 ; CHECK-NEXT: result    i32{{$}}
198 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
199 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
200 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
201 ; CHECK-NEXT: i32.const $push3=, 40{{$}}
202 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
203 ; CHECK-NEXT: i32.load  $push5=, 0($pop4){{$}}
204 ; CHECK-NEXT: return    $pop5{{$}}
205 define i32 @load_test12(i32* %p, i32 %n) {
206   %add = add nsw i32 %n, 10
207   %arrayidx = getelementptr inbounds i32, i32* %p, i32 %add
208   %t = load i32, i32* %arrayidx, align 4
209   ret i32 %t
210 }
211
212 ; CHECK-LABEL: load_test13:
213 ; CHECK-NEXT: param     i32, i32{{$}}
214 ; CHECK-NEXT: result    i32{{$}}
215 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
216 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
217 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
218 ; CHECK-NEXT: i32.const $push3=, 40{{$}}
219 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
220 ; CHECK-NEXT: i32.load  $push5=, 0($pop4){{$}}
221 ; CHECK-NEXT: return    $pop5{{$}}
222 define i32 @load_test13(i32* %p, i32 %n) {
223   %add = add nsw i32 10, %n
224   %arrayidx = getelementptr inbounds i32, i32* %p, i32 %add
225   %t = load i32, i32* %arrayidx, align 4
226   ret i32 %t
227 }
228
229 ; CHECK-LABEL: load_test14:
230 ; CHECK-NEXT: param     i32, i32{{$}}
231 ; CHECK-NEXT: result    i32{{$}}
232 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
233 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
234 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
235 ; CHECK-NEXT: i32.load  $push3=, 40($pop2){{$}}
236 ; CHECK-NEXT: return    $pop3{{$}}
237 define i32 @load_test14(i32* %p, i32 %n) {
238   %add.ptr = getelementptr inbounds i32, i32* %p, i32 %n
239   %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10
240   %t = load i32, i32* %add.ptr1, align 4
241   ret i32 %t
242 }
243
244 ; CHECK-LABEL: load_test15:
245 ; CHECK-NEXT: param     i32, i32{{$}}
246 ; CHECK-NEXT: result    i32{{$}}
247 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
248 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
249 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
250 ; CHECK-NEXT: i32.const $push3=, 40{{$}}
251 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
252 ; CHECK-NEXT: i32.load  $push5=, 0($pop4){{$}}
253 ; CHECK-NEXT: return    $pop5{{$}}
254 define i32 @load_test15(i32* %p, i32 %n) {
255   %add.ptr = getelementptr inbounds i32, i32* %p, i32 10
256   %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 %n
257   %t = load i32, i32* %add.ptr1, align 4
258   ret i32 %t
259 }
260
261 ; CHECK-LABEL: load_test16:
262 ; CHECK-NEXT: param     i32, i32{{$}}
263 ; CHECK-NEXT: result    i32{{$}}
264 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
265 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
266 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
267 ; CHECK-NEXT: i32.const $push3=, 40{{$}}
268 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
269 ; CHECK-NEXT: i32.load  $push5=, 0($pop4){{$}}
270 ; CHECK-NEXT: return    $pop5{{$}}
271 define i32 @load_test16(i32* %p, i32 %n) {
272   %add.ptr = getelementptr inbounds i32, i32* %p, i32 10
273   %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 %n
274   %t = load i32, i32* %add.ptr1, align 4
275   ret i32 %t
276 }
277
278 ; CHECK-LABEL: load_test17:
279 ; CHECK-NEXT: param     i32, i32{{$}}
280 ; CHECK-NEXT: result    i32{{$}}
281 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
282 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
283 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
284 ; CHECK-NEXT: i32.const $push3=, 40{{$}}
285 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
286 ; CHECK-NEXT: i32.load  $push5=, 0($pop4){{$}}
287 ; CHECK-NEXT: return    $pop5{{$}}
288 define i32 @load_test17(i32* %p, i32 %n) {
289   %add = add nsw i32 %n, 10
290   %add.ptr = getelementptr inbounds i32, i32* %p, i32 %add
291   %t = load i32, i32* %add.ptr, align 4
292   ret i32 %t
293 }
294
295 ; CHECK-LABEL: load_test18:
296 ; CHECK-NEXT: param     i32, i32{{$}}
297 ; CHECK-NEXT: result    i32{{$}}
298 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
299 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
300 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
301 ; CHECK-NEXT: i32.load  $push3=, 40($pop2){{$}}
302 ; CHECK-NEXT: return    $pop3{{$}}
303 define i32 @load_test18(i32* %p, i32 %n) {
304   %add.ptr = getelementptr inbounds i32, i32* %p, i32 %n
305   %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10
306   %t = load i32, i32* %add.ptr1, align 4
307   ret i32 %t
308 }
309
310 ; CHECK-LABEL: load_test19:
311 ; CHECK-NEXT: param     i32, i32{{$}}
312 ; CHECK-NEXT: result    i32{{$}}
313 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
314 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
315 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
316 ; CHECK-NEXT: i32.const $push3=, 40{{$}}
317 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
318 ; CHECK-NEXT: i32.load  $push5=, 0($pop4){{$}}
319 ; CHECK-NEXT: return    $pop5{{$}}
320 define i32 @load_test19(i32* %p, i32 %n) {
321   %add = add nsw i32 10, %n
322   %add.ptr = getelementptr inbounds i32, i32* %p, i32 %add
323   %t = load i32, i32* %add.ptr, align 4
324   ret i32 %t
325 }
326
327 ; CHECK-LABEL: load_test20:
328 ; CHECK-NEXT: param     i32{{$}}
329 ; CHECK-NEXT: result    i32{{$}}
330 ; CHECK-NEXT: i32.const $push0=, -40{{$}}
331 ; CHECK-NEXT: i32.add   $push1=, $0, $pop0{{$}}
332 ; CHECK-NEXT: i32.load  $push2=, 0($pop1){{$}}
333 ; CHECK-NEXT: return    $pop2{{$}}
334 define i32 @load_test20(i32* %p) {
335   %arrayidx = getelementptr inbounds i32, i32* %p, i32 -10
336   %t = load i32, i32* %arrayidx, align 4
337   ret i32 %t
338 }
339
340 ; CHECK-LABEL: load_test21:
341 ; CHECK-NEXT: param     i32, i32{{$}}
342 ; CHECK-NEXT: result    i32{{$}}
343 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
344 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
345 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
346 ; CHECK-NEXT: i32.const $push3=, -40{{$}}
347 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
348 ; CHECK-NEXT: i32.load  $push5=, 0($pop4){{$}}
349 ; CHECK-NEXT: return    $pop5{{$}}
350 define i32 @load_test21(i32* %p, i32 %n) {
351   %add = add nsw i32 %n, -10
352   %arrayidx = getelementptr inbounds i32, i32* %p, i32 %add
353   %t = load i32, i32* %arrayidx, align 4
354   ret i32 %t
355 }
356
357 ; CHECK-LABEL: store_test0:
358 ; CHECK-NEXT: param     i32{{$}}
359 ; CHECK-NEXT: i32.const $push0=, 0{{$}}
360 ; CHECK-NEXT: i32.store g+40($pop0), $0{{$}}
361 ; CHECK-NEXT: return{{$}}
362 define void @store_test0(i32 %i) {
363   store i32 %i, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), align 4
364   ret void
365 }
366
367 ; CHECK-LABEL: store_test0_noinbounds:
368 ; CHECK-NEXT: param     i32{{$}}
369 ; CHECK-NEXT: i32.const $push0=, 0{{$}}
370 ; CHECK-NEXT: i32.store g+40($pop0), $0{{$}}
371 ; CHECK-NEXT: return{{$}}
372 define void @store_test0_noinbounds(i32 %i) {
373   store i32 %i, i32* getelementptr ([0 x i32], [0 x i32]* @g, i32 0, i32 10), align 4
374   ret void
375 }
376
377 ; CHECK-LABEL: store_test1:
378 ; CHECK-NEXT: param     i32, i32{{$}}
379 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
380 ; CHECK-NEXT: i32.shl   $push1=, $0, $pop0{{$}}
381 ; CHECK-NEX T: i32.store g+40($pop1), $1{{$}}
382 ; CHECK-NEX T: return{{$}}
383 define void @store_test1(i32 %n, i32 %i) {
384   %add = add nsw i32 %n, 10
385   %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
386   store i32 %i, i32* %arrayidx, align 4
387   ret void
388 }
389
390 ; CHECK-LABEL: store_test2:
391 ; CHECK-NEXT: param     i32, i32{{$}}
392 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
393 ; CHECK-NEXT: i32.shl   $push1=, $0, $pop0{{$}}
394 ; CHECK-NEX T: i32.store g+40($pop1), $1{{$}}
395 ; CHECK-NEX T: return{{$}}
396 define void @store_test2(i32 %n, i32 %i) {
397   %add = add nsw i32 10, %n
398   %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
399   store i32 %i, i32* %arrayidx, align 4
400   ret void
401 }
402
403 ; CHECK-LABEL: store_test3:
404 ; CHECK-NEXT: param     i32, i32{{$}}
405 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
406 ; CHECK-NEXT: i32.shl   $push1=, $0, $pop0{{$}}
407 ; CHECK-NEX T: i32.store g+40($pop1), $1{{$}}
408 ; CHECK-NEX T: return{{$}}
409 define void @store_test3(i32 %n, i32 %i) {
410   %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %n
411   %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10
412   store i32 %i, i32* %add.ptr1, align 4
413   ret void
414 }
415
416 ; CHECK-LABEL: store_test4:
417 ; CHECK-NEXT: param     i32, i32{{$}}
418 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
419 ; CHECK-NEXT: i32.shl   $push1=, $0, $pop0{{$}}
420 ; CHECK-NEX T: i32.store g+40($pop1), $1{{$}}
421 ; CHECK-NEX T: return{{$}}
422 define void @store_test4(i32 %n, i32 %i) {
423   %add.ptr = getelementptr inbounds i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), i32 %n
424   store i32 %i, i32* %add.ptr, align 4
425   ret void
426 }
427
428 ; CHECK-LABEL: store_test5:
429 ; CHECK-NEXT: param     i32, i32{{$}}
430 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
431 ; CHECK-NEXT: i32.shl   $push1=, $0, $pop0{{$}}
432 ; CHECK-NEX T: i32.store g+40($pop1), $1{{$}}
433 ; CHECK-NEX T: return{{$}}
434 define void @store_test5(i32 %n, i32 %i) {
435   %add.ptr = getelementptr inbounds i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), i32 %n
436   store i32 %i, i32* %add.ptr, align 4
437   ret void
438 }
439
440 ; CHECK-LABEL: store_test6:
441 ; CHECK-NEXT: param     i32, i32{{$}}
442 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
443 ; CHECK-NEXT: i32.shl   $push1=, $0, $pop0{{$}}
444 ; CHECK-NEX T: i32.store g+40($pop1), $1{{$}}
445 ; CHECK-NEX T: return{{$}}
446 define void @store_test6(i32 %n, i32 %i) {
447   %add = add nsw i32 %n, 10
448   %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
449   store i32 %i, i32* %add.ptr, align 4
450   ret void
451 }
452
453 ; CHECK-LABEL: store_test7:
454 ; CHECK-NEXT: param     i32, i32{{$}}
455 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
456 ; CHECK-NEXT: i32.shl   $push1=, $0, $pop0{{$}}
457 ; CHECK-NEX T: i32.store g+40($pop1), $1{{$}}
458 ; CHECK-NEX T: return{{$}}
459 define void @store_test7(i32 %n, i32 %i) {
460   %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %n
461   %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10
462   store i32 %i, i32* %add.ptr1, align 4
463   ret void
464 }
465
466 ; CHECK-LABEL: store_test8:
467 ; CHECK-NEXT: param     i32, i32{{$}}
468 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
469 ; CHECK-NEXT: i32.shl   $push1=, $0, $pop0{{$}}
470 ; CHECK-NEX T: i32.store g+40($pop1), $1{{$}}
471 ; CHECK-NEX T: return{{$}}
472 define void @store_test8(i32 %n, i32 %i) {
473   %add = add nsw i32 10, %n
474   %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
475   store i32 %i, i32* %add.ptr, align 4
476   ret void
477 }
478
479 ; CHECK-LABEL: store_test9:
480 ; CHECK-NEXT: param     i32{{$}}
481 ; CHECK-NEXT: i32.const $push0=, 0{{$}}
482 ; CHECK-NEXT: i32.store g-40($pop0), $0{{$}}
483 ; CHECK-NEXT: return{{$}}
484 define void @store_test9(i32 %i) {
485   store i32 %i, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 1073741814), align 4
486   ret void
487 }
488
489 ; CHECK-LABEL: store_test10:
490 ; CHECK-NEXT: param     i32, i32{{$}}
491 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
492 ; CHECK-NEXT: i32.shl   $push1=, $0, $pop0{{$}}
493 ; CHECK-NEXT: i32.const $push2=, g-40{{$}}
494 ; CHECK-NEXT: i32.add   $push3=, $pop1, $pop2{{$}}
495 ; CHECK-NEXT: i32.store 0($pop3), $1{{$}}
496 ; CHECK-NEXT: return{{$}}
497 define void @store_test10(i32 %n, i32 %i) {
498   %add = add nsw i32 %n, -10
499   %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
500   store i32 %i, i32* %arrayidx, align 4
501   ret void
502 }
503
504 ; CHECK-LABEL: store_test11:
505 ; CHECK-NEXT: param     i32, i32{{$}}
506 ; CHECK-NEXT: i32.store 40($0), $1{{$}}
507 ; CHECK-NEXT: return{{$}}
508 define void @store_test11(i32* %p, i32 %i) {
509   %arrayidx = getelementptr inbounds i32, i32* %p, i32 10
510   store i32 %i, i32* %arrayidx, align 4
511   ret void
512 }
513
514 ; CHECK-LABEL: store_test11_noinbounds:
515 ; CHECK-NEXT: param     i32, i32{{$}}
516 ; CHECK-NEXT: i32.const $push0=, 40{{$}}
517 ; CHECK-NEXT: i32.add   $push1=, $0, $pop0{{$}}
518 ; CHECK-NEXT: i32.store 0($pop1), $1{{$}}
519 ; CHECK-NEXT: return{{$}}
520 define void @store_test11_noinbounds(i32* %p, i32 %i) {
521   %arrayidx = getelementptr i32, i32* %p, i32 10
522   store i32 %i, i32* %arrayidx, align 4
523   ret void
524 }
525
526 ; CHECK-LABEL: store_test12:
527 ; CHECK-NEXT: param     i32, i32, i32{{$}}
528 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
529 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
530 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
531 ; CHECK-NEXT: i32.const $push3=, 40{{$}}
532 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
533 ; CHECK-NEXT: i32.store 0($pop4), $2{{$}}
534 ; CHECK-NEXT: return{{$}}
535 define void @store_test12(i32* %p, i32 %n, i32 %i) {
536   %add = add nsw i32 %n, 10
537   %arrayidx = getelementptr inbounds i32, i32* %p, i32 %add
538   store i32 %i, i32* %arrayidx, align 4
539   ret void
540 }
541
542 ; CHECK-LABEL: store_test13:
543 ; CHECK-NEXT: param     i32, i32, i32{{$}}
544 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
545 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
546 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
547 ; CHECK-NEXT: i32.const $push3=, 40{{$}}
548 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
549 ; CHECK-NEXT: i32.store 0($pop4), $2{{$}}
550 ; CHECK-NEXT: return{{$}}
551 define void @store_test13(i32* %p, i32 %n, i32 %i) {
552   %add = add nsw i32 10, %n
553   %arrayidx = getelementptr inbounds i32, i32* %p, i32 %add
554   store i32 %i, i32* %arrayidx, align 4
555   ret void
556 }
557
558 ; CHECK-LABEL: store_test14:
559 ; CHECK-NEXT: param     i32, i32, i32{{$}}
560 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
561 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
562 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
563 ; CHECK-NEXT: i32.store 40($pop2), $2{{$}}
564 ; CHECK-NEXT: return{{$}}
565 define void @store_test14(i32* %p, i32 %n, i32 %i) {
566   %add.ptr = getelementptr inbounds i32, i32* %p, i32 %n
567   %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10
568   store i32 %i, i32* %add.ptr1, align 4
569   ret void
570 }
571
572 ; CHECK-LABEL: store_test15:
573 ; CHECK-NEXT: param     i32, i32, i32{{$}}
574 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
575 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
576 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
577 ; CHECK-NEXT: i32.const $push3=, 40{{$}}
578 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
579 ; CHECK-NEXT: i32.store 0($pop4), $2{{$}}
580 ; CHECK-NEXT: return{{$}}
581 define void @store_test15(i32* %p, i32 %n, i32 %i) {
582   %add.ptr = getelementptr inbounds i32, i32* %p, i32 10
583   %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 %n
584   store i32 %i, i32* %add.ptr1, align 4
585   ret void
586 }
587
588 ; CHECK-LABEL: store_test16:
589 ; CHECK-NEXT: param     i32, i32, i32{{$}}
590 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
591 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
592 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
593 ; CHECK-NEXT: i32.const $push3=, 40{{$}}
594 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
595 ; CHECK-NEXT: i32.store 0($pop4), $2{{$}}
596 ; CHECK-NEXT: return{{$}}
597 define void @store_test16(i32* %p, i32 %n, i32 %i) {
598   %add.ptr = getelementptr inbounds i32, i32* %p, i32 10
599   %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 %n
600   store i32 %i, i32* %add.ptr1, align 4
601   ret void
602 }
603
604 ; CHECK-LABEL: store_test17:
605 ; CHECK-NEXT: param     i32, i32, i32{{$}}
606 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
607 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
608 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
609 ; CHECK-NEXT: i32.const $push3=, 40{{$}}
610 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
611 ; CHECK-NEXT: i32.store 0($pop4), $2{{$}}
612 ; CHECK-NEXT: return{{$}}
613 define void @store_test17(i32* %p, i32 %n, i32 %i) {
614   %add = add nsw i32 %n, 10
615   %add.ptr = getelementptr inbounds i32, i32* %p, i32 %add
616   store i32 %i, i32* %add.ptr, align 4
617   ret void
618 }
619
620 ; CHECK-LABEL: store_test18:
621 ; CHECK-NEXT: param     i32, i32, i32{{$}}
622 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
623 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
624 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
625 ; CHECK-NEXT: i32.store 40($pop2), $2{{$}}
626 ; CHECK-NEXT: return{{$}}
627 define void @store_test18(i32* %p, i32 %n, i32 %i) {
628   %add.ptr = getelementptr inbounds i32, i32* %p, i32 %n
629   %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10
630   store i32 %i, i32* %add.ptr1, align 4
631   ret void
632 }
633
634 ; CHECK-LABEL: store_test19:
635 ; CHECK-NEXT: param     i32, i32, i32{{$}}
636 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
637 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
638 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
639 ; CHECK-NEXT: i32.const $push3=, 40{{$}}
640 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
641 ; CHECK-NEXT: i32.store 0($pop4), $2{{$}}
642 ; CHECK-NEXT: return{{$}}
643 define void @store_test19(i32* %p, i32 %n, i32 %i) {
644   %add = add nsw i32 10, %n
645   %add.ptr = getelementptr inbounds i32, i32* %p, i32 %add
646   store i32 %i, i32* %add.ptr, align 4
647   ret void
648 }
649
650 ; CHECK-LABEL: store_test20:
651 ; CHECK-NEXT: param     i32, i32{{$}}
652 ; CHECK-NEXT: i32.const $push0=, -40{{$}}
653 ; CHECK-NEXT: i32.add   $push1=, $0, $pop0{{$}}
654 ; CHECK-NEXT: i32.store 0($pop1), $1{{$}}
655 ; CHECK-NEXT: return{{$}}
656 define void @store_test20(i32* %p, i32 %i) {
657   %arrayidx = getelementptr inbounds i32, i32* %p, i32 -10
658   store i32 %i, i32* %arrayidx, align 4
659   ret void
660 }
661
662 ; CHECK-LABEL: store_test21:
663 ; CHECK-NEXT: param     i32, i32, i32{{$}}
664 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
665 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
666 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
667 ; CHECK-NEXT: i32.const $push3=, -40{{$}}
668 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
669 ; CHECK-NEXT: i32.store 0($pop4), $2{{$}}
670 ; CHECK-NEXT: return{{$}}
671 define void @store_test21(i32* %p, i32 %n, i32 %i) {
672   %add = add nsw i32 %n, -10
673   %arrayidx = getelementptr inbounds i32, i32* %p, i32 %add
674   store i32 %i, i32* %arrayidx, align 4
675   ret void
676 }