xref: /llvm-project/llvm/test/CodeGen/WebAssembly/offset-fastisel.ll (revision 41080b2fdd4b6c57d5a2926d6157b9847342b3a1)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -wasm-disable-explicit-locals -wasm-keep-registers -fast-isel -fast-isel-abort=1 | FileCheck %s
3
4; TODO: Merge this with offset.ll when fast-isel matches better.
5
6target triple = "wasm32-unknown-unknown"
7
8define void @store_i8_with_variable_gep_offset(ptr %p, i32 %idx) {
9; CHECK-LABEL: store_i8_with_variable_gep_offset:
10; CHECK:         .functype store_i8_with_variable_gep_offset (i32, i32) -> ()
11; CHECK-NEXT:  # %bb.0:
12; CHECK-NEXT:    i32.add $push1=, $0, $1
13; CHECK-NEXT:    i32.const $push0=, 0
14; CHECK-NEXT:    i32.store8 0($pop1), $pop0
15; CHECK-NEXT:    # fallthrough-return
16  %s = getelementptr inbounds i8, ptr %p, i32 %idx
17  store i8 0, ptr %s
18  ret void
19}
20
21define hidden void @store_i8_with_array_alloca_gep(i32 %idx) {
22; CHECK-LABEL: store_i8_with_array_alloca_gep:
23; CHECK:         .functype store_i8_with_array_alloca_gep (i32) -> ()
24; CHECK-NEXT:  # %bb.0:
25; CHECK-NEXT:    global.get $push3=, __stack_pointer
26; CHECK-NEXT:    i32.const $push4=, 32
27; CHECK-NEXT:    i32.sub $push5=, $pop3, $pop4
28; CHECK-NEXT:    local.copy $push1=, $pop5
29; CHECK-NEXT:    i32.add $push2=, $pop1, $0
30; CHECK-NEXT:    i32.const $push0=, 0
31; CHECK-NEXT:    i32.store8 0($pop2), $pop0
32; CHECK-NEXT:    # fallthrough-return
33  %A = alloca [30 x i8], align 16
34  %s = getelementptr inbounds [30 x i8], ptr %A, i32 0, i32 %idx
35  store i8 0, ptr %s, align 1
36  ret void
37}
38
39define void @store_i32_with_unfolded_gep_offset(ptr %p) {
40; CHECK-LABEL: store_i32_with_unfolded_gep_offset:
41; CHECK:         .functype store_i32_with_unfolded_gep_offset (i32) -> ()
42; CHECK-NEXT:  # %bb.0:
43; CHECK-NEXT:    i32.const $push1=, 24
44; CHECK-NEXT:    i32.add $push2=, $0, $pop1
45; CHECK-NEXT:    i32.const $push0=, 0
46; CHECK-NEXT:    i32.store 0($pop2), $pop0
47; CHECK-NEXT:    # fallthrough-return
48  %s = getelementptr i32, ptr %p, i32 6
49  store i32 0, ptr %s
50  ret void
51}
52
53define void @store_i32_with_folded_gep_offset(ptr %p) {
54; CHECK-LABEL: store_i32_with_folded_gep_offset:
55; CHECK:         .functype store_i32_with_folded_gep_offset (i32) -> ()
56; CHECK-NEXT:  # %bb.0:
57; CHECK-NEXT:    i32.const $push0=, 0
58; CHECK-NEXT:    i32.store 24($0), $pop0
59; CHECK-NEXT:    # fallthrough-return
60  %s = getelementptr inbounds i32, ptr %p, i32 6
61  store i32 0, ptr %s
62  ret void
63}
64
65define i32 @load_i32_with_folded_gep_offset(ptr %p) {
66; CHECK-LABEL: load_i32_with_folded_gep_offset:
67; CHECK:         .functype load_i32_with_folded_gep_offset (i32) -> (i32)
68; CHECK-NEXT:  # %bb.0:
69; CHECK-NEXT:    i32.load $push0=, 24($0)
70; CHECK-NEXT:    # fallthrough-return
71  %s = getelementptr inbounds i32, ptr %p, i32 6
72  %t = load i32, ptr %s
73  ret i32 %t
74}
75
76define void @store_i64_with_unfolded_gep_offset(ptr %p) {
77; CHECK-LABEL: store_i64_with_unfolded_gep_offset:
78; CHECK:         .functype store_i64_with_unfolded_gep_offset (i32) -> ()
79; CHECK-NEXT:  # %bb.0:
80; CHECK-NEXT:    i32.const $push1=, 24
81; CHECK-NEXT:    i32.add $push2=, $0, $pop1
82; CHECK-NEXT:    i64.const $push0=, 0
83; CHECK-NEXT:    i64.store 0($pop2), $pop0
84; CHECK-NEXT:    # fallthrough-return
85  %s = getelementptr i64, ptr %p, i32 3
86  store i64 0, ptr %s
87  ret void
88}
89
90define void @store_i8_with_folded_gep_offset(ptr %p) {
91; CHECK-LABEL: store_i8_with_folded_gep_offset:
92; CHECK:         .functype store_i8_with_folded_gep_offset (i32) -> ()
93; CHECK-NEXT:  # %bb.0:
94; CHECK-NEXT:    i32.const $push0=, 0
95; CHECK-NEXT:    i32.store8 24($0), $pop0
96; CHECK-NEXT:    # fallthrough-return
97  %s = getelementptr inbounds i8, ptr %p, i32 24
98  store i8 0, ptr %s
99  ret void
100}
101
102define i32 @load_i8_u_with_folded_offset(ptr %p) {
103; CHECK-LABEL: load_i8_u_with_folded_offset:
104; CHECK:         .functype load_i8_u_with_folded_offset (i32) -> (i32)
105; CHECK-NEXT:  # %bb.0:
106; CHECK-NEXT:    i32.load8_u $push2=, 24($0)
107; CHECK-NEXT:    i32.const $push0=, 255
108; CHECK-NEXT:    i32.and $push1=, $pop2, $pop0
109; CHECK-NEXT:    # fallthrough-return
110  %q = ptrtoint ptr %p to i32
111  %r = add nuw i32 %q, 24
112  %s = inttoptr i32 %r to ptr
113  %t = load i8, ptr %s
114  %u = zext i8 %t to i32
115  ret i32 %u
116}
117
118; TODO: this should be load8_s, need to fold sign-/zero-extend in fast-isel
119define i32 @load_i8_s_with_folded_offset(ptr %p) {
120; CHECK-LABEL: load_i8_s_with_folded_offset:
121; CHECK:         .functype load_i8_s_with_folded_offset (i32) -> (i32)
122; CHECK-NEXT:  # %bb.0:
123; CHECK-NEXT:    i32.load8_u $push3=, 24($0)
124; CHECK-NEXT:    i32.const $push0=, 24
125; CHECK-NEXT:    i32.shl $push1=, $pop3, $pop0
126; CHECK-NEXT:    i32.const $push4=, 24
127; CHECK-NEXT:    i32.shr_s $push2=, $pop1, $pop4
128; CHECK-NEXT:    # fallthrough-return
129  %q = ptrtoint ptr %p to i32
130  %r = add nuw i32 %q, 24
131  %s = inttoptr i32 %r to ptr
132  %t = load i8, ptr %s
133  %u = sext i8 %t to i32
134  ret i32 %u
135}
136