• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
6target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
7target 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{{$}}
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: result    i32{{$}}
23; CHECK-NEXT: i32.const $push0=, 0{{$}}
24; CHECK-NEXT: i32.load  $push1=, g+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: 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{{$}}
42define 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{{$}}
56define 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{{$}}
70define 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{{$}}
84define 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{{$}}
97define 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{{$}}
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: 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{{$}}
124define 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{{$}}
138define 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{{$}}
150define 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{{$}}
164define 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{{$}}
176define 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{{$}}
189define 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{{$}}
205define 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{{$}}
222define 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{{$}}
237define 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{{$}}
254define 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{{$}}
271define 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{{$}}
288define 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{{$}}
303define 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{{$}}
320define 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{{$}}
334define 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{{$}}
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: param     i32{{$}}
359; CHECK-NEXT: i32.const $push0=, 0{{$}}
360; CHECK-NEXT: i32.store g+40($pop0), $0{{$}}
361; CHECK-NEXT: return{{$}}
362define 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{{$}}
372define 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{{$}}
383define 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{{$}}
396define 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{{$}}
409define 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{{$}}
422define 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{{$}}
434define 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{{$}}
446define 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{{$}}
459define 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{{$}}
472define 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{{$}}
484define 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{{$}}
497define 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{{$}}
508define 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{{$}}
520define 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{{$}}
535define 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{{$}}
551define 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{{$}}
565define 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{{$}}
581define 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{{$}}
597define 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{{$}}
613define 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{{$}}
627define 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{{$}}
643define 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{{$}}
656define 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{{$}}
671define 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}
677