xref: /llvm-project/llvm/test/CodeGen/WebAssembly/fast-isel-no-offset.ll (revision 115cb402d8ed91f94d22afcc4c2c9ed9def53cc7)
1; RUN: llc < %s -asm-verbose=false -fast-isel -fast-isel-abort=1 -verify-machineinstrs | FileCheck %s
2
3target triple = "wasm32-unknown-unknown"
4
5; FastISel should not fold one of the add/sub operands into a load/store's
6; offset when 'nuw' (no unsigned wrap) is not present, because the address
7; calculation does not wrap. When there is an add/sub and nuw is not present, we
8; bail out of FastISel.
9
10@mylabel = external global ptr
11
12; CHECK-LABEL: dont_fold_non_nuw_add_load:
13; CHECK:       local.get  0
14; CHECK-NEXT:  i32.const  2147483644
15; CHECK-NEXT:  i32.add
16; CHECK-NEXT:  i32.load  0
17define i32 @dont_fold_non_nuw_add_load(ptr %p) {
18  %q = ptrtoint ptr %p to i32
19  %r = add i32 %q, 2147483644
20  %s = inttoptr i32 %r to ptr
21  %t = load i32, ptr %s
22  ret i32 %t
23}
24
25; CHECK-LABEL: dont_fold_non_nuw_add_store:
26; CHECK:       local.get  0
27; CHECK-NEXT:  i32.const  2147483644
28; CHECK-NEXT:  i32.add
29; CHECK-NEXT:  i32.const  5
30; CHECK-NEXT:  i32.store  0
31define void @dont_fold_non_nuw_add_store(ptr %p) {
32  %q = ptrtoint ptr %p to i32
33  %r = add i32 %q, 2147483644
34  %s = inttoptr i32 %r to ptr
35  store i32 5, ptr %s
36  ret void
37}
38
39; CHECK-LABEL: dont_fold_non_nuw_add_load_2:
40; CHECK:       i32.const  mylabel
41; CHECK-NEXT:  i32.const  -4
42; CHECK-NEXT:  i32.add
43; CHECK-NEXT:  i32.load  0
44define i32 @dont_fold_non_nuw_add_load_2() {
45  %t = load i32, ptr inttoptr (i32 add (i32 ptrtoint (ptr @mylabel to i32), i32 -4) to ptr), align 4
46  ret i32 %t
47}
48
49; CHECK-LABEL: dont_fold_non_nuw_add_store_2:
50; CHECK:       i32.const  mylabel
51; CHECK-NEXT:  i32.const  -4
52; CHECK-NEXT:  i32.add
53; CHECK-NEXT:  i32.const  5
54; CHECK-NEXT:  i32.store  0
55define void @dont_fold_non_nuw_add_store_2() {
56  store i32 5, ptr inttoptr (i32 add (i32 ptrtoint (ptr @mylabel to i32), i32 -4) to ptr), align 4
57  ret void
58}
59
60; CHECK-LABEL: dont_fold_non_nuw_sub_load:
61; CHECK:       local.get  0
62; CHECK-NEXT:  i32.const  -2147483644
63; CHECK-NEXT:  i32.sub
64; CHECK-NEXT:  i32.load  0
65define i32 @dont_fold_non_nuw_sub_load(ptr %p) {
66  %q = ptrtoint ptr %p to i32
67  %r = sub i32 %q, -2147483644
68  %s = inttoptr i32 %r to ptr
69  %t = load i32, ptr %s
70  ret i32 %t
71}
72
73; CHECK-LABEL: dont_fold_non_nuw_sub_store:
74; CHECK:       local.get  0
75; CHECK-NEXT:  i32.const  -2147483644
76; CHECK-NEXT:  i32.sub
77; CHECK-NEXT:  i32.const  5
78; CHECK-NEXT:  i32.store  0
79define void @dont_fold_non_nuw_sub_store(ptr %p) {
80  %q = ptrtoint ptr %p to i32
81  %r = sub i32 %q, -2147483644
82  %s = inttoptr i32 %r to ptr
83  store i32 5, ptr %s
84  ret void
85}
86
87; CHECK-LABEL: dont_fold_non_nuw_sub_load_2:
88; CHECK:       i32.const  mylabel
89; CHECK-NEXT:  i32.const  4
90; CHECK-NEXT:  i32.sub
91; CHECK-NEXT:  i32.load  0
92define i32 @dont_fold_non_nuw_sub_load_2() {
93  %t = load i32, ptr inttoptr (i32 sub (i32 ptrtoint (ptr @mylabel to i32), i32 4) to ptr), align 4
94 ret i32 %t
95}
96
97; CHECK-LABEL: dont_fold_non_nuw_sub_store_2:
98; CHECK:       i32.const  mylabel
99; CHECK-NEXT:  i32.const  4
100; CHECK-NEXT:  i32.sub
101; CHECK-NEXT:  i32.const  5
102; CHECK-NEXT:  i32.store  0
103define void @dont_fold_non_nuw_sub_store_2() {
104  store i32 5, ptr inttoptr (i32 sub (i32 ptrtoint (ptr @mylabel to i32), i32 4) to ptr), align 4
105  ret void
106}
107