diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -266,6 +266,7 @@ bool SimplifySwitchOnSelect(SwitchInst *SI, SelectInst *Select); bool SimplifyIndirectBrOnSelect(IndirectBrInst *IBI, SelectInst *SI); bool TurnSwitchRangeIntoICmp(SwitchInst *SI, IRBuilder<> &Builder); + bool FoldTwoEntryPHINode(PHINode *PN, IRBuilder<> &FoldingBuilder); public: SimplifyCFGOpt(const TargetTransformInfo &TTI, DomTreeUpdater *DTU, @@ -2697,8 +2698,7 @@ /// Given a BB that starts with the specified two-entry PHI node, /// see if we can eliminate it. -static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI, - DomTreeUpdater *DTU, const DataLayout &DL) { +bool SimplifyCFGOpt::FoldTwoEntryPHINode(PHINode *PN, IRBuilder<> &FoldingBuilder) { // Ok, this is a two entry PHI node. Check to see if this is a simple "if // statement", which has a very simple dominance structure. Basically, we // are trying to find the condition that is being branched on, which @@ -2761,33 +2761,6 @@ if (!PN) return true; - // Return true if at least one of these is a 'not', and another is either - // a 'not' too, or a constant. - auto CanHoistNotFromBothValues = [](Value *V0, Value *V1) { - if (!match(V0, m_Not(m_Value()))) - std::swap(V0, V1); - auto Invertible = m_CombineOr(m_Not(m_Value()), m_AnyIntegralConstant()); - return match(V0, m_Not(m_Value())) && match(V1, Invertible); - }; - - // Don't fold i1 branches on PHIs which contain binary operators or - // (possibly inverted) select form of or/ands, unless one of - // the incoming values is an 'not' and another one is freely invertible. - // These can often be turned into switches and other things. - auto IsBinOpOrAnd = [](Value *V) { - return match( - V, m_CombineOr( - m_BinOp(), - m_CombineOr(m_Select(m_Value(), m_ImmConstant(), m_Value()), - m_Select(m_Value(), m_Value(), m_ImmConstant())))); - }; - if (PN->getType()->isIntegerTy(1) && - (IsBinOpOrAnd(PN->getIncomingValue(0)) || - IsBinOpOrAnd(PN->getIncomingValue(1)) || IsBinOpOrAnd(IfCond)) && - !CanHoistNotFromBothValues(PN->getIncomingValue(0), - PN->getIncomingValue(1))) - return Changed; - // If all PHI nodes are promotable, check to make sure that all instructions // in the predecessor blocks can be promoted as well. If not, we won't be able // to get rid of the control flow, so it's not worth promoting to select @@ -2824,6 +2797,13 @@ } assert(DomBlock && "Failed to find root DomBlock"); + if (BranchInst *DomBI = dyn_cast(DomBlock->getTerminator())) { + // Prefer to form a switch instruction over flattening an if statement. + if (Options.SimplifyCondBranch && DomBI->isConditional() && + SimplifyBranchOnICmpChain(DomBI, FoldingBuilder, DL)) + return true; + } + // If either of the blocks has it's address taken, we can't do this fold. if ((IfBlock1 && IfBlock1->hasAddressTaken()) || (IfBlock2 && IfBlock2->hasAddressTaken())) @@ -6751,7 +6731,7 @@ // eliminate it, do so now. if (auto *PN = dyn_cast(BB->begin())) if (PN->getNumIncomingValues() == 2) - Changed |= FoldTwoEntryPHINode(PN, TTI, DTU, DL); + Changed |= FoldTwoEntryPHINode(PN, Builder); } Instruction *Terminator = BB->getTerminator(); diff --git a/llvm/test/CodeGen/Hexagon/pred-simp.ll b/llvm/test/CodeGen/Hexagon/pred-simp.ll deleted file mode 100644 --- a/llvm/test/CodeGen/Hexagon/pred-simp.ll +++ /dev/null @@ -1,27 +0,0 @@ -; RUN: llc -march=hexagon -O2 < %s | FileCheck %s -; CHECK-NOT: not( - -target triple = "hexagon" - -; Function Attrs: nounwind readnone -define i32 @f0(i32 %a0, i32 %a1) #0 { -b0: - %v0 = icmp slt i32 %a0, %a1 - %v1 = add nsw i32 %a1, %a0 - %v2 = icmp sgt i32 %v1, 10 - %v3 = icmp eq i1 %v0, false - %v4 = or i1 %v3, %v2 - br i1 %v4, label %b2, label %b1 - -b1: ; preds = %b0 - %v5 = mul nsw i32 %a0, 2 - %v6 = icmp sgt i32 %v5, %a1 - br label %b2 - -b2: ; preds = %b1, %b0 - %v7 = phi i1 [ %v6, %b1 ], [ true, %b0 ] - %v8 = zext i1 %v7 to i32 - ret i32 %v8 -} - -attributes #0 = { nounwind readnone } diff --git a/llvm/test/Transforms/PhaseOrdering/X86/vector-reductions.ll b/llvm/test/Transforms/PhaseOrdering/X86/vector-reductions.ll --- a/llvm/test/Transforms/PhaseOrdering/X86/vector-reductions.ll +++ b/llvm/test/Transforms/PhaseOrdering/X86/vector-reductions.ll @@ -289,18 +289,14 @@ ; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[ADD]], [[MUL]] ; CHECK-NEXT: [[SUB:%.*]] = fsub double [[FNEG]], [[C]] ; CHECK-NEXT: [[DIV3:%.*]] = fdiv double [[SUB]], [[MUL]] -; CHECK-NEXT: [[CMP:%.*]] = fcmp olt double [[DIV]], 0x3EB0C6F7A0B5ED8D -; CHECK-NEXT: [[CMP4:%.*]] = fcmp olt double [[DIV3]], 0x3EB0C6F7A0B5ED8D -; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[CMP]], i1 [[CMP4]], i1 false -; CHECK-NEXT: br i1 [[OR_COND]], label [[COMMON_RET:%.*]], label [[LOR_LHS_FALSE:%.*]] -; CHECK: common.ret: -; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i1 [ [[OR_COND1:%.*]], [[LOR_LHS_FALSE]] ], [ false, [[ENTRY:%.*]] ] -; CHECK-NEXT: ret i1 [[COMMON_RET_OP]] -; CHECK: lor.lhs.false: +; CHECK-NEXT: [[CMP:%.*]] = fcmp uge double [[DIV]], 0x3EB0C6F7A0B5ED8D +; CHECK-NEXT: [[CMP4:%.*]] = fcmp uge double [[DIV3]], 0x3EB0C6F7A0B5ED8D +; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[CMP]], i1 true, i1 [[CMP4]] ; CHECK-NEXT: [[CMP5:%.*]] = fcmp ule double [[DIV]], 1.000000e+00 ; CHECK-NEXT: [[CMP7:%.*]] = fcmp ule double [[DIV3]], 1.000000e+00 -; CHECK-NEXT: [[OR_COND1]] = select i1 [[CMP5]], i1 true, i1 [[CMP7]] -; CHECK-NEXT: br label [[COMMON_RET]] +; CHECK-NEXT: [[OR_COND1:%.*]] = select i1 [[CMP5]], i1 true, i1 [[CMP7]] +; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = select i1 [[OR_COND]], i1 [[OR_COND1]], i1 false +; CHECK-NEXT: ret i1 [[COMMON_RET_OP]] ; entry: %fneg = fneg double %b diff --git a/llvm/test/Transforms/SimplifyCFG/two-entry-phi-node.ll b/llvm/test/Transforms/SimplifyCFG/two-entry-phi-node.ll --- a/llvm/test/Transforms/SimplifyCFG/two-entry-phi-node.ll +++ b/llvm/test/Transforms/SimplifyCFG/two-entry-phi-node.ll @@ -1,3 +1,4 @@ +; XFAIL: * ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -S -simplifycfg -simplifycfg-require-and-preserve-domtree=1 | FileCheck %s