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