|
1 | 1 | ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
|
2 | 2 | ; RUN: opt -S -passes=drop-unnecessary-assumes < %s | FileCheck %s
|
3 | 3 |
|
| 4 | +declare void @use(i32 %x) |
| 5 | +declare i32 @get() |
| 6 | + |
4 | 7 | define void @basic_dead(i32 %x) {
|
5 | 8 | ; CHECK-LABEL: define void @basic_dead(
|
6 | 9 | ; CHECK-SAME: i32 [[X:%.*]]) {
|
@@ -180,3 +183,136 @@ define void @type_test(ptr %x) {
|
180 | 183 | call void @llvm.assume(i1 %test)
|
181 | 184 | ret void
|
182 | 185 | }
|
| 186 | + |
| 187 | +define void @multiple_dead_conds(i32 %x) { |
| 188 | +; CHECK-LABEL: define void @multiple_dead_conds( |
| 189 | +; CHECK-SAME: i32 [[X:%.*]]) { |
| 190 | +; CHECK-NEXT: ret void |
| 191 | +; |
| 192 | + %cond1 = icmp sge i32 %x, 0 |
| 193 | + call void @llvm.assume(i1 %cond1) |
| 194 | + %cond2 = icmp ne i32 %x, 64 |
| 195 | + call void @llvm.assume(i1 %cond2) |
| 196 | + ret void |
| 197 | +} |
| 198 | + |
| 199 | +define void @multiple_dead_bundles(ptr %x) { |
| 200 | +; CHECK-LABEL: define void @multiple_dead_bundles( |
| 201 | +; CHECK-SAME: ptr [[X:%.*]]) { |
| 202 | +; CHECK-NEXT: ret void |
| 203 | +; |
| 204 | + call void @llvm.assume(i1 true) ["align"(ptr %x, i64 8), "nonnull"(ptr %x)] |
| 205 | + ret void |
| 206 | +} |
| 207 | + |
| 208 | +; The assume is eliminated, but currently leaves behind a dead cycle. |
| 209 | +define void @dead_cycle(i1 %loop.cond) { |
| 210 | +; CHECK-LABEL: define void @dead_cycle( |
| 211 | +; CHECK-SAME: i1 [[LOOP_COND:%.*]]) { |
| 212 | +; CHECK-NEXT: [[ENTRY:.*]]: |
| 213 | +; CHECK-NEXT: br label %[[LOOP:.*]] |
| 214 | +; CHECK: [[LOOP]]: |
| 215 | +; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] |
| 216 | +; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 |
| 217 | +; CHECK-NEXT: br i1 [[LOOP_COND]], label %[[LOOP]], label %[[EXIT:.*]] |
| 218 | +; CHECK: [[EXIT]]: |
| 219 | +; CHECK-NEXT: ret void |
| 220 | +; |
| 221 | +entry: |
| 222 | + br label %loop |
| 223 | + |
| 224 | +loop: |
| 225 | + %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] |
| 226 | + %cond = icmp ne i32 %iv, 64 |
| 227 | + call void @llvm.assume(i1 %cond) |
| 228 | + %iv.next = add i32 %iv, 1 |
| 229 | + br i1 %loop.cond, label %loop, label %exit |
| 230 | + |
| 231 | +exit: |
| 232 | + ret void |
| 233 | +} |
| 234 | + |
| 235 | +define void @use_in_side_effect(i32 %x) { |
| 236 | +; CHECK-LABEL: define void @use_in_side_effect( |
| 237 | +; CHECK-SAME: i32 [[X:%.*]]) { |
| 238 | +; CHECK-NEXT: [[COND:%.*]] = icmp sge i32 [[X]], 0 |
| 239 | +; CHECK-NEXT: call void @llvm.assume(i1 [[COND]]) |
| 240 | +; CHECK-NEXT: call void @use(i32 [[X]]) |
| 241 | +; CHECK-NEXT: ret void |
| 242 | +; |
| 243 | + %cond = icmp sge i32 %x, 0 |
| 244 | + call void @llvm.assume(i1 %cond) |
| 245 | + call void @use(i32 %x) |
| 246 | + ret void |
| 247 | +} |
| 248 | + |
| 249 | +define void @indirect_use_in_side_effect(i32 %x) { |
| 250 | +; CHECK-LABEL: define void @indirect_use_in_side_effect( |
| 251 | +; CHECK-SAME: i32 [[X:%.*]]) { |
| 252 | +; CHECK-NEXT: [[COND:%.*]] = icmp sge i32 [[X]], 0 |
| 253 | +; CHECK-NEXT: call void @llvm.assume(i1 [[COND]]) |
| 254 | +; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X]], 1 |
| 255 | +; CHECK-NEXT: call void @use(i32 [[ADD]]) |
| 256 | +; CHECK-NEXT: ret void |
| 257 | +; |
| 258 | + %cond = icmp sge i32 %x, 0 |
| 259 | + call void @llvm.assume(i1 %cond) |
| 260 | + %add = add i32 %x, 1 |
| 261 | + call void @use(i32 %add) |
| 262 | + ret void |
| 263 | +} |
| 264 | + |
| 265 | +; The affected value itself has a side effect, but we can still drop the |
| 266 | +; assume. |
| 267 | +define void @affected_value_has_side_effect() { |
| 268 | +; CHECK-LABEL: define void @affected_value_has_side_effect() { |
| 269 | +; CHECK-NEXT: [[X:%.*]] = call i32 @get() |
| 270 | +; CHECK-NEXT: ret void |
| 271 | +; |
| 272 | + %x = call i32 @get() |
| 273 | + %cond = icmp sge i32 %x, 0 |
| 274 | + call void @llvm.assume(i1 %cond) |
| 275 | + ret void |
| 276 | +} |
| 277 | + |
| 278 | +define i32 @affected_value_has_side_effect_and_is_used() { |
| 279 | +; CHECK-LABEL: define i32 @affected_value_has_side_effect_and_is_used() { |
| 280 | +; CHECK-NEXT: [[X:%.*]] = call i32 @get() |
| 281 | +; CHECK-NEXT: [[COND:%.*]] = icmp sge i32 [[X]], 0 |
| 282 | +; CHECK-NEXT: call void @llvm.assume(i1 [[COND]]) |
| 283 | +; CHECK-NEXT: ret i32 [[X]] |
| 284 | +; |
| 285 | + %x = call i32 @get() |
| 286 | + %cond = icmp sge i32 %x, 0 |
| 287 | + call void @llvm.assume(i1 %cond) |
| 288 | + ret i32 %x |
| 289 | +} |
| 290 | + |
| 291 | +@g = external global i8 |
| 292 | +@g2 = external global i8 |
| 293 | + |
| 294 | +; Assumes on globals are currently not supported. |
| 295 | +define void @assume_on_global() { |
| 296 | +; CHECK-LABEL: define void @assume_on_global() { |
| 297 | +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr @g, i64 8) ] |
| 298 | +; CHECK-NEXT: ret void |
| 299 | +; |
| 300 | + call void @llvm.assume(i1 true) ["align"(ptr @g, i64 8)] |
| 301 | + ret void |
| 302 | +} |
| 303 | + |
| 304 | +define void @assume_on_global_used_in_other_func() { |
| 305 | +; CHECK-LABEL: define void @assume_on_global_used_in_other_func() { |
| 306 | +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr @g2, i64 8) ] |
| 307 | +; CHECK-NEXT: ret void |
| 308 | +; |
| 309 | + call void @llvm.assume(i1 true) ["align"(ptr @g2, i64 8)] |
| 310 | + ret void |
| 311 | +} |
| 312 | + |
| 313 | +define ptr @other_func() { |
| 314 | +; CHECK-LABEL: define ptr @other_func() { |
| 315 | +; CHECK-NEXT: ret ptr @g2 |
| 316 | +; |
| 317 | + ret ptr @g2 |
| 318 | +} |
0 commit comments