From: Chris Lattner Date: Sun, 27 Sep 2009 19:57:57 +0000 (+0000) Subject: implement PR4895, by making FoldOpIntoPhi handle select conditions X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=5d1704ddbf6d6471f4e8f9e0b27ab844d80e8172;p=oota-llvm.git implement PR4895, by making FoldOpIntoPhi handle select conditions that are phi nodes. Also tighten up FoldOpIntoPhi to treat constantexpr operands to phis just like other variables, avoiding moving constantexpr computations around. Patch by Daniel Dunbar. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82913 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 8d61fce4b43..be88d299ded 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -384,9 +384,10 @@ namespace { Value *SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, APInt& UndefElts, unsigned Depth = 0); - // FoldOpIntoPhi - Given a binary operator or cast instruction which has a - // PHI node as operand #0, see if we can fold the instruction into the PHI - // (which is only possible if all operands to the PHI are constants). + // FoldOpIntoPhi - Given a binary operator, cast instruction, or select + // which has a PHI node as operand #0, see if we can fold the instruction + // into the PHI (which is only possible if all operands to the PHI are + // constants). Instruction *FoldOpIntoPhi(Instruction &I); // FoldPHIArgOpIntoPHI - If all operands to a PHI node are the same "unary" @@ -1938,20 +1939,23 @@ static Instruction *FoldOpIntoSelect(Instruction &Op, SelectInst *SI, } -/// FoldOpIntoPhi - Given a binary operator or cast instruction which has a PHI -/// node as operand #0, see if we can fold the instruction into the PHI (which -/// is only possible if all operands to the PHI are constants). +/// FoldOpIntoPhi - Given a binary operator, cast instruction, or select which +/// has a PHI node as operand #0, see if we can fold the instruction into the +/// PHI (which is only possible if all operands to the PHI are constants). Instruction *InstCombiner::FoldOpIntoPhi(Instruction &I) { PHINode *PN = cast(I.getOperand(0)); unsigned NumPHIValues = PN->getNumIncomingValues(); if (!PN->hasOneUse() || NumPHIValues == 0) return 0; - // Check to see if all of the operands of the PHI are constants. If there is - // one non-constant value, remember the BB it is. If there is more than one - // or if *it* is a PHI, bail out. + // Check to see if all of the operands of the PHI are simple constants + // (constantint/constantfp/undef). If there is one non-constant value, + // remember the BB it is. If there is more than one or if *it* is a PHI, bail + // out. We don't do arbitrary constant expressions here because moving their + // computation can be expensive without a cost model. BasicBlock *NonConstBB = 0; for (unsigned i = 0; i != NumPHIValues; ++i) - if (!isa(PN->getIncomingValue(i))) { + if (!isa(PN->getIncomingValue(i)) || + isa(PN->getIncomingValue(i))) { if (NonConstBB) return 0; // More than one non-const value. if (isa(PN->getIncomingValue(i))) return 0; // Itself a phi. NonConstBB = PN->getIncomingBlock(i); @@ -1978,7 +1982,26 @@ Instruction *InstCombiner::FoldOpIntoPhi(Instruction &I) { NewPN->takeName(PN); // Next, add all of the operands to the PHI. - if (I.getNumOperands() == 2) { + if (SelectInst *SI = dyn_cast(&I)) { + // We only currently try to fold the condition of a select when it is a phi, + // not the true/false values. + for (unsigned i = 0; i != NumPHIValues; ++i) { + Value *InV = 0; + if (Constant *InC = dyn_cast(PN->getIncomingValue(i))) { + if (InC->isNullValue()) + InV = SI->getFalseValue(); + else + InV = SI->getTrueValue(); + } else { + assert(PN->getIncomingBlock(i) == NonConstBB); + InV = SelectInst::Create(PN->getIncomingValue(i), + SI->getTrueValue(), SI->getFalseValue(), + "phitmp", NonConstBB->getTerminator()); + Worklist.Add(cast(InV)); + } + NewPN->addIncoming(InV, PN->getIncomingBlock(i)); + } + } else if (I.getNumOperands() == 2) { Constant *C = cast(I.getOperand(1)); for (unsigned i = 0; i != NumPHIValues; ++i) { Value *InV = 0; @@ -9422,6 +9445,14 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) { return FoldI; } + // See if we can fold the select into a phi node. The true/false values have + // to be live in the predecessor blocks. + if (isa(SI.getCondition()) && + isa(SI.getTrueValue()) && + isa(SI.getFalseValue())) + if (Instruction *NV = FoldOpIntoPhi(SI)) + return NV; + if (BinaryOperator::isNot(CondVal)) { SI.setOperand(0, BinaryOperator::getNotArgument(CondVal)); SI.setOperand(1, FalseVal); diff --git a/test/Transforms/InstCombine/select.ll b/test/Transforms/InstCombine/select.ll index 22fe57f2372..fc4b82002d3 100644 --- a/test/Transforms/InstCombine/select.ll +++ b/test/Transforms/InstCombine/select.ll @@ -202,3 +202,25 @@ define i1 @test24(i1 %a, i1 %b) { ret i1 %c } +define i32 @test25() { +entry: + br i1 false, label %jump, label %ret +jump: + br label %ret +ret: + %a = phi i1 [true, %jump], [false, %entry] + %b = select i1 %a, i32 10, i32 20 + ret i32 %b +} + +define i32 @test26() { +entry: + br i1 false, label %jump, label %ret +jump: + %c = or i1 false, false + br label %ret +ret: + %a = phi i1 [true, %jump], [%c, %entry] + %b = select i1 %a, i32 10, i32 20 + ret i32 %b +}