Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / SimplifyCFG / unprofitable-pr.ll
blob709a83b45a403d49140af0a85a742ce0a271bf8e
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -simplifycfg-max-small-block-size=6 -S < %s | FileCheck %s
3 ; RUN: opt -passes=simplifycfg -simplifycfg-max-small-block-size=6 -S < %s | FileCheck %s
5 target datalayout = "e-p:64:64-p5:32:32-A5"
7 declare void @llvm.assume(i1)
8 declare i1 @llvm.type.test(ptr, metadata) nounwind readnone
10 define void @test_01(i1 %c, ptr align 1 %ptr) local_unnamed_addr #0 {
11 ; CHECK-LABEL: @test_01(
12 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[TRUE2_CRITEDGE:%.*]], label [[FALSE1:%.*]]
13 ; CHECK:       false1:
14 ; CHECK-NEXT:    store volatile i64 1, ptr [[PTR:%.*]], align 4
15 ; CHECK-NEXT:    [[PTRINT:%.*]] = ptrtoint ptr [[PTR]] to i64
16 ; CHECK-NEXT:    [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 7
17 ; CHECK-NEXT:    [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
18 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[MASKCOND]])
19 ; CHECK-NEXT:    store volatile i64 0, ptr [[PTR]], align 8
20 ; CHECK-NEXT:    store volatile i64 3, ptr [[PTR]], align 8
21 ; CHECK-NEXT:    br label [[COMMON_RET:%.*]]
22 ; CHECK:       common.ret:
23 ; CHECK-NEXT:    ret void
24 ; CHECK:       true2.critedge:
25 ; CHECK-NEXT:    [[PTRINT_C:%.*]] = ptrtoint ptr [[PTR]] to i64
26 ; CHECK-NEXT:    [[MASKEDPTR_C:%.*]] = and i64 [[PTRINT_C]], 7
27 ; CHECK-NEXT:    [[MASKCOND_C:%.*]] = icmp eq i64 [[MASKEDPTR_C]], 0
28 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[MASKCOND_C]])
29 ; CHECK-NEXT:    store volatile i64 0, ptr [[PTR]], align 8
30 ; CHECK-NEXT:    store volatile i64 2, ptr [[PTR]], align 8
31 ; CHECK-NEXT:    br label [[COMMON_RET]]
33   br i1 %c, label %true1, label %false1
35 true1:                                            ; preds = %false1, %0
36   %ptrint = ptrtoint ptr %ptr to i64
37   %maskedptr = and i64 %ptrint, 7
38   %maskcond = icmp eq i64 %maskedptr, 0
39   tail call void @llvm.assume(i1 %maskcond)
40   store volatile i64 0, ptr %ptr, align 8
41   br i1 %c, label %true2, label %false2
43 false1:                                           ; preds = %0
44   store volatile i64 1, ptr %ptr, align 4
45   br label %true1
47 true2:                                            ; preds = %true1
48   store volatile i64 2, ptr %ptr, align 8
49   ret void
51 false2:                                           ; preds = %true1
52   store volatile i64 3, ptr %ptr, align 8
53   ret void
56 ; Corner case: the block has max possible size for which we still do PRE.
57 define void @test_02(i1 %c, ptr align 1 %ptr) local_unnamed_addr #0 {
58 ; CHECK-LABEL: @test_02(
59 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[TRUE2_CRITEDGE:%.*]], label [[FALSE1:%.*]]
60 ; CHECK:       false1:
61 ; CHECK-NEXT:    store volatile i64 1, ptr [[PTR:%.*]], align 4
62 ; CHECK-NEXT:    [[PTRINT:%.*]] = ptrtoint ptr [[PTR]] to i64
63 ; CHECK-NEXT:    [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 7
64 ; CHECK-NEXT:    [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
65 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[MASKCOND]])
66 ; CHECK-NEXT:    store volatile i64 0, ptr [[PTR]], align 8
67 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
68 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
69 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
70 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
71 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
72 ; CHECK-NEXT:    store volatile i64 3, ptr [[PTR]], align 8
73 ; CHECK-NEXT:    br label [[COMMON_RET:%.*]]
74 ; CHECK:       common.ret:
75 ; CHECK-NEXT:    ret void
76 ; CHECK:       true2.critedge:
77 ; CHECK-NEXT:    [[PTRINT_C:%.*]] = ptrtoint ptr [[PTR]] to i64
78 ; CHECK-NEXT:    [[MASKEDPTR_C:%.*]] = and i64 [[PTRINT_C]], 7
79 ; CHECK-NEXT:    [[MASKCOND_C:%.*]] = icmp eq i64 [[MASKEDPTR_C]], 0
80 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[MASKCOND_C]])
81 ; CHECK-NEXT:    store volatile i64 0, ptr [[PTR]], align 8
82 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
83 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
84 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
85 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
86 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
87 ; CHECK-NEXT:    store volatile i64 2, ptr [[PTR]], align 8
88 ; CHECK-NEXT:    br label [[COMMON_RET]]
90   br i1 %c, label %true1, label %false1
92 true1:                                            ; preds = %false1, %0
93   %ptrint = ptrtoint ptr %ptr to i64
94   %maskedptr = and i64 %ptrint, 7
95   %maskcond = icmp eq i64 %maskedptr, 0
96   tail call void @llvm.assume(i1 %maskcond)
97   store volatile i64 0, ptr %ptr, align 8
98   store volatile i64 -1, ptr %ptr, align 8
99   store volatile i64 -1, ptr %ptr, align 8
100   store volatile i64 -1, ptr %ptr, align 8
101   store volatile i64 -1, ptr %ptr, align 8
102   store volatile i64 -1, ptr %ptr, align 8
103   br i1 %c, label %true2, label %false2
105 false1:                                           ; preds = %0
106   store volatile i64 1, ptr %ptr, align 4
107   br label %true1
109 true2:                                            ; preds = %true1
110   store volatile i64 2, ptr %ptr, align 8
111   ret void
113 false2:                                           ; preds = %true1
114   store volatile i64 3, ptr %ptr, align 8
115   ret void
118 ; This block is too huge for PRE.
119 define void @test_03(i1 %c, ptr align 1 %ptr) local_unnamed_addr #0 {
120 ; CHECK-LABEL: @test_03(
121 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[TRUE1:%.*]], label [[FALSE1:%.*]]
122 ; CHECK:       true1:
123 ; CHECK-NEXT:    [[PTRINT:%.*]] = ptrtoint ptr [[PTR:%.*]] to i64
124 ; CHECK-NEXT:    [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 7
125 ; CHECK-NEXT:    [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
126 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[MASKCOND]])
127 ; CHECK-NEXT:    store volatile i64 0, ptr [[PTR]], align 8
128 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
129 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
130 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
131 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
132 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
133 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
134 ; CHECK-NEXT:    br i1 [[C]], label [[TRUE2:%.*]], label [[FALSE2:%.*]]
135 ; CHECK:       false1:
136 ; CHECK-NEXT:    store volatile i64 1, ptr [[PTR]], align 4
137 ; CHECK-NEXT:    br label [[TRUE1]]
138 ; CHECK:       common.ret:
139 ; CHECK-NEXT:    ret void
140 ; CHECK:       true2:
141 ; CHECK-NEXT:    store volatile i64 2, ptr [[PTR]], align 8
142 ; CHECK-NEXT:    br label [[COMMON_RET:%.*]]
143 ; CHECK:       false2:
144 ; CHECK-NEXT:    store volatile i64 3, ptr [[PTR]], align 8
145 ; CHECK-NEXT:    br label [[COMMON_RET]]
147   br i1 %c, label %true1, label %false1
149 true1:                                            ; preds = %false1, %0
150   %ptrint = ptrtoint ptr %ptr to i64
151   %maskedptr = and i64 %ptrint, 7
152   %maskcond = icmp eq i64 %maskedptr, 0
153   tail call void @llvm.assume(i1 %maskcond)
154   store volatile i64 0, ptr %ptr, align 8
155   store volatile i64 -1, ptr %ptr, align 8
156   store volatile i64 -1, ptr %ptr, align 8
157   store volatile i64 -1, ptr %ptr, align 8
158   store volatile i64 -1, ptr %ptr, align 8
159   store volatile i64 -1, ptr %ptr, align 8
160   store volatile i64 -1, ptr %ptr, align 8
161   br i1 %c, label %true2, label %false2
163 false1:                                           ; preds = %0
164   store volatile i64 1, ptr %ptr, align 4
165   br label %true1
167 true2:                                            ; preds = %true1
168   store volatile i64 2, ptr %ptr, align 8
169   ret void
171 false2:                                           ; preds = %true1
172   store volatile i64 3, ptr %ptr, align 8
173   ret void
176 ; Try the max block size for PRE again but with the bitcast/type test/assume
177 ; sequence used for whole program devirt.
178 define void @test_04(i1 %c, ptr align 1 %ptr, ptr %vtable) local_unnamed_addr #0 {
179 ; CHECK-LABEL: @test_04(
180 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[TRUE2_CRITEDGE:%.*]], label [[FALSE1:%.*]]
181 ; CHECK:       false1:
182 ; CHECK-NEXT:    store volatile i64 1, ptr [[PTR:%.*]], align 4
183 ; CHECK-NEXT:    [[P:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE:%.*]], metadata !"foo")
184 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[P]])
185 ; CHECK-NEXT:    store volatile i64 0, ptr [[PTR]], align 8
186 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
187 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
188 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
189 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
190 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
191 ; CHECK-NEXT:    store volatile i64 3, ptr [[PTR]], align 8
192 ; CHECK-NEXT:    br label [[COMMON_RET:%.*]]
193 ; CHECK:       common.ret:
194 ; CHECK-NEXT:    ret void
195 ; CHECK:       true2.critedge:
196 ; CHECK-NEXT:    [[P_C:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"foo")
197 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[P_C]])
198 ; CHECK-NEXT:    store volatile i64 0, ptr [[PTR]], align 8
199 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
200 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
201 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
202 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
203 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
204 ; CHECK-NEXT:    store volatile i64 2, ptr [[PTR]], align 8
205 ; CHECK-NEXT:    br label [[COMMON_RET]]
207   br i1 %c, label %true1, label %false1
209 true1:                                            ; preds = %false1, %0
210   %p = call i1 @llvm.type.test(ptr %vtable, metadata !"foo")
211   tail call void @llvm.assume(i1 %p)
212   store volatile i64 0, ptr %ptr, align 8
213   store volatile i64 -1, ptr %ptr, align 8
214   store volatile i64 -1, ptr %ptr, align 8
215   store volatile i64 -1, ptr %ptr, align 8
216   store volatile i64 -1, ptr %ptr, align 8
217   store volatile i64 -1, ptr %ptr, align 8
218   br i1 %c, label %true2, label %false2
220 false1:                                           ; preds = %0
221   store volatile i64 1, ptr %ptr, align 4
222   br label %true1
224 true2:                                            ; preds = %true1
225   store volatile i64 2, ptr %ptr, align 8
226   ret void
228 false2:                                           ; preds = %true1
229   store volatile i64 3, ptr %ptr, align 8
230   ret void
233 ; The load, icmp and assume should not count towards the limit, they are
234 ; ephemeral.
235 define void @test_non_speculatable(i1 %c, ptr align 1 %ptr, ptr %ptr2) local_unnamed_addr #0 {
236 ; CHECK-LABEL: @test_non_speculatable(
237 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[TRUE2_CRITEDGE:%.*]], label [[FALSE1:%.*]]
238 ; CHECK:       false1:
239 ; CHECK-NEXT:    store volatile i64 1, ptr [[PTR:%.*]], align 4
240 ; CHECK-NEXT:    [[V:%.*]] = load i8, ptr [[PTR2:%.*]], align 1
241 ; CHECK-NEXT:    [[C2:%.*]] = icmp eq i8 [[V]], 42
242 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C2]])
243 ; CHECK-NEXT:    store volatile i64 0, ptr [[PTR]], align 8
244 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
245 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
246 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
247 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
248 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
249 ; CHECK-NEXT:    store volatile i64 3, ptr [[PTR]], align 8
250 ; CHECK-NEXT:    br label [[COMMON_RET:%.*]]
251 ; CHECK:       common.ret:
252 ; CHECK-NEXT:    ret void
253 ; CHECK:       true2.critedge:
254 ; CHECK-NEXT:    [[V_C:%.*]] = load i8, ptr [[PTR2]], align 1
255 ; CHECK-NEXT:    [[C2_C:%.*]] = icmp eq i8 [[V_C]], 42
256 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C2_C]])
257 ; CHECK-NEXT:    store volatile i64 0, ptr [[PTR]], align 8
258 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
259 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
260 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
261 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
262 ; CHECK-NEXT:    store volatile i64 -1, ptr [[PTR]], align 8
263 ; CHECK-NEXT:    store volatile i64 2, ptr [[PTR]], align 8
264 ; CHECK-NEXT:    br label [[COMMON_RET]]
266   br i1 %c, label %true1, label %false1
268 true1:                                            ; preds = %false1, %0
269   %v = load i8, ptr %ptr2
270   %c2 = icmp eq i8 %v, 42
271   call void @llvm.assume(i1 %c2)
272   store volatile i64 0, ptr %ptr, align 8
273   store volatile i64 -1, ptr %ptr, align 8
274   store volatile i64 -1, ptr %ptr, align 8
275   store volatile i64 -1, ptr %ptr, align 8
276   store volatile i64 -1, ptr %ptr, align 8
277   store volatile i64 -1, ptr %ptr, align 8
278   br i1 %c, label %true2, label %false2
280 false1:                                           ; preds = %0
281   store volatile i64 1, ptr %ptr, align 4
282   br label %true1
284 true2:                                            ; preds = %true1
285   store volatile i64 2, ptr %ptr, align 8
286   ret void
288 false2:                                           ; preds = %true1
289   store volatile i64 3, ptr %ptr, align 8
290   ret void