forked from OSchip/llvm-project
Revert "[InstCombine] Simplify boolean Phis with const inputs using CFG"
This reverts commit 00472067c3
.
Need to fix failing clang tests.
This commit is contained in:
parent
fc55308628
commit
b893822e32
|
@ -1129,75 +1129,6 @@ Instruction *InstCombiner::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) {
|
|||
return replaceInstUsesWith(FirstPhi, Undef);
|
||||
}
|
||||
|
||||
static Value *SimplifyUsingControlFlow(InstCombiner &Self, PHINode &PN,
|
||||
const DominatorTree &DT) {
|
||||
// Simplify the following patterns:
|
||||
// if (cond)
|
||||
// / \
|
||||
// ... ...
|
||||
// \ /
|
||||
// phi [true] [false]
|
||||
if (!PN.getType()->isIntegerTy(1))
|
||||
return nullptr;
|
||||
|
||||
if (PN.getNumOperands() != 2)
|
||||
return nullptr;
|
||||
|
||||
// Make sure all inputs are constants.
|
||||
if (!all_of(PN.operands(), [](Value *V) { return isa<ConstantInt>(V); }))
|
||||
return nullptr;
|
||||
|
||||
BasicBlock *BB = PN.getParent();
|
||||
// Do not bother with unreachable instructions.
|
||||
if (!DT.isReachableFromEntry(BB))
|
||||
return nullptr;
|
||||
|
||||
// Same inputs.
|
||||
if (PN.getOperand(0) == PN.getOperand(1))
|
||||
return PN.getOperand(0);
|
||||
|
||||
BasicBlock *TruePred = nullptr, *FalsePred = nullptr;
|
||||
for (auto *Pred : predecessors(BB)) {
|
||||
auto *Input = cast<ConstantInt>(PN.getIncomingValueForBlock(Pred));
|
||||
if (Input->isAllOnesValue())
|
||||
TruePred = Pred;
|
||||
else
|
||||
FalsePred = Pred;
|
||||
}
|
||||
assert(TruePred && FalsePred && "Must be!");
|
||||
|
||||
// Check which edge of the dominator dominates the true input. If it is the
|
||||
// false edge, we should invert the condition.
|
||||
auto *IDom = DT.getNode(BB)->getIDom()->getBlock();
|
||||
auto *BI = dyn_cast<BranchInst>(IDom->getTerminator());
|
||||
if (!BI || BI->isUnconditional())
|
||||
return nullptr;
|
||||
|
||||
// Check that edges outgoing from the idom's terminators dominate respective
|
||||
// inputs of the Phi.
|
||||
BasicBlockEdge TrueOutEdge(IDom, BI->getSuccessor(0));
|
||||
BasicBlockEdge FalseOutEdge(IDom, BI->getSuccessor(1));
|
||||
|
||||
BasicBlockEdge TrueIncEdge(TruePred, BB);
|
||||
BasicBlockEdge FalseIncEdge(FalsePred, BB);
|
||||
|
||||
auto *Cond = BI->getCondition();
|
||||
if (DT.dominates(TrueOutEdge, TrueIncEdge) &&
|
||||
DT.dominates(FalseOutEdge, FalseIncEdge))
|
||||
// This Phi is actually equivalent to branching condition of IDom.
|
||||
return Cond;
|
||||
else if (DT.dominates(TrueOutEdge, FalseIncEdge) &&
|
||||
DT.dominates(FalseOutEdge, TrueIncEdge)) {
|
||||
// This Phi is actually opposite to branching condition of IDom. We invert
|
||||
// the condition that will potentially open up some opportunities for
|
||||
// sinking.
|
||||
Self.Builder.SetInsertPoint(BB->getFirstNonPHI());
|
||||
return Self.Builder.CreateNot(Cond);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// PHINode simplification
|
||||
//
|
||||
Instruction *InstCombiner::visitPHINode(PHINode &PN) {
|
||||
|
@ -1345,9 +1276,5 @@ Instruction *InstCombiner::visitPHINode(PHINode &PN) {
|
|||
if (Instruction *Res = SliceUpIllegalIntegerPHI(PN))
|
||||
return Res;
|
||||
|
||||
// Ultimately, try to replace this Phi with a dominating condition.
|
||||
if (auto *V = SimplifyUsingControlFlow(*this, PN, DT))
|
||||
return replaceInstUsesWith(PN, V);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -74,8 +74,8 @@ declare void @dummy1(%struct.bitmap*, %struct.bitmap*, %struct.bitmap*, %struct.
|
|||
;CHECK-LABEL: NextCond.split:
|
||||
;CHECK: call void @dummy3()
|
||||
;CheCK-LABEL: CallSiteBB:
|
||||
;CHECK: [[NEG:%.*]] = xor i1 %tobool1, true
|
||||
;CHECK: call void @foo(i1 [[NEG]])
|
||||
;CHECK: %phi.call = phi i1 [ true, %NextCond.split ], [ false, %Top.split ]
|
||||
;CHECK: call void @foo(i1 %phi.call)
|
||||
define void @caller2(i1 %c, %struct.bitmap* %a_elt, %struct.bitmap* %b_elt, %struct.bitmap* %c_elt) {
|
||||
entry:
|
||||
br label %Top
|
||||
|
|
|
@ -32,6 +32,7 @@ patatino:
|
|||
ret i32 %x
|
||||
}
|
||||
|
||||
; TODO: Simplify this to "ret cond".
|
||||
define i1 @test01(i1 %cond) {
|
||||
; CHECK-LABEL: @test01(
|
||||
; CHECK-NEXT: entry:
|
||||
|
@ -41,13 +42,15 @@ define i1 @test01(i1 %cond) {
|
|||
; CHECK: if.false.1:
|
||||
; CHECK-NEXT: br label [[MERGE_1]]
|
||||
; CHECK: merge.1:
|
||||
; CHECK-NEXT: br i1 [[COND]], label [[IF_TRUE_2:%.*]], label [[IF_FALSE_2:%.*]]
|
||||
; CHECK-NEXT: [[MERGE_COND_1:%.*]] = phi i1 [ true, [[IF_TRUE_1]] ], [ false, [[IF_FALSE_1]] ]
|
||||
; CHECK-NEXT: br i1 [[MERGE_COND_1]], label [[IF_TRUE_2:%.*]], label [[IF_FALSE_2:%.*]]
|
||||
; CHECK: if.true.2:
|
||||
; CHECK-NEXT: br label [[MERGE_2:%.*]]
|
||||
; CHECK: if.false.2:
|
||||
; CHECK-NEXT: br label [[MERGE_2]]
|
||||
; CHECK: merge.2:
|
||||
; CHECK-NEXT: ret i1 [[COND]]
|
||||
; CHECK-NEXT: [[MERGE_COND_2:%.*]] = phi i1 [ true, [[IF_TRUE_2]] ], [ false, [[IF_FALSE_2]] ]
|
||||
; CHECK-NEXT: ret i1 [[MERGE_COND_2]]
|
||||
;
|
||||
entry:
|
||||
br i1 %cond, label %if.true.1, label %if.false.1
|
||||
|
@ -73,6 +76,7 @@ merge.2:
|
|||
ret i1 %merge.cond.2
|
||||
}
|
||||
|
||||
; TODO: Simplify this to "ret %cond".
|
||||
define i1 @test02(i1 %cond) {
|
||||
; CHECK-LABEL: @test02(
|
||||
; CHECK-NEXT: entry:
|
||||
|
@ -82,13 +86,15 @@ define i1 @test02(i1 %cond) {
|
|||
; CHECK: if.false.1:
|
||||
; CHECK-NEXT: br label [[MERGE_1]]
|
||||
; CHECK: merge.1:
|
||||
; CHECK-NEXT: br i1 [[COND]], label [[IF_FALSE_2:%.*]], label [[IF_TRUE_2:%.*]]
|
||||
; CHECK-NEXT: [[MERGE_COND_1:%.*]] = phi i1 [ false, [[IF_TRUE_1]] ], [ true, [[IF_FALSE_1]] ]
|
||||
; CHECK-NEXT: br i1 [[MERGE_COND_1]], label [[IF_TRUE_2:%.*]], label [[IF_FALSE_2:%.*]]
|
||||
; CHECK: if.true.2:
|
||||
; CHECK-NEXT: br label [[MERGE_2:%.*]]
|
||||
; CHECK: if.false.2:
|
||||
; CHECK-NEXT: br label [[MERGE_2]]
|
||||
; CHECK: merge.2:
|
||||
; CHECK-NEXT: ret i1 [[COND]]
|
||||
; CHECK-NEXT: [[MERGE_COND_2:%.*]] = phi i1 [ false, [[IF_TRUE_2]] ], [ true, [[IF_FALSE_2]] ]
|
||||
; CHECK-NEXT: ret i1 [[MERGE_COND_2]]
|
||||
;
|
||||
entry:
|
||||
br i1 %cond, label %if.true.1, label %if.false.1
|
||||
|
|
|
@ -11,10 +11,10 @@ define i1 @test_eq(i1 %cond) {
|
|||
; CHECK: if.false:
|
||||
; CHECK-NEXT: br label [[MERGE]]
|
||||
; CHECK: merge:
|
||||
; CHECK-NEXT: [[COMPARE:%.*]] = phi i1 [ true, [[IF_FALSE]] ], [ false, [[IF_TRUE]] ]
|
||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[COND]], true
|
||||
; CHECK-NEXT: ret i1 [[TMP0]]
|
||||
; CHECK-NEXT: ret i1 [[COMPARE]]
|
||||
;
|
||||
entry:
|
||||
br i1 %cond, label %if.true, label %if.false
|
||||
|
@ -43,9 +43,10 @@ define i1 @test_slt(i1 %cond) {
|
|||
; CHECK: if.false:
|
||||
; CHECK-NEXT: br label [[MERGE]]
|
||||
; CHECK: merge:
|
||||
; CHECK-NEXT: [[COMPARE:%.*]] = phi i1 [ false, [[IF_FALSE]] ], [ true, [[IF_TRUE]] ]
|
||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: ret i1 [[COND]]
|
||||
; CHECK-NEXT: ret i1 [[COMPARE]]
|
||||
;
|
||||
entry:
|
||||
br i1 %cond, label %if.true, label %if.false
|
||||
|
@ -105,9 +106,10 @@ define i1 @test_ne(i1 %cond) {
|
|||
; CHECK: if.false:
|
||||
; CHECK-NEXT: br label [[MERGE]]
|
||||
; CHECK: merge:
|
||||
; CHECK-NEXT: [[COMPARE:%.*]] = phi i1 [ false, [[IF_FALSE]] ], [ true, [[IF_TRUE]] ]
|
||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: ret i1 [[COND]]
|
||||
; CHECK-NEXT: ret i1 [[COMPARE]]
|
||||
;
|
||||
entry:
|
||||
br i1 %cond, label %if.true, label %if.false
|
||||
|
|
|
@ -416,11 +416,10 @@ bb1: ; preds = %entry
|
|||
|
||||
bb2: ; preds = %bb1, %entry
|
||||
%cond = phi i1 [ true, %bb1 ], [ false, %entry ] ; <i1> [#uses=1]
|
||||
; CHECK-NOT: phi i1
|
||||
; CHECK: %res = phi i32 [ %0, %bb1 ], [ 0, %entry ]
|
||||
; CHECK: ret i32 %res
|
||||
; CHECK-NOT: %val = phi i32 [ %0, %bb1 ], [ 0, %entry ]
|
||||
%val = phi i32 [ %0, %bb1 ], [ 0, %entry ] ; <i32> [#uses=1]
|
||||
%res = select i1 %cond, i32 %val, i32 0 ; <i32> [#uses=1]
|
||||
; CHECK: ret i32 %cond
|
||||
ret i32 %res
|
||||
}
|
||||
|
||||
|
|
|
@ -448,8 +448,8 @@ define i32 @test25(i1 %c) {
|
|||
; CHECK: jump:
|
||||
; CHECK-NEXT: br label [[RET]]
|
||||
; CHECK: ret:
|
||||
; CHECK-NEXT: [[B:%.*]] = phi i32 [ 10, [[JUMP]] ], [ 20, [[ENTRY:%.*]] ]
|
||||
; CHECK-NEXT: ret i32 [[B]]
|
||||
; CHECK-NEXT: [[A:%.*]] = phi i32 [ 10, [[JUMP]] ], [ 20, [[ENTRY:%.*]] ]
|
||||
; CHECK-NEXT: ret i32 [[A]]
|
||||
;
|
||||
entry:
|
||||
br i1 %c, label %jump, label %ret
|
||||
|
@ -468,8 +468,8 @@ define i32 @test26(i1 %cond) {
|
|||
; CHECK: jump:
|
||||
; CHECK-NEXT: br label [[RET]]
|
||||
; CHECK: ret:
|
||||
; CHECK-NEXT: [[B:%.*]] = phi i32 [ 10, [[JUMP]] ], [ 20, [[ENTRY:%.*]] ]
|
||||
; CHECK-NEXT: ret i32 [[B]]
|
||||
; CHECK-NEXT: [[A:%.*]] = phi i32 [ 20, [[ENTRY:%.*]] ], [ 10, [[JUMP]] ]
|
||||
; CHECK-NEXT: ret i32 [[A]]
|
||||
;
|
||||
entry:
|
||||
br i1 %cond, label %jump, label %ret
|
||||
|
@ -489,8 +489,8 @@ define i32 @test27(i1 %c, i32 %A, i32 %B) {
|
|||
; CHECK: jump:
|
||||
; CHECK-NEXT: br label [[RET]]
|
||||
; CHECK: ret:
|
||||
; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[A:%.*]], [[JUMP]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
|
||||
; CHECK-NEXT: ret i32 [[S]]
|
||||
; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[A:%.*]], [[JUMP]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
|
||||
; CHECK-NEXT: ret i32 [[P]]
|
||||
;
|
||||
entry:
|
||||
br i1 %c, label %jump, label %ret
|
||||
|
@ -509,8 +509,8 @@ define i32 @test28(i1 %cond, i32 %A, i32 %B) {
|
|||
; CHECK: jump:
|
||||
; CHECK-NEXT: br label [[RET]]
|
||||
; CHECK: ret:
|
||||
; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[A:%.*]], [[JUMP]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
|
||||
; CHECK-NEXT: ret i32 [[S]]
|
||||
; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[A:%.*]], [[JUMP]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
|
||||
; CHECK-NEXT: ret i32 [[P]]
|
||||
;
|
||||
entry:
|
||||
br i1 %cond, label %jump, label %ret
|
||||
|
@ -530,10 +530,10 @@ define i32 @test29(i1 %cond, i32 %A, i32 %B) {
|
|||
; CHECK: jump:
|
||||
; CHECK-NEXT: br label [[RET]]
|
||||
; CHECK: ret:
|
||||
; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[A:%.*]], [[JUMP]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
|
||||
; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[A:%.*]], [[JUMP]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
|
||||
; CHECK-NEXT: br label [[NEXT:%.*]]
|
||||
; CHECK: next:
|
||||
; CHECK-NEXT: ret i32 [[S]]
|
||||
; CHECK-NEXT: ret i32 [[P]]
|
||||
;
|
||||
entry:
|
||||
br i1 %cond, label %jump, label %ret
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
; RUN: opt -S < %s -instcombine | FileCheck %s
|
||||
; RUN: opt -S < %s -passes=instcombine | FileCheck %s
|
||||
|
||||
; TODO: Simplify to "ret cond".
|
||||
define i1 @test_direct_implication(i1 %cond) {
|
||||
; CHECK-LABEL: @test_direct_implication(
|
||||
; CHECK-NEXT: entry:
|
||||
|
@ -11,7 +12,8 @@ define i1 @test_direct_implication(i1 %cond) {
|
|||
; CHECK: if.false:
|
||||
; CHECK-NEXT: br label [[MERGE]]
|
||||
; CHECK: merge:
|
||||
; CHECK-NEXT: ret i1 [[COND]]
|
||||
; CHECK-NEXT: [[RET:%.*]] = phi i1 [ true, [[IF_TRUE]] ], [ false, [[IF_FALSE]] ]
|
||||
; CHECK-NEXT: ret i1 [[RET]]
|
||||
;
|
||||
entry:
|
||||
br i1 %cond, label %if.true, label %if.false
|
||||
|
@ -27,6 +29,7 @@ merge:
|
|||
ret i1 %ret
|
||||
}
|
||||
|
||||
; TODO: Simplify to "ret !cond".
|
||||
define i1 @test_inverted_implication(i1 %cond) {
|
||||
; CHECK-LABEL: @test_inverted_implication(
|
||||
; CHECK-NEXT: entry:
|
||||
|
@ -36,8 +39,8 @@ define i1 @test_inverted_implication(i1 %cond) {
|
|||
; CHECK: if.false:
|
||||
; CHECK-NEXT: br label [[MERGE]]
|
||||
; CHECK: merge:
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[COND]], true
|
||||
; CHECK-NEXT: ret i1 [[TMP0]]
|
||||
; CHECK-NEXT: [[RET:%.*]] = phi i1 [ false, [[IF_TRUE]] ], [ true, [[IF_FALSE]] ]
|
||||
; CHECK-NEXT: ret i1 [[RET]]
|
||||
;
|
||||
entry:
|
||||
br i1 %cond, label %if.true, label %if.false
|
||||
|
@ -53,6 +56,7 @@ merge:
|
|||
ret i1 %ret
|
||||
}
|
||||
|
||||
; TODO: Simplify to "ret cond".
|
||||
define i1 @test_direct_implication_complex_cfg(i1 %cond, i32 %cnt1) {
|
||||
; CHECK-LABEL: @test_direct_implication_complex_cfg(
|
||||
; CHECK-NEXT: entry:
|
||||
|
@ -69,7 +73,8 @@ define i1 @test_direct_implication_complex_cfg(i1 %cond, i32 %cnt1) {
|
|||
; CHECK: if.false:
|
||||
; CHECK-NEXT: br label [[MERGE]]
|
||||
; CHECK: merge:
|
||||
; CHECK-NEXT: ret i1 [[COND]]
|
||||
; CHECK-NEXT: [[RET:%.*]] = phi i1 [ true, [[IF_TRUE_END]] ], [ false, [[IF_FALSE]] ]
|
||||
; CHECK-NEXT: ret i1 [[RET]]
|
||||
;
|
||||
entry:
|
||||
br i1 %cond, label %if.true, label %if.false
|
||||
|
@ -94,6 +99,7 @@ merge:
|
|||
ret i1 %ret
|
||||
}
|
||||
|
||||
; TODO: Simplify to "ret !cond".
|
||||
define i1 @test_inverted_implication_complex_cfg(i1 %cond, i32 %cnt1) {
|
||||
; CHECK-LABEL: @test_inverted_implication_complex_cfg(
|
||||
; CHECK-NEXT: entry:
|
||||
|
@ -110,8 +116,8 @@ define i1 @test_inverted_implication_complex_cfg(i1 %cond, i32 %cnt1) {
|
|||
; CHECK: if.false:
|
||||
; CHECK-NEXT: br label [[MERGE]]
|
||||
; CHECK: merge:
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[COND]], true
|
||||
; CHECK-NEXT: ret i1 [[TMP0]]
|
||||
; CHECK-NEXT: [[RET:%.*]] = phi i1 [ false, [[IF_TRUE_END]] ], [ true, [[IF_FALSE]] ]
|
||||
; CHECK-NEXT: ret i1 [[RET]]
|
||||
;
|
||||
entry:
|
||||
br i1 %cond, label %if.true, label %if.false
|
||||
|
|
|
@ -18,16 +18,16 @@ define i1 @PR33605(i32 %a, i32 %b, i32* %c) {
|
|||
; ALL-NEXT: call void @foo()
|
||||
; ALL-NEXT: br label [[IF_END]]
|
||||
; ALL: if.end:
|
||||
; ALL-NEXT: [[TMP1:%.*]] = xor i1 [[CMP]], true
|
||||
; ALL-NEXT: [[TMP2:%.*]] = load i32, i32* [[C]], align 4
|
||||
; ALL-NEXT: [[CMP_1:%.*]] = icmp eq i32 [[OR]], [[TMP2]]
|
||||
; ALL-NEXT: [[CHANGED_1_OFF0:%.*]] = phi i1 [ true, [[IF_THEN]] ], [ false, [[ENTRY:%.*]] ]
|
||||
; ALL-NEXT: [[TMP1:%.*]] = load i32, i32* [[C]], align 4
|
||||
; ALL-NEXT: [[CMP_1:%.*]] = icmp eq i32 [[OR]], [[TMP1]]
|
||||
; ALL-NEXT: br i1 [[CMP_1]], label [[IF_END_1:%.*]], label [[IF_THEN_1:%.*]]
|
||||
; ALL: if.then.1:
|
||||
; ALL-NEXT: store i32 [[OR]], i32* [[C]], align 4
|
||||
; ALL-NEXT: call void @foo()
|
||||
; ALL-NEXT: br label [[IF_END_1]]
|
||||
; ALL: if.end.1:
|
||||
; ALL-NEXT: [[CHANGED_1_OFF0_1:%.*]] = phi i1 [ true, [[IF_THEN_1]] ], [ [[TMP1]], [[IF_END]] ]
|
||||
; ALL-NEXT: [[CHANGED_1_OFF0_1:%.*]] = phi i1 [ true, [[IF_THEN_1]] ], [ [[CHANGED_1_OFF0]], [[IF_END]] ]
|
||||
; ALL-NEXT: ret i1 [[CHANGED_1_OFF0_1]]
|
||||
;
|
||||
entry:
|
||||
|
|
Loading…
Reference in New Issue