BI->setCondition(AllChecks);
if (InsertAssumesOfPredicatedGuardsConditions) {
Builder.SetInsertPoint(IfTrueBB, IfTrueBB->getFirstInsertionPt());
- Builder.CreateAssumption(Cond);
+ // If this block has other predecessors, we might not be able to use Cond.
+ // In this case, create a Phi where every other input is `true` and input
+ // from guard block is Cond.
+ Value *AssumeCond = Cond;
+ if (!IfTrueBB->getUniquePredecessor()) {
+ auto *GuardBB = BI->getParent();
+ auto *PN = Builder.CreatePHI(Cond->getType(), pred_size(IfTrueBB),
+ "assume.cond");
+ for (auto *Pred : predecessors(IfTrueBB))
+ PN->addIncoming(Pred == GuardBB ? Cond : Builder.getTrue(), Pred);
+ AssumeCond = PN;
+ }
+ Builder.CreateAssumption(AssumeCond);
}
RecursivelyDeleteTriviallyDeadInstructions(OldCond, nullptr /* TLI */, MSSAU);
assert(isGuardAsWidenableBranch(BI) &&
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -passes=loop-predication < %s 2>&1 | FileCheck %s
-; REQUIRES: asserts
-; XFAIL: *
declare void @llvm.experimental.deoptimize.isVoid(...)
-; FIXME: Loop predication here inserts assume across the critical edge, and
-; it leads to malformed IR (assume's condition does not dominate it).
define void @test_01(i1 %cond) {
-; CHECK-LABEL: test
+; CHECK-LABEL: @test_01(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[INST:%.*]] = call i1 @llvm.experimental.widenable.condition()
+; CHECK-NEXT: [[TMP0:%.*]] = and i1 true, [[INST]]
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: unreached:
+; CHECK-NEXT: unreachable
+; CHECK: loop:
+; CHECK-NEXT: [[INST3:%.*]] = phi i32 [ 0, [[BB:%.*]] ], [ [[INST4:%.*]], [[BACKEDGE:%.*]] ]
+; CHECK-NEXT: [[INST4]] = add nsw i32 [[INST3]], 1
+; CHECK-NEXT: br i1 [[COND:%.*]], label [[BACKEDGE]], label [[GUARD_BLOCK:%.*]]
+; CHECK: normal_ret:
+; CHECK-NEXT: ret void
+; CHECK: backedge:
+; CHECK-NEXT: [[ASSUME_COND:%.*]] = phi i1 [ [[INST9:%.*]], [[GUARD_BLOCK]] ], [ true, [[LOOP]] ]
+; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME_COND]])
+; CHECK-NEXT: [[INST7:%.*]] = icmp sgt i32 [[INST3]], 137
+; CHECK-NEXT: br i1 [[INST7]], label [[UNREACHED:%.*]], label [[LOOP]]
+; CHECK: guard_block:
+; CHECK-NEXT: [[INST9]] = icmp ult i32 [[INST4]], 10000
+; CHECK-NEXT: br i1 [[TMP0]], label [[BACKEDGE]], label [[DEOPT:%.*]]
+; CHECK: deopt:
+; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid(i32 13) [ "deopt"() ]
+; CHECK-NEXT: ret void
+; CHECK: done:
+; CHECK-NEXT: ret void
+;
bb:
%inst = call i1 @llvm.experimental.widenable.condition()
br label %loop