Revert "[InstCombine] Support gep nuw in icmp folds" (#118698)
[llvm-project.git] / llvm / test / Transforms / GVNHoist / hoist-call.ll
blob01e6029c90b002c6acacc45d78ede02638c9e17a
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=gvn-hoist < %s | FileCheck %s
4 ; Check that the call and fcmp are hoisted.
5 define void @fun(float %__b, i1 %arg) minsize {
6 ; CHECK-LABEL: @fun(
7 ; CHECK-NEXT:  entry:
8 ; CHECK-NEXT:    br label [[IF_THEN:%.*]]
9 ; CHECK:       if.then:
10 ; CHECK-NEXT:    [[TMP0:%.*]] = call float @llvm.fabs.f32(float [[__B:%.*]])
11 ; CHECK-NEXT:    [[CMPINF7:%.*]] = fcmp oeq float [[TMP0]], 0x7FF0000000000000
12 ; CHECK-NEXT:    br i1 %arg, label [[IF_THEN8:%.*]], label [[LOR_LHS_FALSE:%.*]]
13 ; CHECK:       lor.lhs.false:
14 ; CHECK-NEXT:    unreachable
15 ; CHECK:       if.then8:
16 ; CHECK-NEXT:    ret void
18 entry:
19   br label %if.then
21 if.then:                                          ; preds = %entry
22   br i1 %arg, label %if.then8, label %lor.lhs.false
24 lor.lhs.false:                                    ; preds = %if.then
25   %0 = call float @llvm.fabs.f32(float %__b) #2
26   %cmpinf7 = fcmp oeq float %0, 0x7FF0000000000000
27   unreachable
29 if.then8:                                         ; preds = %if.then
30   %1 = call float @llvm.fabs.f32(float %__b) #2
31   %cmpinf10 = fcmp oeq float %1, 0x7FF0000000000000
32   ret void
35 declare float @llvm.fabs.f32(float)
37 ; Check that extractvalues are not hoisted into entry, but that non-dependent
38 ; adds are.
39 define i32 @foo(i32 %x) {
40 ; CHECK-LABEL: @foo(
41 ; CHECK-NEXT:  entry:
42 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], 1
43 ; CHECK-NEXT:    [[TMP0:%.*]] = callbr { i32, i32 } asm sideeffect "somestuff", "=r,=r,!i"()
44 ; CHECK-NEXT:    to label [[ASM_FALLTHROUGH:%.*]] [label %err.split]
45 ; CHECK:       asm.fallthrough:
46 ; CHECK-NEXT:    [[ASMRESULT:%.*]] = extractvalue { i32, i32 } [[TMP0]], 0
47 ; CHECK-NEXT:    ret i32 [[ADD]]
48 ; CHECK:       err.split:
49 ; CHECK-NEXT:    [[ASMRESULT2:%.*]] = extractvalue { i32, i32 } [[TMP0]], 0
50 ; CHECK-NEXT:    ret i32 [[ADD]]
52 entry:
53   %0 = callbr { i32, i32 } asm sideeffect "somestuff", "=r,=r,!i"()
54   to label %asm.fallthrough [label %err.split]
56 asm.fallthrough:                                  ; preds = %entry
57   %asmresult = extractvalue { i32, i32 } %0, 0
58   %add = add nsw i32 %x, 1
59   ret i32 %add
61 err.split:                                        ; preds = %entry
62   %asmresult2 = extractvalue { i32, i32 } %0, 0
63   %add2 = add nsw i32 %x, 1
64   ret i32 %add2
67 ; Check that extractvalues and dependent adds are not hoisted into entry.
68 define i32 @foo2() {
69 ; CHECK-LABEL: @foo2(
70 ; CHECK-NEXT:  entry:
71 ; CHECK-NEXT:    [[TMP0:%.*]] = callbr { i32, i32 } asm sideeffect "somestuff", "=r,=r,!i"()
72 ; CHECK-NEXT:    to label [[ASM_FALLTHROUGH:%.*]] [label %err.split]
73 ; CHECK:       asm.fallthrough:
74 ; CHECK-NEXT:    [[ASMRESULT:%.*]] = extractvalue { i32, i32 } [[TMP0]], 0
75 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[ASMRESULT]], 1
76 ; CHECK-NEXT:    ret i32 [[ADD]]
77 ; CHECK:       err.split:
78 ; CHECK-NEXT:    [[ASMRESULT2:%.*]] = extractvalue { i32, i32 } [[TMP0]], 0
79 ; CHECK-NEXT:    [[ADD2:%.*]] = add nsw i32 [[ASMRESULT2]], 1
80 ; CHECK-NEXT:    ret i32 [[ADD2]]
82 entry:
83   %0 = callbr { i32, i32 } asm sideeffect "somestuff", "=r,=r,!i"()
84   to label %asm.fallthrough [label %err.split]
86 asm.fallthrough:                                  ; preds = %entry
87   %asmresult = extractvalue { i32, i32 } %0, 0
88   %add = add nsw i32 %asmresult, 1
89   ret i32 %add
91 err.split:                                        ; preds = %entry
92   %asmresult2 = extractvalue { i32, i32 } %0, 0
93   %add2 = add nsw i32 %asmresult2, 1
94   ret i32 %add2
97 ; Ensure we don't hoist loads that are modified by callbr.
98 @x = global i32 0
99 define i32 @foo3() {
100 ; CHECK-LABEL: @foo3(
101 ; CHECK-NEXT:  entry:
102 ; CHECK-NEXT:    callbr void asm "", "=*m,!i"(ptr elementtype(i32) @x)
103 ; CHECK-NEXT:    to label [[ASM_FALLTHROUGH:%.*]] [label %err.split]
104 ; CHECK:       asm.fallthrough:
105 ; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @x, align 4
106 ; CHECK-NEXT:    ret i32 [[TMP0]]
107 ; CHECK:       err.split:
108 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr @x, align 4
109 ; CHECK-NEXT:    ret i32 [[TMP1]]
111 entry:
112   callbr void asm "", "=*m,!i"(ptr elementtype(i32) @x)
113   to label %asm.fallthrough [label %err.split]
115 asm.fallthrough:                                  ; preds = %entry
116   %0 = load i32, ptr @x
117   ret i32 %0
119 err.split:                                        ; preds = %entry
120   %1 = load i32, ptr @x
121   ret i32 %1
124 ; Ensure we do hoist loads that aren't modified by callbr, if the callbr has
125 ; the attribute memory(argmem:readwrite).
126 @y = global i32 0
127 define i32 @foo4() {
128 ; CHECK-LABEL: @foo4(
129 ; CHECK-NEXT:  entry:
130 ; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @y, align 4
131 ; CHECK-NEXT:    callbr void asm "", "=*m,!i"(ptr elementtype(i32) @x) #[[ATTR2:[0-9]+]]
132 ; CHECK-NEXT:    to label [[A:%.*]] [label %b]
133 ; CHECK:       a:
134 ; CHECK-NEXT:    ret i32 [[TMP0]]
135 ; CHECK:       b:
136 ; CHECK-NEXT:    ret i32 [[TMP0]]
138 entry:
139   callbr void asm "", "=*m,!i"(ptr elementtype(i32) @x) memory(argmem: readwrite)
140   to label %a [label %b]
142 a:                                  ; preds = %entry
143   %0 = load i32, ptr @y
144   ret i32 %0
146 b:                                        ; preds = %entry
147   %1 = load i32, ptr @y
148   ret i32 %1
151 ; Ensure we don't hoist loads that are modified by callbr, if the callbr has
152 ; the attribute memory(argmem:readwrite).
153 define i32 @foo5() {
154 ; CHECK-LABEL: @foo5(
155 ; CHECK-NEXT:  entry:
156 ; CHECK-NEXT:    callbr void asm "", "=*m,!i"(ptr elementtype(i32) @x) #[[ATTR2]]
157 ; CHECK-NEXT:    to label [[A:%.*]] [label %b]
158 ; CHECK:       a:
159 ; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @x, align 4
160 ; CHECK-NEXT:    ret i32 [[TMP0]]
161 ; CHECK:       b:
162 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr @x, align 4
163 ; CHECK-NEXT:    ret i32 [[TMP1]]
165 entry:
166   callbr void asm "", "=*m,!i"(ptr elementtype(i32) @x) memory(argmem: readwrite)
167   to label %a [label %b]
169 a:                                  ; preds = %entry
170   %0 = load i32, ptr @x
171   ret i32 %0
173 b:                                        ; preds = %entry
174   %1 = load i32, ptr @x
175   ret i32 %1
178 ; Ensure we hoist loads that are modified by callbr, if the callbr has the
179 ; attribute memory(argmem:none).
180 define i32 @foo6() {
181 ; CHECK-LABEL: @foo6(
182 ; CHECK-NEXT:  entry:
183 ; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @x, align 4
184 ; CHECK-NEXT:    callbr void asm "", "=*m,!i"(ptr elementtype(i32) @x) #[[ATTR3:[0-9]+]]
185 ; CHECK-NEXT:    to label [[A:%.*]] [label %b]
186 ; CHECK:       a:
187 ; CHECK-NEXT:    ret i32 [[TMP0]]
188 ; CHECK:       b:
189 ; CHECK-NEXT:    ret i32 [[TMP0]]
191 entry:
192   callbr void asm "", "=*m,!i"(ptr elementtype(i32) @x) memory(argmem: none)
193   to label %a [label %b]
195 a:                                  ; preds = %entry
196   %0 = load i32, ptr @x
197   ret i32 %0
199 b:                                        ; preds = %entry
200   %1 = load i32, ptr @x
201   ret i32 %1