| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; RUN: opt -S -passes=guard-widening < %s | FileCheck %s |
| |
| declare void @llvm.experimental.deoptimize.isVoid(...) |
| declare i1 @llvm.experimental.widenable.condition() |
| |
| ; In the current scheme we widen `br i1 %and1`, so we try to build |
| ; `and i1 poison, %and1` using `%call0` as insertion point. |
| ; That's not possible, so widening will not occur in the case. |
| ; TODO: Widen `%call0` in the test case, not a branch. |
| define void @test() { |
| ; CHECK-LABEL: @test( |
| ; CHECK-NEXT: bb0: |
| ; CHECK-NEXT: [[CALL0:%.*]] = call i1 @llvm.experimental.widenable.condition() |
| ; CHECK-NEXT: [[AND0:%.*]] = and i1 false, [[CALL0]] |
| ; CHECK-NEXT: [[AND1:%.*]] = and i1 false, [[AND0]] |
| ; CHECK-NEXT: br i1 [[AND1]], label [[BB1:%.*]], label [[DEOPT:%.*]] |
| ; CHECK: bb1: |
| ; CHECK-NEXT: [[CALL1:%.*]] = call i1 @llvm.experimental.widenable.condition() |
| ; CHECK-NEXT: [[AND2:%.*]] = and i1 poison, [[CALL1]] |
| ; CHECK-NEXT: br i1 [[AND2]], label [[UNREACH:%.*]], label [[DEOPT]] |
| ; CHECK: unreach: |
| ; CHECK-NEXT: unreachable |
| ; CHECK: deopt: |
| ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid(i32 0) [ "deopt"(i32 0) ] |
| ; CHECK-NEXT: ret void |
| ; |
| bb0: |
| %call0 = call i1 @llvm.experimental.widenable.condition() |
| %and0 = and i1 false, %call0 |
| %and1 = and i1 false, %and0 |
| br i1 %and1, label %bb1, label %deopt |
| |
| bb1: |
| %call1 = call i1 @llvm.experimental.widenable.condition() |
| %and2 = and i1 poison, %call1 |
| br i1 %and2, label %unreach, label %deopt |
| |
| unreach: |
| unreachable |
| |
| deopt: |
| call void (...) @llvm.experimental.deoptimize.isVoid(i32 0) [ "deopt"(i32 0) ] |
| ret void |
| } |