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