1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -verify-machineinstrs -mattr=+simd128 | FileCheck %s
3
4; Test SIMD v128.load{8,16,32,64}_lane instructions.
5
6; TODO: Use the offset field by supporting more patterns. Right now only the
7; equivalents of LoadPatNoOffset/StorePatNoOffset are supported.
8
9target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
10target triple = "wasm32-unknown-unknown"
11
12declare <16 x i8> @llvm.wasm.load8.lane(i8*, <16 x i8>, i32)
13declare <8 x i16> @llvm.wasm.load16.lane(i16*, <8 x i16>, i32)
14declare <4 x i32> @llvm.wasm.load32.lane(i32*, <4 x i32>, i32)
15declare <2 x i64> @llvm.wasm.load64.lane(i64*, <2 x i64>, i32)
16
17declare void @llvm.wasm.store8.lane(i8*, <16 x i8>, i32)
18declare void @llvm.wasm.store16.lane(i16*, <8 x i16>, i32)
19declare void @llvm.wasm.store32.lane(i32*, <4 x i32>, i32)
20declare void @llvm.wasm.store64.lane(i64*, <2 x i64>, i32)
21
22;===----------------------------------------------------------------------------
23; v128.load8_lane / v128.store8_lane
24;===----------------------------------------------------------------------------
25
26define <16 x i8> @load_lane_i8_no_offset(i8* %p, <16 x i8> %v) {
27; CHECK-LABEL: load_lane_i8_no_offset:
28; CHECK:         .functype load_lane_i8_no_offset (i32, v128) -> (v128)
29; CHECK-NEXT:  # %bb.0:
30; CHECK-NEXT:    local.get 0
31; CHECK-NEXT:    local.get 1
32; CHECK-NEXT:    v128.load8_lane 0, 0
33; CHECK-NEXT:    # fallthrough-return
34  %t = tail call <16 x i8> @llvm.wasm.load8.lane(i8* %p, <16 x i8> %v, i32 0)
35  ret <16 x i8> %t
36}
37
38define <16 x i8> @load_lane_i8_with_folded_offset(i8* %p, <16 x i8> %v) {
39; CHECK-LABEL: load_lane_i8_with_folded_offset:
40; CHECK:         .functype load_lane_i8_with_folded_offset (i32, v128) -> (v128)
41; CHECK-NEXT:  # %bb.0:
42; CHECK-NEXT:    local.get 0
43; CHECK-NEXT:    i32.const 24
44; CHECK-NEXT:    i32.add
45; CHECK-NEXT:    local.get 1
46; CHECK-NEXT:    v128.load8_lane 0, 0
47; CHECK-NEXT:    # fallthrough-return
48  %q = ptrtoint i8* %p to i32
49  %r = add nuw i32 %q, 24
50  %s = inttoptr i32 %r to i8*
51  %t = tail call <16 x i8> @llvm.wasm.load8.lane(i8* %s, <16 x i8> %v, i32 0)
52  ret <16 x i8> %t
53}
54
55define <16 x i8> @load_lane_i8_with_folded_gep_offset(i8* %p, <16 x i8> %v) {
56; CHECK-LABEL: load_lane_i8_with_folded_gep_offset:
57; CHECK:         .functype load_lane_i8_with_folded_gep_offset (i32, v128) -> (v128)
58; CHECK-NEXT:  # %bb.0:
59; CHECK-NEXT:    local.get 0
60; CHECK-NEXT:    i32.const 6
61; CHECK-NEXT:    i32.add
62; CHECK-NEXT:    local.get 1
63; CHECK-NEXT:    v128.load8_lane 0, 0
64; CHECK-NEXT:    # fallthrough-return
65  %s = getelementptr inbounds i8, i8* %p, i32 6
66  %t = tail call <16 x i8> @llvm.wasm.load8.lane(i8* %s, <16 x i8> %v, i32 0)
67  ret <16 x i8> %t
68}
69
70define <16 x i8> @load_lane_i8_with_unfolded_gep_negative_offset(i8* %p, <16 x i8> %v) {
71; CHECK-LABEL: load_lane_i8_with_unfolded_gep_negative_offset:
72; CHECK:         .functype load_lane_i8_with_unfolded_gep_negative_offset (i32, v128) -> (v128)
73; CHECK-NEXT:  # %bb.0:
74; CHECK-NEXT:    local.get 0
75; CHECK-NEXT:    i32.const -6
76; CHECK-NEXT:    i32.add
77; CHECK-NEXT:    local.get 1
78; CHECK-NEXT:    v128.load8_lane 0, 0
79; CHECK-NEXT:    # fallthrough-return
80  %s = getelementptr inbounds i8, i8* %p, i32 -6
81  %t = tail call <16 x i8> @llvm.wasm.load8.lane(i8* %s, <16 x i8> %v, i32 0)
82  ret <16 x i8> %t
83}
84
85define <16 x i8> @load_lane_i8_with_unfolded_offset(i8* %p, <16 x i8> %v) {
86; CHECK-LABEL: load_lane_i8_with_unfolded_offset:
87; CHECK:         .functype load_lane_i8_with_unfolded_offset (i32, v128) -> (v128)
88; CHECK-NEXT:  # %bb.0:
89; CHECK-NEXT:    local.get 0
90; CHECK-NEXT:    i32.const 24
91; CHECK-NEXT:    i32.add
92; CHECK-NEXT:    local.get 1
93; CHECK-NEXT:    v128.load8_lane 0, 0
94; CHECK-NEXT:    # fallthrough-return
95  %q = ptrtoint i8* %p to i32
96  %r = add nsw i32 %q, 24
97  %s = inttoptr i32 %r to i8*
98  %t = tail call <16 x i8> @llvm.wasm.load8.lane(i8* %s, <16 x i8> %v, i32 0)
99  ret <16 x i8> %t
100}
101
102define <16 x i8> @load_lane_i8_with_unfolded_gep_offset(i8* %p, <16 x i8> %v) {
103; CHECK-LABEL: load_lane_i8_with_unfolded_gep_offset:
104; CHECK:         .functype load_lane_i8_with_unfolded_gep_offset (i32, v128) -> (v128)
105; CHECK-NEXT:  # %bb.0:
106; CHECK-NEXT:    local.get 0
107; CHECK-NEXT:    i32.const 6
108; CHECK-NEXT:    i32.add
109; CHECK-NEXT:    local.get 1
110; CHECK-NEXT:    v128.load8_lane 0, 0
111; CHECK-NEXT:    # fallthrough-return
112  %s = getelementptr i8, i8* %p, i32 6
113  %t = tail call <16 x i8> @llvm.wasm.load8.lane(i8* %s, <16 x i8> %v, i32 0)
114  ret <16 x i8> %t
115}
116
117define <16 x i8> @load_lane_i8_from_numeric_address(<16 x i8> %v) {
118; CHECK-LABEL: load_lane_i8_from_numeric_address:
119; CHECK:         .functype load_lane_i8_from_numeric_address (v128) -> (v128)
120; CHECK-NEXT:  # %bb.0:
121; CHECK-NEXT:    i32.const 42
122; CHECK-NEXT:    local.get 0
123; CHECK-NEXT:    v128.load8_lane 0, 0
124; CHECK-NEXT:    # fallthrough-return
125  %s = inttoptr i32 42 to i8*
126  %t = tail call <16 x i8> @llvm.wasm.load8.lane(i8* %s, <16 x i8> %v, i32 0)
127  ret <16 x i8> %t
128}
129
130@gv_i8 = global i8 0
131define <16 x i8> @load_lane_i8_from_global_address(<16 x i8> %v) {
132; CHECK-LABEL: load_lane_i8_from_global_address:
133; CHECK:         .functype load_lane_i8_from_global_address (v128) -> (v128)
134; CHECK-NEXT:  # %bb.0:
135; CHECK-NEXT:    i32.const gv_i8
136; CHECK-NEXT:    local.get 0
137; CHECK-NEXT:    v128.load8_lane 0, 0
138; CHECK-NEXT:    # fallthrough-return
139  %t = tail call <16 x i8> @llvm.wasm.load8.lane(i8* @gv_i8, <16 x i8> %v, i32 0)
140  ret <16 x i8> %t
141}
142
143define void @store_lane_i8_no_offset(<16 x i8> %v, i8* %p) {
144; CHECK-LABEL: store_lane_i8_no_offset:
145; CHECK:         .functype store_lane_i8_no_offset (v128, i32) -> ()
146; CHECK-NEXT:  # %bb.0:
147; CHECK-NEXT:    local.get 1
148; CHECK-NEXT:    local.get 0
149; CHECK-NEXT:    v128.store8_lane 0, 0
150; CHECK-NEXT:    # fallthrough-return
151  tail call void @llvm.wasm.store8.lane(i8* %p, <16 x i8> %v, i32 0)
152  ret void
153}
154
155define void @store_lane_i8_with_folded_offset(<16 x i8> %v, i8* %p) {
156; CHECK-LABEL: store_lane_i8_with_folded_offset:
157; CHECK:         .functype store_lane_i8_with_folded_offset (v128, i32) -> ()
158; CHECK-NEXT:  # %bb.0:
159; CHECK-NEXT:    local.get 1
160; CHECK-NEXT:    i32.const 24
161; CHECK-NEXT:    i32.add
162; CHECK-NEXT:    local.get 0
163; CHECK-NEXT:    v128.store8_lane 0, 0
164; CHECK-NEXT:    # fallthrough-return
165  %q = ptrtoint i8* %p to i32
166  %r = add nuw i32 %q, 24
167  %s = inttoptr i32 %r to i8*
168  tail call void @llvm.wasm.store8.lane(i8* %s, <16 x i8> %v, i32 0)
169  ret void
170}
171
172define void @store_lane_i8_with_folded_gep_offset(<16 x i8> %v, i8* %p) {
173; CHECK-LABEL: store_lane_i8_with_folded_gep_offset:
174; CHECK:         .functype store_lane_i8_with_folded_gep_offset (v128, i32) -> ()
175; CHECK-NEXT:  # %bb.0:
176; CHECK-NEXT:    local.get 1
177; CHECK-NEXT:    i32.const 6
178; CHECK-NEXT:    i32.add
179; CHECK-NEXT:    local.get 0
180; CHECK-NEXT:    v128.store8_lane 0, 0
181; CHECK-NEXT:    # fallthrough-return
182  %s = getelementptr inbounds i8, i8* %p, i32 6
183  tail call void @llvm.wasm.store8.lane(i8* %s, <16 x i8> %v, i32 0)
184  ret void
185}
186
187define void @store_lane_i8_with_unfolded_gep_negative_offset(<16 x i8> %v, i8* %p) {
188; CHECK-LABEL: store_lane_i8_with_unfolded_gep_negative_offset:
189; CHECK:         .functype store_lane_i8_with_unfolded_gep_negative_offset (v128, i32) -> ()
190; CHECK-NEXT:  # %bb.0:
191; CHECK-NEXT:    local.get 1
192; CHECK-NEXT:    i32.const -6
193; CHECK-NEXT:    i32.add
194; CHECK-NEXT:    local.get 0
195; CHECK-NEXT:    v128.store8_lane 0, 0
196; CHECK-NEXT:    # fallthrough-return
197  %s = getelementptr inbounds i8, i8* %p, i32 -6
198  tail call void @llvm.wasm.store8.lane(i8* %s, <16 x i8> %v, i32 0)
199  ret void
200}
201
202define void @store_lane_i8_with_unfolded_offset(<16 x i8> %v, i8* %p) {
203; CHECK-LABEL: store_lane_i8_with_unfolded_offset:
204; CHECK:         .functype store_lane_i8_with_unfolded_offset (v128, i32) -> ()
205; CHECK-NEXT:  # %bb.0:
206; CHECK-NEXT:    local.get 1
207; CHECK-NEXT:    i32.const 24
208; CHECK-NEXT:    i32.add
209; CHECK-NEXT:    local.get 0
210; CHECK-NEXT:    v128.store8_lane 0, 0
211; CHECK-NEXT:    # fallthrough-return
212  %q = ptrtoint i8* %p to i32
213  %r = add nsw i32 %q, 24
214  %s = inttoptr i32 %r to i8*
215  tail call void @llvm.wasm.store8.lane(i8* %s, <16 x i8> %v, i32 0)
216  ret void
217}
218
219define void @store_lane_i8_with_unfolded_gep_offset(<16 x i8> %v, i8* %p) {
220; CHECK-LABEL: store_lane_i8_with_unfolded_gep_offset:
221; CHECK:         .functype store_lane_i8_with_unfolded_gep_offset (v128, i32) -> ()
222; CHECK-NEXT:  # %bb.0:
223; CHECK-NEXT:    local.get 1
224; CHECK-NEXT:    i32.const 6
225; CHECK-NEXT:    i32.add
226; CHECK-NEXT:    local.get 0
227; CHECK-NEXT:    v128.store8_lane 0, 0
228; CHECK-NEXT:    # fallthrough-return
229  %s = getelementptr i8, i8* %p, i32 6
230  tail call void @llvm.wasm.store8.lane(i8* %s, <16 x i8> %v, i32 0)
231  ret void
232}
233
234define void @store_lane_i8_to_numeric_address(<16 x i8> %v) {
235; CHECK-LABEL: store_lane_i8_to_numeric_address:
236; CHECK:         .functype store_lane_i8_to_numeric_address (v128) -> ()
237; CHECK-NEXT:  # %bb.0:
238; CHECK-NEXT:    i32.const 42
239; CHECK-NEXT:    local.get 0
240; CHECK-NEXT:    v128.store8_lane 0, 0
241; CHECK-NEXT:    # fallthrough-return
242  %s = inttoptr i32 42 to i8*
243  tail call void @llvm.wasm.store8.lane(i8* %s, <16 x i8> %v, i32 0)
244  ret void
245}
246
247define void @store_lane_i8_from_global_address(<16 x i8> %v) {
248; CHECK-LABEL: store_lane_i8_from_global_address:
249; CHECK:         .functype store_lane_i8_from_global_address (v128) -> ()
250; CHECK-NEXT:  # %bb.0:
251; CHECK-NEXT:    i32.const gv_i8
252; CHECK-NEXT:    local.get 0
253; CHECK-NEXT:    v128.store8_lane 0, 0
254; CHECK-NEXT:    # fallthrough-return
255  tail call void @llvm.wasm.store8.lane(i8* @gv_i8, <16 x i8> %v, i32 0)
256  ret void
257}
258
259;===----------------------------------------------------------------------------
260; v128.load16_lane / v128.store16_lane
261;===----------------------------------------------------------------------------
262
263define <8 x i16> @load_lane_i16_no_offset(i16* %p, <8 x i16> %v) {
264; CHECK-LABEL: load_lane_i16_no_offset:
265; CHECK:         .functype load_lane_i16_no_offset (i32, v128) -> (v128)
266; CHECK-NEXT:  # %bb.0:
267; CHECK-NEXT:    local.get 0
268; CHECK-NEXT:    local.get 1
269; CHECK-NEXT:    v128.load16_lane 0:p2align=0, 0
270; CHECK-NEXT:    # fallthrough-return
271  %t = tail call <8 x i16> @llvm.wasm.load16.lane(i16* %p, <8 x i16> %v, i32 0)
272  ret <8 x i16> %t
273}
274
275define <8 x i16> @load_lane_i16_with_folded_offset(i16* %p, <8 x i16> %v) {
276; CHECK-LABEL: load_lane_i16_with_folded_offset:
277; CHECK:         .functype load_lane_i16_with_folded_offset (i32, v128) -> (v128)
278; CHECK-NEXT:  # %bb.0:
279; CHECK-NEXT:    local.get 0
280; CHECK-NEXT:    i32.const 24
281; CHECK-NEXT:    i32.add
282; CHECK-NEXT:    local.get 1
283; CHECK-NEXT:    v128.load16_lane 0:p2align=0, 0
284; CHECK-NEXT:    # fallthrough-return
285  %q = ptrtoint i16* %p to i32
286  %r = add nuw i32 %q, 24
287  %s = inttoptr i32 %r to i16*
288  %t = tail call <8 x i16> @llvm.wasm.load16.lane(i16* %s, <8 x i16> %v, i32 0)
289  ret <8 x i16> %t
290}
291
292define <8 x i16> @load_lane_i16_with_folded_gep_offset(i16* %p, <8 x i16> %v) {
293; CHECK-LABEL: load_lane_i16_with_folded_gep_offset:
294; CHECK:         .functype load_lane_i16_with_folded_gep_offset (i32, v128) -> (v128)
295; CHECK-NEXT:  # %bb.0:
296; CHECK-NEXT:    local.get 0
297; CHECK-NEXT:    i32.const 12
298; CHECK-NEXT:    i32.add
299; CHECK-NEXT:    local.get 1
300; CHECK-NEXT:    v128.load16_lane 0:p2align=0, 0
301; CHECK-NEXT:    # fallthrough-return
302  %s = getelementptr inbounds i16, i16* %p, i32 6
303  %t = tail call <8 x i16> @llvm.wasm.load16.lane(i16* %s, <8 x i16> %v, i32 0)
304  ret <8 x i16> %t
305}
306
307define <8 x i16> @load_lane_i16_with_unfolded_gep_negative_offset(i16* %p, <8 x i16> %v) {
308; CHECK-LABEL: load_lane_i16_with_unfolded_gep_negative_offset:
309; CHECK:         .functype load_lane_i16_with_unfolded_gep_negative_offset (i32, v128) -> (v128)
310; CHECK-NEXT:  # %bb.0:
311; CHECK-NEXT:    local.get 0
312; CHECK-NEXT:    i32.const -12
313; CHECK-NEXT:    i32.add
314; CHECK-NEXT:    local.get 1
315; CHECK-NEXT:    v128.load16_lane 0:p2align=0, 0
316; CHECK-NEXT:    # fallthrough-return
317  %s = getelementptr inbounds i16, i16* %p, i32 -6
318  %t = tail call <8 x i16> @llvm.wasm.load16.lane(i16* %s, <8 x i16> %v, i32 0)
319  ret <8 x i16> %t
320}
321
322define <8 x i16> @load_lane_i16_with_unfolded_offset(i16* %p, <8 x i16> %v) {
323; CHECK-LABEL: load_lane_i16_with_unfolded_offset:
324; CHECK:         .functype load_lane_i16_with_unfolded_offset (i32, v128) -> (v128)
325; CHECK-NEXT:  # %bb.0:
326; CHECK-NEXT:    local.get 0
327; CHECK-NEXT:    i32.const 24
328; CHECK-NEXT:    i32.add
329; CHECK-NEXT:    local.get 1
330; CHECK-NEXT:    v128.load16_lane 0:p2align=0, 0
331; CHECK-NEXT:    # fallthrough-return
332  %q = ptrtoint i16* %p to i32
333  %r = add nsw i32 %q, 24
334  %s = inttoptr i32 %r to i16*
335  %t = tail call <8 x i16> @llvm.wasm.load16.lane(i16* %s, <8 x i16> %v, i32 0)
336  ret <8 x i16> %t
337}
338
339define <8 x i16> @load_lane_i16_with_unfolded_gep_offset(i16* %p, <8 x i16> %v) {
340; CHECK-LABEL: load_lane_i16_with_unfolded_gep_offset:
341; CHECK:         .functype load_lane_i16_with_unfolded_gep_offset (i32, v128) -> (v128)
342; CHECK-NEXT:  # %bb.0:
343; CHECK-NEXT:    local.get 0
344; CHECK-NEXT:    i32.const 12
345; CHECK-NEXT:    i32.add
346; CHECK-NEXT:    local.get 1
347; CHECK-NEXT:    v128.load16_lane 0:p2align=0, 0
348; CHECK-NEXT:    # fallthrough-return
349  %s = getelementptr i16, i16* %p, i32 6
350  %t = tail call <8 x i16> @llvm.wasm.load16.lane(i16* %s, <8 x i16> %v, i32 0)
351  ret <8 x i16> %t
352}
353
354define <8 x i16> @load_lane_i16_from_numeric_address(<8 x i16> %v) {
355; CHECK-LABEL: load_lane_i16_from_numeric_address:
356; CHECK:         .functype load_lane_i16_from_numeric_address (v128) -> (v128)
357; CHECK-NEXT:  # %bb.0:
358; CHECK-NEXT:    i32.const 42
359; CHECK-NEXT:    local.get 0
360; CHECK-NEXT:    v128.load16_lane 0:p2align=0, 0
361; CHECK-NEXT:    # fallthrough-return
362  %s = inttoptr i32 42 to i16*
363  %t = tail call <8 x i16> @llvm.wasm.load16.lane(i16* %s, <8 x i16> %v, i32 0)
364  ret <8 x i16> %t
365}
366
367@gv_i16 = global i16 0
368define <8 x i16> @load_lane_i16_from_global_address(<8 x i16> %v) {
369; CHECK-LABEL: load_lane_i16_from_global_address:
370; CHECK:         .functype load_lane_i16_from_global_address (v128) -> (v128)
371; CHECK-NEXT:  # %bb.0:
372; CHECK-NEXT:    i32.const gv_i16
373; CHECK-NEXT:    local.get 0
374; CHECK-NEXT:    v128.load16_lane 0:p2align=0, 0
375; CHECK-NEXT:    # fallthrough-return
376  %t = tail call <8 x i16> @llvm.wasm.load16.lane(i16* @gv_i16, <8 x i16> %v, i32 0)
377  ret <8 x i16> %t
378}
379
380define void @store_lane_i16_no_offset(<8 x i16> %v, i16* %p) {
381; CHECK-LABEL: store_lane_i16_no_offset:
382; CHECK:         .functype store_lane_i16_no_offset (v128, i32) -> ()
383; CHECK-NEXT:  # %bb.0:
384; CHECK-NEXT:    local.get 1
385; CHECK-NEXT:    local.get 0
386; CHECK-NEXT:    v128.store16_lane 0:p2align=0, 0
387; CHECK-NEXT:    # fallthrough-return
388  tail call void @llvm.wasm.store16.lane(i16* %p, <8 x i16> %v, i32 0)
389  ret void
390}
391
392define void @store_lane_i16_with_folded_offset(<8 x i16> %v, i16* %p) {
393; CHECK-LABEL: store_lane_i16_with_folded_offset:
394; CHECK:         .functype store_lane_i16_with_folded_offset (v128, i32) -> ()
395; CHECK-NEXT:  # %bb.0:
396; CHECK-NEXT:    local.get 1
397; CHECK-NEXT:    i32.const 24
398; CHECK-NEXT:    i32.add
399; CHECK-NEXT:    local.get 0
400; CHECK-NEXT:    v128.store16_lane 0:p2align=0, 0
401; CHECK-NEXT:    # fallthrough-return
402  %q = ptrtoint i16* %p to i32
403  %r = add nuw i32 %q, 24
404  %s = inttoptr i32 %r to i16*
405  tail call void @llvm.wasm.store16.lane(i16* %s, <8 x i16> %v, i32 0)
406  ret void
407}
408
409define void @store_lane_i16_with_folded_gep_offset(<8 x i16> %v, i16* %p) {
410; CHECK-LABEL: store_lane_i16_with_folded_gep_offset:
411; CHECK:         .functype store_lane_i16_with_folded_gep_offset (v128, i32) -> ()
412; CHECK-NEXT:  # %bb.0:
413; CHECK-NEXT:    local.get 1
414; CHECK-NEXT:    i32.const 12
415; CHECK-NEXT:    i32.add
416; CHECK-NEXT:    local.get 0
417; CHECK-NEXT:    v128.store16_lane 0:p2align=0, 0
418; CHECK-NEXT:    # fallthrough-return
419  %s = getelementptr inbounds i16, i16* %p, i32 6
420  tail call void @llvm.wasm.store16.lane(i16* %s, <8 x i16> %v, i32 0)
421  ret void
422}
423
424define void @store_lane_i16_with_unfolded_gep_negative_offset(<8 x i16> %v, i16* %p) {
425; CHECK-LABEL: store_lane_i16_with_unfolded_gep_negative_offset:
426; CHECK:         .functype store_lane_i16_with_unfolded_gep_negative_offset (v128, i32) -> ()
427; CHECK-NEXT:  # %bb.0:
428; CHECK-NEXT:    local.get 1
429; CHECK-NEXT:    i32.const -12
430; CHECK-NEXT:    i32.add
431; CHECK-NEXT:    local.get 0
432; CHECK-NEXT:    v128.store16_lane 0:p2align=0, 0
433; CHECK-NEXT:    # fallthrough-return
434  %s = getelementptr inbounds i16, i16* %p, i32 -6
435  tail call void @llvm.wasm.store16.lane(i16* %s, <8 x i16> %v, i32 0)
436  ret void
437}
438
439define void @store_lane_i16_with_unfolded_offset(<8 x i16> %v, i16* %p) {
440; CHECK-LABEL: store_lane_i16_with_unfolded_offset:
441; CHECK:         .functype store_lane_i16_with_unfolded_offset (v128, i32) -> ()
442; CHECK-NEXT:  # %bb.0:
443; CHECK-NEXT:    local.get 1
444; CHECK-NEXT:    i32.const 24
445; CHECK-NEXT:    i32.add
446; CHECK-NEXT:    local.get 0
447; CHECK-NEXT:    v128.store16_lane 0:p2align=0, 0
448; CHECK-NEXT:    # fallthrough-return
449  %q = ptrtoint i16* %p to i32
450  %r = add nsw i32 %q, 24
451  %s = inttoptr i32 %r to i16*
452  tail call void @llvm.wasm.store16.lane(i16* %s, <8 x i16> %v, i32 0)
453  ret void
454}
455
456define void @store_lane_i16_with_unfolded_gep_offset(<8 x i16> %v, i16* %p) {
457; CHECK-LABEL: store_lane_i16_with_unfolded_gep_offset:
458; CHECK:         .functype store_lane_i16_with_unfolded_gep_offset (v128, i32) -> ()
459; CHECK-NEXT:  # %bb.0:
460; CHECK-NEXT:    local.get 1
461; CHECK-NEXT:    i32.const 12
462; CHECK-NEXT:    i32.add
463; CHECK-NEXT:    local.get 0
464; CHECK-NEXT:    v128.store16_lane 0:p2align=0, 0
465; CHECK-NEXT:    # fallthrough-return
466  %s = getelementptr i16, i16* %p, i32 6
467  tail call void @llvm.wasm.store16.lane(i16* %s, <8 x i16> %v, i32 0)
468  ret void
469}
470
471define void @store_lane_i16_to_numeric_address(<8 x i16> %v) {
472; CHECK-LABEL: store_lane_i16_to_numeric_address:
473; CHECK:         .functype store_lane_i16_to_numeric_address (v128) -> ()
474; CHECK-NEXT:  # %bb.0:
475; CHECK-NEXT:    i32.const 42
476; CHECK-NEXT:    local.get 0
477; CHECK-NEXT:    v128.store16_lane 0:p2align=0, 0
478; CHECK-NEXT:    # fallthrough-return
479  %s = inttoptr i32 42 to i16*
480  tail call void @llvm.wasm.store16.lane(i16* %s, <8 x i16> %v, i32 0)
481  ret void
482}
483
484define void @store_lane_i16_from_global_address(<8 x i16> %v) {
485; CHECK-LABEL: store_lane_i16_from_global_address:
486; CHECK:         .functype store_lane_i16_from_global_address (v128) -> ()
487; CHECK-NEXT:  # %bb.0:
488; CHECK-NEXT:    i32.const gv_i16
489; CHECK-NEXT:    local.get 0
490; CHECK-NEXT:    v128.store16_lane 0:p2align=0, 0
491; CHECK-NEXT:    # fallthrough-return
492  tail call void @llvm.wasm.store16.lane(i16* @gv_i16, <8 x i16> %v, i32 0)
493  ret void
494}
495
496;===----------------------------------------------------------------------------
497; v128.load32_lane / v128.store32_lane
498;===----------------------------------------------------------------------------
499
500define <4 x i32> @load_lane_i32_no_offset(i32* %p, <4 x i32> %v) {
501; CHECK-LABEL: load_lane_i32_no_offset:
502; CHECK:         .functype load_lane_i32_no_offset (i32, v128) -> (v128)
503; CHECK-NEXT:  # %bb.0:
504; CHECK-NEXT:    local.get 0
505; CHECK-NEXT:    local.get 1
506; CHECK-NEXT:    v128.load32_lane 0:p2align=0, 0
507; CHECK-NEXT:    # fallthrough-return
508  %t = tail call <4 x i32> @llvm.wasm.load32.lane(i32* %p, <4 x i32> %v, i32 0)
509  ret <4 x i32> %t
510}
511
512define <4 x i32> @load_lane_i32_with_folded_offset(i32* %p, <4 x i32> %v) {
513; CHECK-LABEL: load_lane_i32_with_folded_offset:
514; CHECK:         .functype load_lane_i32_with_folded_offset (i32, v128) -> (v128)
515; CHECK-NEXT:  # %bb.0:
516; CHECK-NEXT:    local.get 0
517; CHECK-NEXT:    i32.const 24
518; CHECK-NEXT:    i32.add
519; CHECK-NEXT:    local.get 1
520; CHECK-NEXT:    v128.load32_lane 0:p2align=0, 0
521; CHECK-NEXT:    # fallthrough-return
522  %q = ptrtoint i32* %p to i32
523  %r = add nuw i32 %q, 24
524  %s = inttoptr i32 %r to i32*
525  %t = tail call <4 x i32> @llvm.wasm.load32.lane(i32* %s, <4 x i32> %v, i32 0)
526  ret <4 x i32> %t
527}
528
529define <4 x i32> @load_lane_i32_with_folded_gep_offset(i32* %p, <4 x i32> %v) {
530; CHECK-LABEL: load_lane_i32_with_folded_gep_offset:
531; CHECK:         .functype load_lane_i32_with_folded_gep_offset (i32, v128) -> (v128)
532; CHECK-NEXT:  # %bb.0:
533; CHECK-NEXT:    local.get 0
534; CHECK-NEXT:    i32.const 24
535; CHECK-NEXT:    i32.add
536; CHECK-NEXT:    local.get 1
537; CHECK-NEXT:    v128.load32_lane 0:p2align=0, 0
538; CHECK-NEXT:    # fallthrough-return
539  %s = getelementptr inbounds i32, i32* %p, i32 6
540  %t = tail call <4 x i32> @llvm.wasm.load32.lane(i32* %s, <4 x i32> %v, i32 0)
541  ret <4 x i32> %t
542}
543
544define <4 x i32> @load_lane_i32_with_unfolded_gep_negative_offset(i32* %p, <4 x i32> %v) {
545; CHECK-LABEL: load_lane_i32_with_unfolded_gep_negative_offset:
546; CHECK:         .functype load_lane_i32_with_unfolded_gep_negative_offset (i32, v128) -> (v128)
547; CHECK-NEXT:  # %bb.0:
548; CHECK-NEXT:    local.get 0
549; CHECK-NEXT:    i32.const -24
550; CHECK-NEXT:    i32.add
551; CHECK-NEXT:    local.get 1
552; CHECK-NEXT:    v128.load32_lane 0:p2align=0, 0
553; CHECK-NEXT:    # fallthrough-return
554  %s = getelementptr inbounds i32, i32* %p, i32 -6
555  %t = tail call <4 x i32> @llvm.wasm.load32.lane(i32* %s, <4 x i32> %v, i32 0)
556  ret <4 x i32> %t
557}
558
559define <4 x i32> @load_lane_i32_with_unfolded_offset(i32* %p, <4 x i32> %v) {
560; CHECK-LABEL: load_lane_i32_with_unfolded_offset:
561; CHECK:         .functype load_lane_i32_with_unfolded_offset (i32, v128) -> (v128)
562; CHECK-NEXT:  # %bb.0:
563; CHECK-NEXT:    local.get 0
564; CHECK-NEXT:    i32.const 24
565; CHECK-NEXT:    i32.add
566; CHECK-NEXT:    local.get 1
567; CHECK-NEXT:    v128.load32_lane 0:p2align=0, 0
568; CHECK-NEXT:    # fallthrough-return
569  %q = ptrtoint i32* %p to i32
570  %r = add nsw i32 %q, 24
571  %s = inttoptr i32 %r to i32*
572  %t = tail call <4 x i32> @llvm.wasm.load32.lane(i32* %s, <4 x i32> %v, i32 0)
573  ret <4 x i32> %t
574}
575
576define <4 x i32> @load_lane_i32_with_unfolded_gep_offset(i32* %p, <4 x i32> %v) {
577; CHECK-LABEL: load_lane_i32_with_unfolded_gep_offset:
578; CHECK:         .functype load_lane_i32_with_unfolded_gep_offset (i32, v128) -> (v128)
579; CHECK-NEXT:  # %bb.0:
580; CHECK-NEXT:    local.get 0
581; CHECK-NEXT:    i32.const 24
582; CHECK-NEXT:    i32.add
583; CHECK-NEXT:    local.get 1
584; CHECK-NEXT:    v128.load32_lane 0:p2align=0, 0
585; CHECK-NEXT:    # fallthrough-return
586  %s = getelementptr i32, i32* %p, i32 6
587  %t = tail call <4 x i32> @llvm.wasm.load32.lane(i32* %s, <4 x i32> %v, i32 0)
588  ret <4 x i32> %t
589}
590
591define <4 x i32> @load_lane_i32_from_numeric_address(<4 x i32> %v) {
592; CHECK-LABEL: load_lane_i32_from_numeric_address:
593; CHECK:         .functype load_lane_i32_from_numeric_address (v128) -> (v128)
594; CHECK-NEXT:  # %bb.0:
595; CHECK-NEXT:    i32.const 42
596; CHECK-NEXT:    local.get 0
597; CHECK-NEXT:    v128.load32_lane 0:p2align=0, 0
598; CHECK-NEXT:    # fallthrough-return
599  %s = inttoptr i32 42 to i32*
600  %t = tail call <4 x i32> @llvm.wasm.load32.lane(i32* %s, <4 x i32> %v, i32 0)
601  ret <4 x i32> %t
602}
603
604@gv_i32 = global i32 0
605define <4 x i32> @load_lane_i32_from_global_address(<4 x i32> %v) {
606; CHECK-LABEL: load_lane_i32_from_global_address:
607; CHECK:         .functype load_lane_i32_from_global_address (v128) -> (v128)
608; CHECK-NEXT:  # %bb.0:
609; CHECK-NEXT:    i32.const gv_i32
610; CHECK-NEXT:    local.get 0
611; CHECK-NEXT:    v128.load32_lane 0:p2align=0, 0
612; CHECK-NEXT:    # fallthrough-return
613  %t = tail call <4 x i32> @llvm.wasm.load32.lane(i32* @gv_i32, <4 x i32> %v, i32 0)
614  ret <4 x i32> %t
615}
616
617define void @store_lane_i32_no_offset(<4 x i32> %v, i32* %p) {
618; CHECK-LABEL: store_lane_i32_no_offset:
619; CHECK:         .functype store_lane_i32_no_offset (v128, i32) -> ()
620; CHECK-NEXT:  # %bb.0:
621; CHECK-NEXT:    local.get 1
622; CHECK-NEXT:    local.get 0
623; CHECK-NEXT:    v128.store32_lane 0:p2align=0, 0
624; CHECK-NEXT:    # fallthrough-return
625  tail call void @llvm.wasm.store32.lane(i32* %p, <4 x i32> %v, i32 0)
626  ret void
627}
628
629define void @store_lane_i32_with_folded_offset(<4 x i32> %v, i32* %p) {
630; CHECK-LABEL: store_lane_i32_with_folded_offset:
631; CHECK:         .functype store_lane_i32_with_folded_offset (v128, i32) -> ()
632; CHECK-NEXT:  # %bb.0:
633; CHECK-NEXT:    local.get 1
634; CHECK-NEXT:    i32.const 24
635; CHECK-NEXT:    i32.add
636; CHECK-NEXT:    local.get 0
637; CHECK-NEXT:    v128.store32_lane 0:p2align=0, 0
638; CHECK-NEXT:    # fallthrough-return
639  %q = ptrtoint i32* %p to i32
640  %r = add nuw i32 %q, 24
641  %s = inttoptr i32 %r to i32*
642  tail call void @llvm.wasm.store32.lane(i32* %s, <4 x i32> %v, i32 0)
643  ret void
644}
645
646define void @store_lane_i32_with_folded_gep_offset(<4 x i32> %v, i32* %p) {
647; CHECK-LABEL: store_lane_i32_with_folded_gep_offset:
648; CHECK:         .functype store_lane_i32_with_folded_gep_offset (v128, i32) -> ()
649; CHECK-NEXT:  # %bb.0:
650; CHECK-NEXT:    local.get 1
651; CHECK-NEXT:    i32.const 24
652; CHECK-NEXT:    i32.add
653; CHECK-NEXT:    local.get 0
654; CHECK-NEXT:    v128.store32_lane 0:p2align=0, 0
655; CHECK-NEXT:    # fallthrough-return
656  %s = getelementptr inbounds i32, i32* %p, i32 6
657  tail call void @llvm.wasm.store32.lane(i32* %s, <4 x i32> %v, i32 0)
658  ret void
659}
660
661define void @store_lane_i32_with_unfolded_gep_negative_offset(<4 x i32> %v, i32* %p) {
662; CHECK-LABEL: store_lane_i32_with_unfolded_gep_negative_offset:
663; CHECK:         .functype store_lane_i32_with_unfolded_gep_negative_offset (v128, i32) -> ()
664; CHECK-NEXT:  # %bb.0:
665; CHECK-NEXT:    local.get 1
666; CHECK-NEXT:    i32.const -24
667; CHECK-NEXT:    i32.add
668; CHECK-NEXT:    local.get 0
669; CHECK-NEXT:    v128.store32_lane 0:p2align=0, 0
670; CHECK-NEXT:    # fallthrough-return
671  %s = getelementptr inbounds i32, i32* %p, i32 -6
672  tail call void @llvm.wasm.store32.lane(i32* %s, <4 x i32> %v, i32 0)
673  ret void
674}
675
676define void @store_lane_i32_with_unfolded_offset(<4 x i32> %v, i32* %p) {
677; CHECK-LABEL: store_lane_i32_with_unfolded_offset:
678; CHECK:         .functype store_lane_i32_with_unfolded_offset (v128, i32) -> ()
679; CHECK-NEXT:  # %bb.0:
680; CHECK-NEXT:    local.get 1
681; CHECK-NEXT:    i32.const 24
682; CHECK-NEXT:    i32.add
683; CHECK-NEXT:    local.get 0
684; CHECK-NEXT:    v128.store32_lane 0:p2align=0, 0
685; CHECK-NEXT:    # fallthrough-return
686  %q = ptrtoint i32* %p to i32
687  %r = add nsw i32 %q, 24
688  %s = inttoptr i32 %r to i32*
689  tail call void @llvm.wasm.store32.lane(i32* %s, <4 x i32> %v, i32 0)
690  ret void
691}
692
693define void @store_lane_i32_with_unfolded_gep_offset(<4 x i32> %v, i32* %p) {
694; CHECK-LABEL: store_lane_i32_with_unfolded_gep_offset:
695; CHECK:         .functype store_lane_i32_with_unfolded_gep_offset (v128, i32) -> ()
696; CHECK-NEXT:  # %bb.0:
697; CHECK-NEXT:    local.get 1
698; CHECK-NEXT:    i32.const 24
699; CHECK-NEXT:    i32.add
700; CHECK-NEXT:    local.get 0
701; CHECK-NEXT:    v128.store32_lane 0:p2align=0, 0
702; CHECK-NEXT:    # fallthrough-return
703  %s = getelementptr i32, i32* %p, i32 6
704  tail call void @llvm.wasm.store32.lane(i32* %s, <4 x i32> %v, i32 0)
705  ret void
706}
707
708define void @store_lane_i32_to_numeric_address(<4 x i32> %v) {
709; CHECK-LABEL: store_lane_i32_to_numeric_address:
710; CHECK:         .functype store_lane_i32_to_numeric_address (v128) -> ()
711; CHECK-NEXT:  # %bb.0:
712; CHECK-NEXT:    i32.const 42
713; CHECK-NEXT:    local.get 0
714; CHECK-NEXT:    v128.store32_lane 0:p2align=0, 0
715; CHECK-NEXT:    # fallthrough-return
716  %s = inttoptr i32 42 to i32*
717  tail call void @llvm.wasm.store32.lane(i32* %s, <4 x i32> %v, i32 0)
718  ret void
719}
720
721define void @store_lane_i32_from_global_address(<4 x i32> %v) {
722; CHECK-LABEL: store_lane_i32_from_global_address:
723; CHECK:         .functype store_lane_i32_from_global_address (v128) -> ()
724; CHECK-NEXT:  # %bb.0:
725; CHECK-NEXT:    i32.const gv_i32
726; CHECK-NEXT:    local.get 0
727; CHECK-NEXT:    v128.store32_lane 0:p2align=0, 0
728; CHECK-NEXT:    # fallthrough-return
729  tail call void @llvm.wasm.store32.lane(i32* @gv_i32, <4 x i32> %v, i32 0)
730  ret void
731}
732
733;===----------------------------------------------------------------------------
734; v128.load64_lane / v128.store64_lane
735;===----------------------------------------------------------------------------
736
737define <2 x i64> @load_lane_i64_no_offset(i64* %p, <2 x i64> %v) {
738; CHECK-LABEL: load_lane_i64_no_offset:
739; CHECK:         .functype load_lane_i64_no_offset (i32, v128) -> (v128)
740; CHECK-NEXT:  # %bb.0:
741; CHECK-NEXT:    local.get 0
742; CHECK-NEXT:    local.get 1
743; CHECK-NEXT:    v128.load64_lane 0:p2align=0, 0
744; CHECK-NEXT:    # fallthrough-return
745  %t = tail call <2 x i64> @llvm.wasm.load64.lane(i64* %p, <2 x i64> %v, i32 0)
746  ret <2 x i64> %t
747}
748
749define <2 x i64> @load_lane_i64_with_folded_offset(i64* %p, <2 x i64> %v) {
750; CHECK-LABEL: load_lane_i64_with_folded_offset:
751; CHECK:         .functype load_lane_i64_with_folded_offset (i32, v128) -> (v128)
752; CHECK-NEXT:  # %bb.0:
753; CHECK-NEXT:    local.get 0
754; CHECK-NEXT:    i32.const 24
755; CHECK-NEXT:    i32.add
756; CHECK-NEXT:    local.get 1
757; CHECK-NEXT:    v128.load64_lane 0:p2align=0, 0
758; CHECK-NEXT:    # fallthrough-return
759  %q = ptrtoint i64* %p to i32
760  %r = add nuw i32 %q, 24
761  %s = inttoptr i32 %r to i64*
762  %t = tail call <2 x i64> @llvm.wasm.load64.lane(i64* %s, <2 x i64> %v, i32 0)
763  ret <2 x i64> %t
764}
765
766define <2 x i64> @load_lane_i64_with_folded_gep_offset(i64* %p, <2 x i64> %v) {
767; CHECK-LABEL: load_lane_i64_with_folded_gep_offset:
768; CHECK:         .functype load_lane_i64_with_folded_gep_offset (i32, v128) -> (v128)
769; CHECK-NEXT:  # %bb.0:
770; CHECK-NEXT:    local.get 0
771; CHECK-NEXT:    i32.const 48
772; CHECK-NEXT:    i32.add
773; CHECK-NEXT:    local.get 1
774; CHECK-NEXT:    v128.load64_lane 0:p2align=0, 0
775; CHECK-NEXT:    # fallthrough-return
776  %s = getelementptr inbounds i64, i64* %p, i32 6
777  %t = tail call <2 x i64> @llvm.wasm.load64.lane(i64* %s, <2 x i64> %v, i32 0)
778  ret <2 x i64> %t
779}
780
781define <2 x i64> @load_lane_i64_with_unfolded_gep_negative_offset(i64* %p, <2 x i64> %v) {
782; CHECK-LABEL: load_lane_i64_with_unfolded_gep_negative_offset:
783; CHECK:         .functype load_lane_i64_with_unfolded_gep_negative_offset (i32, v128) -> (v128)
784; CHECK-NEXT:  # %bb.0:
785; CHECK-NEXT:    local.get 0
786; CHECK-NEXT:    i32.const -48
787; CHECK-NEXT:    i32.add
788; CHECK-NEXT:    local.get 1
789; CHECK-NEXT:    v128.load64_lane 0:p2align=0, 0
790; CHECK-NEXT:    # fallthrough-return
791  %s = getelementptr inbounds i64, i64* %p, i32 -6
792  %t = tail call <2 x i64> @llvm.wasm.load64.lane(i64* %s, <2 x i64> %v, i32 0)
793  ret <2 x i64> %t
794}
795
796define <2 x i64> @load_lane_i64_with_unfolded_offset(i64* %p, <2 x i64> %v) {
797; CHECK-LABEL: load_lane_i64_with_unfolded_offset:
798; CHECK:         .functype load_lane_i64_with_unfolded_offset (i32, v128) -> (v128)
799; CHECK-NEXT:  # %bb.0:
800; CHECK-NEXT:    local.get 0
801; CHECK-NEXT:    i32.const 24
802; CHECK-NEXT:    i32.add
803; CHECK-NEXT:    local.get 1
804; CHECK-NEXT:    v128.load64_lane 0:p2align=0, 0
805; CHECK-NEXT:    # fallthrough-return
806  %q = ptrtoint i64* %p to i32
807  %r = add nsw i32 %q, 24
808  %s = inttoptr i32 %r to i64*
809  %t = tail call <2 x i64> @llvm.wasm.load64.lane(i64* %s, <2 x i64> %v, i32 0)
810  ret <2 x i64> %t
811}
812
813define <2 x i64> @load_lane_i64_with_unfolded_gep_offset(i64* %p, <2 x i64> %v) {
814; CHECK-LABEL: load_lane_i64_with_unfolded_gep_offset:
815; CHECK:         .functype load_lane_i64_with_unfolded_gep_offset (i32, v128) -> (v128)
816; CHECK-NEXT:  # %bb.0:
817; CHECK-NEXT:    local.get 0
818; CHECK-NEXT:    i32.const 48
819; CHECK-NEXT:    i32.add
820; CHECK-NEXT:    local.get 1
821; CHECK-NEXT:    v128.load64_lane 0:p2align=0, 0
822; CHECK-NEXT:    # fallthrough-return
823  %s = getelementptr i64, i64* %p, i32 6
824  %t = tail call <2 x i64> @llvm.wasm.load64.lane(i64* %s, <2 x i64> %v, i32 0)
825  ret <2 x i64> %t
826}
827
828define <2 x i64> @load_lane_i64_from_numeric_address(<2 x i64> %v) {
829; CHECK-LABEL: load_lane_i64_from_numeric_address:
830; CHECK:         .functype load_lane_i64_from_numeric_address (v128) -> (v128)
831; CHECK-NEXT:  # %bb.0:
832; CHECK-NEXT:    i32.const 42
833; CHECK-NEXT:    local.get 0
834; CHECK-NEXT:    v128.load64_lane 0:p2align=0, 0
835; CHECK-NEXT:    # fallthrough-return
836  %s = inttoptr i32 42 to i64*
837  %t = tail call <2 x i64> @llvm.wasm.load64.lane(i64* %s, <2 x i64> %v, i32 0)
838  ret <2 x i64> %t
839}
840
841@gv_i64 = global i64 0
842define <2 x i64> @load_lane_i64_from_global_address(<2 x i64> %v) {
843; CHECK-LABEL: load_lane_i64_from_global_address:
844; CHECK:         .functype load_lane_i64_from_global_address (v128) -> (v128)
845; CHECK-NEXT:  # %bb.0:
846; CHECK-NEXT:    i32.const gv_i64
847; CHECK-NEXT:    local.get 0
848; CHECK-NEXT:    v128.load64_lane 0:p2align=0, 0
849; CHECK-NEXT:    # fallthrough-return
850  %t = tail call <2 x i64> @llvm.wasm.load64.lane(i64* @gv_i64, <2 x i64> %v, i32 0)
851  ret <2 x i64> %t
852}
853
854define void @store_lane_i64_no_offset(<2 x i64> %v, i64* %p) {
855; CHECK-LABEL: store_lane_i64_no_offset:
856; CHECK:         .functype store_lane_i64_no_offset (v128, i32) -> ()
857; CHECK-NEXT:  # %bb.0:
858; CHECK-NEXT:    local.get 1
859; CHECK-NEXT:    local.get 0
860; CHECK-NEXT:    v128.store64_lane 0:p2align=0, 0
861; CHECK-NEXT:    # fallthrough-return
862  tail call void @llvm.wasm.store64.lane(i64* %p, <2 x i64> %v, i32 0)
863  ret void
864}
865
866define void @store_lane_i64_with_folded_offset(<2 x i64> %v, i64* %p) {
867; CHECK-LABEL: store_lane_i64_with_folded_offset:
868; CHECK:         .functype store_lane_i64_with_folded_offset (v128, i32) -> ()
869; CHECK-NEXT:  # %bb.0:
870; CHECK-NEXT:    local.get 1
871; CHECK-NEXT:    i32.const 24
872; CHECK-NEXT:    i32.add
873; CHECK-NEXT:    local.get 0
874; CHECK-NEXT:    v128.store64_lane 0:p2align=0, 0
875; CHECK-NEXT:    # fallthrough-return
876  %q = ptrtoint i64* %p to i32
877  %r = add nuw i32 %q, 24
878  %s = inttoptr i32 %r to i64*
879  tail call void @llvm.wasm.store64.lane(i64* %s, <2 x i64> %v, i32 0)
880  ret void
881}
882
883define void @store_lane_i64_with_folded_gep_offset(<2 x i64> %v, i64* %p) {
884; CHECK-LABEL: store_lane_i64_with_folded_gep_offset:
885; CHECK:         .functype store_lane_i64_with_folded_gep_offset (v128, i32) -> ()
886; CHECK-NEXT:  # %bb.0:
887; CHECK-NEXT:    local.get 1
888; CHECK-NEXT:    i32.const 48
889; CHECK-NEXT:    i32.add
890; CHECK-NEXT:    local.get 0
891; CHECK-NEXT:    v128.store64_lane 0:p2align=0, 0
892; CHECK-NEXT:    # fallthrough-return
893  %s = getelementptr inbounds i64, i64* %p, i32 6
894  tail call void @llvm.wasm.store64.lane(i64* %s, <2 x i64> %v, i32 0)
895  ret void
896}
897
898define void @store_lane_i64_with_unfolded_gep_negative_offset(<2 x i64> %v, i64* %p) {
899; CHECK-LABEL: store_lane_i64_with_unfolded_gep_negative_offset:
900; CHECK:         .functype store_lane_i64_with_unfolded_gep_negative_offset (v128, i32) -> ()
901; CHECK-NEXT:  # %bb.0:
902; CHECK-NEXT:    local.get 1
903; CHECK-NEXT:    i32.const -48
904; CHECK-NEXT:    i32.add
905; CHECK-NEXT:    local.get 0
906; CHECK-NEXT:    v128.store64_lane 0:p2align=0, 0
907; CHECK-NEXT:    # fallthrough-return
908  %s = getelementptr inbounds i64, i64* %p, i32 -6
909  tail call void @llvm.wasm.store64.lane(i64* %s, <2 x i64> %v, i32 0)
910  ret void
911}
912
913define void @store_lane_i64_with_unfolded_offset(<2 x i64> %v, i64* %p) {
914; CHECK-LABEL: store_lane_i64_with_unfolded_offset:
915; CHECK:         .functype store_lane_i64_with_unfolded_offset (v128, i32) -> ()
916; CHECK-NEXT:  # %bb.0:
917; CHECK-NEXT:    local.get 1
918; CHECK-NEXT:    i32.const 24
919; CHECK-NEXT:    i32.add
920; CHECK-NEXT:    local.get 0
921; CHECK-NEXT:    v128.store64_lane 0:p2align=0, 0
922; CHECK-NEXT:    # fallthrough-return
923  %q = ptrtoint i64* %p to i32
924  %r = add nsw i32 %q, 24
925  %s = inttoptr i32 %r to i64*
926  tail call void @llvm.wasm.store64.lane(i64* %s, <2 x i64> %v, i32 0)
927  ret void
928}
929
930define void @store_lane_i64_with_unfolded_gep_offset(<2 x i64> %v, i64* %p) {
931; CHECK-LABEL: store_lane_i64_with_unfolded_gep_offset:
932; CHECK:         .functype store_lane_i64_with_unfolded_gep_offset (v128, i32) -> ()
933; CHECK-NEXT:  # %bb.0:
934; CHECK-NEXT:    local.get 1
935; CHECK-NEXT:    i32.const 48
936; CHECK-NEXT:    i32.add
937; CHECK-NEXT:    local.get 0
938; CHECK-NEXT:    v128.store64_lane 0:p2align=0, 0
939; CHECK-NEXT:    # fallthrough-return
940  %s = getelementptr i64, i64* %p, i32 6
941  tail call void @llvm.wasm.store64.lane(i64* %s, <2 x i64> %v, i32 0)
942  ret void
943}
944
945define void @store_lane_i64_to_numeric_address(<2 x i64> %v) {
946; CHECK-LABEL: store_lane_i64_to_numeric_address:
947; CHECK:         .functype store_lane_i64_to_numeric_address (v128) -> ()
948; CHECK-NEXT:  # %bb.0:
949; CHECK-NEXT:    i32.const 42
950; CHECK-NEXT:    local.get 0
951; CHECK-NEXT:    v128.store64_lane 0:p2align=0, 0
952; CHECK-NEXT:    # fallthrough-return
953  %s = inttoptr i32 42 to i64*
954  tail call void @llvm.wasm.store64.lane(i64* %s, <2 x i64> %v, i32 0)
955  ret void
956}
957
958define void @store_lane_i64_from_global_address(<2 x i64> %v) {
959; CHECK-LABEL: store_lane_i64_from_global_address:
960; CHECK:         .functype store_lane_i64_from_global_address (v128) -> ()
961; CHECK-NEXT:  # %bb.0:
962; CHECK-NEXT:    i32.const gv_i64
963; CHECK-NEXT:    local.get 0
964; CHECK-NEXT:    v128.store64_lane 0:p2align=0, 0
965; CHECK-NEXT:    # fallthrough-return
966  tail call void @llvm.wasm.store64.lane(i64* @gv_i64, <2 x i64> %v, i32 0)
967  ret void
968}
969