From 1845009290e4d804ad377927bd8a08cca3036adc Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Tue, 16 Nov 2010 12:16:38 +0000 Subject: [PATCH] =?UTF-8?q?In=20which=20I=20discover=20the=20existence=20o?= =?UTF-8?q?f=20loops.=20=20Threading=20an=20operation=20over=20a=20phi=20n?= =?UTF-8?q?ode=20by=20applying=20it=20to=20each=20operand=20may=20be=20wro?= =?UTF-8?q?ng=20if=20the=20operation=20and=20the=20phi=20node=20are=20mutu?= =?UTF-8?q?ally=20interdependent=20(the=20testcase=20has=20a=20simple=20ex?= =?UTF-8?q?ample=20of=20this).=20=20So=20only=20do=20this=20transform=20if?= =?UTF-8?q?=20it=20would=20be=20correct=20to=20perform=20the=20operation?= =?UTF-8?q?=20in=20each=20predecessor=20of=20the=20block=20containing=20th?= =?UTF-8?q?e=20phi,=20i.e.=20if=20the=20other=20operands=20all=20dominate?= =?UTF-8?q?=20the=20phi.=20This=20should=20fix=20the=20FFMPEG=20snow.c=20r?= =?UTF-8?q?egression=20reported=20by=20=C4=B0smail=20D=C3=B6nmez.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119347 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Analysis/InstructionSimplify.h | 25 +-- lib/Analysis/InstructionSimplify.cpp | 162 ++++++++++++-------- lib/Analysis/PHITransAddr.cpp | 4 +- test/Transforms/InstCombine/phi.ll | 15 ++ 4 files changed, 133 insertions(+), 73 deletions(-) diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h index d1ad061d5cd..b59adc1de9b 100644 --- a/include/llvm/Analysis/InstructionSimplify.h +++ b/include/llvm/Analysis/InstructionSimplify.h @@ -25,37 +25,40 @@ namespace llvm { /// SimplifyAddInst - Given operands for an Add, see if we can /// fold the result. If not, this returns null. Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW, - const TargetData *TD = 0); + const TargetData *TD = 0, const DominatorTree *DT = 0); /// SimplifyAndInst - Given operands for an And, see if we can /// fold the result. If not, this returns null. - Value *SimplifyAndInst(Value *LHS, Value *RHS, - const TargetData *TD = 0); + Value *SimplifyAndInst(Value *LHS, Value *RHS, const TargetData *TD = 0, + const DominatorTree *DT = 0); /// SimplifyOrInst - Given operands for an Or, see if we can /// fold the result. If not, this returns null. - Value *SimplifyOrInst(Value *LHS, Value *RHS, - const TargetData *TD = 0); + Value *SimplifyOrInst(Value *LHS, Value *RHS, const TargetData *TD = 0, + const DominatorTree *DT = 0); /// SimplifyICmpInst - Given operands for an ICmpInst, see if we can /// fold the result. If not, this returns null. Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, - const TargetData *TD = 0); + const TargetData *TD = 0, + const DominatorTree *DT = 0); /// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can /// fold the result. If not, this returns null. Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, - const TargetData *TD = 0); + const TargetData *TD = 0, + const DominatorTree *DT = 0); /// SimplifySelectInst - Given operands for a SelectInst, see if we can fold /// the result. If not, this returns null. Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, - const TargetData *TD = 0); + const TargetData *TD = 0, + const DominatorTree *DT = 0); /// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can /// fold the result. If not, this returns null. Value *SimplifyGEPInst(Value * const *Ops, unsigned NumOps, - const TargetData *TD = 0); + const TargetData *TD = 0, const DominatorTree *DT = 0); //=== Helper functions for higher up the class hierarchy. @@ -63,12 +66,12 @@ namespace llvm { /// SimplifyCmpInst - Given operands for a CmpInst, see if we can /// fold the result. If not, this returns null. Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS, - const TargetData *TD = 0); + const TargetData *TD = 0, const DominatorTree *DT = 0); /// SimplifyBinOp - Given operands for a BinaryOperator, see if we can /// fold the result. If not, this returns null. Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, - const TargetData *TD = 0); + const TargetData *TD = 0, const DominatorTree *DT = 0); /// SimplifyInstruction - See if we can compute a simplified version of this /// instruction. If not, this returns null. diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index a8288bf67a9..cf1548eeb80 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -15,25 +15,47 @@ #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/ConstantFolding.h" -#include "llvm/Support/ValueHandle.h" -#include "llvm/Instructions.h" +#include "llvm/Analysis/Dominators.h" #include "llvm/Support/PatternMatch.h" +#include "llvm/Support/ValueHandle.h" using namespace llvm; using namespace llvm::PatternMatch; -#define MaxRecursionDepth 3 +#define RecursionLimit 3 static Value *SimplifyBinOp(unsigned, Value *, Value *, const TargetData *, - unsigned); + const DominatorTree *, unsigned); static Value *SimplifyCmpInst(unsigned, Value *, Value *, const TargetData *, - unsigned); + const DominatorTree *, unsigned); + +/// ValueDominatesPHI - Does the given value dominate the specified phi node? +static bool ValueDominatesPHI(Value *V, PHINode *P, const DominatorTree *DT) { + Instruction *I = dyn_cast(V); + if (!I) + // Arguments and constants dominate all instructions. + return true; + + // If we have a DominatorTree then do a precise test. + if (DT) + return DT->dominates(I, P); + + // Otherwise, if the instruction is in the entry block, and is not an invoke, + // then it obviously dominates all phi nodes. + if (I->getParent() == &I->getParent()->getParent()->getEntryBlock() && + !isa(I)) + return true; + + return false; +} /// ThreadBinOpOverSelect - In the case of a binary operation with a select /// instruction as an operand, try to simplify the binop by seeing whether /// evaluating it on both branches of the select results in the same value. /// Returns the common value if so, otherwise returns null. static Value *ThreadBinOpOverSelect(unsigned Opcode, Value *LHS, Value *RHS, - const TargetData *TD, unsigned MaxRecurse) { + const TargetData *TD, + const DominatorTree *DT, + unsigned MaxRecurse) { SelectInst *SI; if (isa(LHS)) { SI = cast(LHS); @@ -46,11 +68,11 @@ static Value *ThreadBinOpOverSelect(unsigned Opcode, Value *LHS, Value *RHS, Value *TV; Value *FV; if (SI == LHS) { - TV = SimplifyBinOp(Opcode, SI->getTrueValue(), RHS, TD, MaxRecurse); - FV = SimplifyBinOp(Opcode, SI->getFalseValue(), RHS, TD, MaxRecurse); + TV = SimplifyBinOp(Opcode, SI->getTrueValue(), RHS, TD, DT, MaxRecurse); + FV = SimplifyBinOp(Opcode, SI->getFalseValue(), RHS, TD, DT, MaxRecurse); } else { - TV = SimplifyBinOp(Opcode, LHS, SI->getTrueValue(), TD, MaxRecurse); - FV = SimplifyBinOp(Opcode, LHS, SI->getFalseValue(), TD, MaxRecurse); + TV = SimplifyBinOp(Opcode, LHS, SI->getTrueValue(), TD, DT, MaxRecurse); + FV = SimplifyBinOp(Opcode, LHS, SI->getFalseValue(), TD, DT, MaxRecurse); } // If they simplified to the same value, then return the common value. @@ -102,6 +124,7 @@ static Value *ThreadBinOpOverSelect(unsigned Opcode, Value *LHS, Value *RHS, /// null. static Value *ThreadCmpOverSelect(CmpInst::Predicate Pred, Value *LHS, Value *RHS, const TargetData *TD, + const DominatorTree *DT, unsigned MaxRecurse) { // Make sure the select is on the LHS. if (!isa(LHS)) { @@ -113,10 +136,10 @@ static Value *ThreadCmpOverSelect(CmpInst::Predicate Pred, Value *LHS, // Now that we have "cmp select(cond, TV, FV), RHS", analyse it. // Does "cmp TV, RHS" simplify? - if (Value *TCmp = SimplifyCmpInst(Pred, SI->getTrueValue(), RHS, TD, + if (Value *TCmp = SimplifyCmpInst(Pred, SI->getTrueValue(), RHS, TD, DT, MaxRecurse)) // It does! Does "cmp FV, RHS" simplify? - if (Value *FCmp = SimplifyCmpInst(Pred, SI->getFalseValue(), RHS, TD, + if (Value *FCmp = SimplifyCmpInst(Pred, SI->getFalseValue(), RHS, TD, DT, MaxRecurse)) // It does! If they simplified to the same value, then use it as the // result of the original comparison. @@ -130,13 +153,20 @@ static Value *ThreadCmpOverSelect(CmpInst::Predicate Pred, Value *LHS, /// it on the incoming phi values yields the same result for every value. If so /// returns the common value, otherwise returns null. static Value *ThreadBinOpOverPHI(unsigned Opcode, Value *LHS, Value *RHS, - const TargetData *TD, unsigned MaxRecurse) { + const TargetData *TD, const DominatorTree *DT, + unsigned MaxRecurse) { PHINode *PI; if (isa(LHS)) { PI = cast(LHS); + // Bail out if RHS and the phi may be mutually interdependent due to a loop. + if (!ValueDominatesPHI(RHS, PI, DT)) + return 0; } else { assert(isa(RHS) && "No PHI instruction operand!"); PI = cast(RHS); + // Bail out if LHS and the phi may be mutually interdependent due to a loop. + if (!ValueDominatesPHI(LHS, PI, DT)) + return 0; } // Evaluate the BinOp on the incoming phi values. @@ -146,8 +176,8 @@ static Value *ThreadBinOpOverPHI(unsigned Opcode, Value *LHS, Value *RHS, // If the incoming value is the phi node itself, it can be safely skipped. if (Incoming == PI) continue; Value *V = PI == LHS ? - SimplifyBinOp(Opcode, Incoming, RHS, TD, MaxRecurse) : - SimplifyBinOp(Opcode, LHS, Incoming, TD, MaxRecurse); + SimplifyBinOp(Opcode, Incoming, RHS, TD, DT, MaxRecurse) : + SimplifyBinOp(Opcode, LHS, Incoming, TD, DT, MaxRecurse); // If the operation failed to simplify, or simplified to a different value // to previously, then give up. if (!V || (CommonValue && V != CommonValue)) @@ -163,7 +193,8 @@ static Value *ThreadBinOpOverPHI(unsigned Opcode, Value *LHS, Value *RHS, /// incoming phi values yields the same result every time. If so returns the /// common result, otherwise returns null. static Value *ThreadCmpOverPHI(CmpInst::Predicate Pred, Value *LHS, Value *RHS, - const TargetData *TD, unsigned MaxRecurse) { + const TargetData *TD, const DominatorTree *DT, + unsigned MaxRecurse) { // Make sure the phi is on the LHS. if (!isa(LHS)) { std::swap(LHS, RHS); @@ -172,13 +203,17 @@ static Value *ThreadCmpOverPHI(CmpInst::Predicate Pred, Value *LHS, Value *RHS, assert(isa(LHS) && "Not comparing with a phi instruction!"); PHINode *PI = cast(LHS); + // Bail out if RHS and the phi may be mutually interdependent due to a loop. + if (!ValueDominatesPHI(RHS, PI, DT)) + return 0; + // Evaluate the BinOp on the incoming phi values. Value *CommonValue = 0; for (unsigned i = 0, e = PI->getNumIncomingValues(); i != e; ++i) { Value *Incoming = PI->getIncomingValue(i); // If the incoming value is the phi node itself, it can be safely skipped. if (Incoming == PI) continue; - Value *V = SimplifyCmpInst(Pred, Incoming, RHS, TD, MaxRecurse); + Value *V = SimplifyCmpInst(Pred, Incoming, RHS, TD, DT, MaxRecurse); // If the operation failed to simplify, or simplified to a different value // to previously, then give up. if (!V || (CommonValue && V != CommonValue)) @@ -192,7 +227,7 @@ static Value *ThreadCmpOverPHI(CmpInst::Predicate Pred, Value *LHS, Value *RHS, /// SimplifyAddInst - Given operands for an Add, see if we can /// fold the result. If not, this returns null. Value *llvm::SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, - const TargetData *TD) { + const TargetData *TD, const DominatorTree *) { if (Constant *CLHS = dyn_cast(Op0)) { if (Constant *CRHS = dyn_cast(Op1)) { Constant *Ops[] = { CLHS, CRHS }; @@ -221,7 +256,7 @@ Value *llvm::SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, /// SimplifyAndInst - Given operands for an And, see if we can /// fold the result. If not, this returns null. static Value *SimplifyAndInst(Value *Op0, Value *Op1, const TargetData *TD, - unsigned MaxRecurse) { + const DominatorTree *DT, unsigned MaxRecurse) { if (Constant *CLHS = dyn_cast(Op0)) { if (Constant *CRHS = dyn_cast(Op1)) { Constant *Ops[] = { CLHS, CRHS }; @@ -288,28 +323,29 @@ static Value *SimplifyAndInst(Value *Op0, Value *Op1, const TargetData *TD, // If the operation is with the result of a select instruction, check whether // operating on either branch of the select always yields the same value. if (MaxRecurse && (isa(Op0) || isa(Op1))) - if (Value *V = ThreadBinOpOverSelect(Instruction::And, Op0, Op1, TD, + if (Value *V = ThreadBinOpOverSelect(Instruction::And, Op0, Op1, TD, DT, MaxRecurse-1)) return V; // If the operation is with the result of a phi instruction, check whether // operating on all incoming values of the phi always yields the same value. if (MaxRecurse && (isa(Op0) || isa(Op1))) - if (Value *V = ThreadBinOpOverPHI(Instruction::And, Op0, Op1, TD, + if (Value *V = ThreadBinOpOverPHI(Instruction::And, Op0, Op1, TD, DT, MaxRecurse-1)) return V; return 0; } -Value *llvm::SimplifyAndInst(Value *Op0, Value *Op1, const TargetData *TD) { - return ::SimplifyAndInst(Op0, Op1, TD, MaxRecursionDepth); +Value *llvm::SimplifyAndInst(Value *Op0, Value *Op1, const TargetData *TD, + const DominatorTree *DT) { + return ::SimplifyAndInst(Op0, Op1, TD, DT, RecursionLimit); } /// SimplifyOrInst - Given operands for an Or, see if we can /// fold the result. If not, this returns null. static Value *SimplifyOrInst(Value *Op0, Value *Op1, const TargetData *TD, - unsigned MaxRecurse) { + const DominatorTree *DT, unsigned MaxRecurse) { if (Constant *CLHS = dyn_cast(Op0)) { if (Constant *CRHS = dyn_cast(Op1)) { Constant *Ops[] = { CLHS, CRHS }; @@ -376,22 +412,23 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, const TargetData *TD, // If the operation is with the result of a select instruction, check whether // operating on either branch of the select always yields the same value. if (MaxRecurse && (isa(Op0) || isa(Op1))) - if (Value *V = ThreadBinOpOverSelect(Instruction::Or, Op0, Op1, TD, + if (Value *V = ThreadBinOpOverSelect(Instruction::Or, Op0, Op1, TD, DT, MaxRecurse-1)) return V; // If the operation is with the result of a phi instruction, check whether // operating on all incoming values of the phi always yields the same value. if (MaxRecurse && (isa(Op0) || isa(Op1))) - if (Value *V = ThreadBinOpOverPHI(Instruction::Or, Op0, Op1, TD, + if (Value *V = ThreadBinOpOverPHI(Instruction::Or, Op0, Op1, TD, DT, MaxRecurse-1)) return V; return 0; } -Value *llvm::SimplifyOrInst(Value *Op0, Value *Op1, const TargetData *TD) { - return ::SimplifyOrInst(Op0, Op1, TD, MaxRecursionDepth); +Value *llvm::SimplifyOrInst(Value *Op0, Value *Op1, const TargetData *TD, + const DominatorTree *DT) { + return ::SimplifyOrInst(Op0, Op1, TD, DT, RecursionLimit); } static const Type *GetCompareTy(Value *Op) { @@ -401,7 +438,8 @@ static const Type *GetCompareTy(Value *Op) { /// SimplifyICmpInst - Given operands for an ICmpInst, see if we can /// fold the result. If not, this returns null. static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, - const TargetData *TD, unsigned MaxRecurse) { + const TargetData *TD, const DominatorTree *DT, + unsigned MaxRecurse) { CmpInst::Predicate Pred = (CmpInst::Predicate)Predicate; assert(CmpInst::isIntPredicate(Pred) && "Not an integer compare!"); @@ -460,27 +498,28 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, // If the comparison is with the result of a select instruction, check whether // comparing with either branch of the select always yields the same value. if (MaxRecurse && (isa(LHS) || isa(RHS))) - if (Value *V = ThreadCmpOverSelect(Pred, LHS, RHS, TD, MaxRecurse-1)) + if (Value *V = ThreadCmpOverSelect(Pred, LHS, RHS, TD, DT, MaxRecurse-1)) return V; // If the comparison is with the result of a phi instruction, check whether // doing the compare with each incoming phi value yields a common result. if (MaxRecurse && (isa(LHS) || isa(RHS))) - if (Value *V = ThreadCmpOverPHI(Pred, LHS, RHS, TD, MaxRecurse-1)) + if (Value *V = ThreadCmpOverPHI(Pred, LHS, RHS, TD, DT, MaxRecurse-1)) return V; return 0; } Value *llvm::SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, - const TargetData *TD) { - return ::SimplifyICmpInst(Predicate, LHS, RHS, TD, MaxRecursionDepth); + const TargetData *TD, const DominatorTree *DT) { + return ::SimplifyICmpInst(Predicate, LHS, RHS, TD, DT, RecursionLimit); } /// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can /// fold the result. If not, this returns null. static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, - const TargetData *TD, unsigned MaxRecurse) { + const TargetData *TD, const DominatorTree *DT, + unsigned MaxRecurse) { CmpInst::Predicate Pred = (CmpInst::Predicate)Predicate; assert(CmpInst::isFPPredicate(Pred) && "Not an FP compare!"); @@ -554,27 +593,27 @@ static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, // If the comparison is with the result of a select instruction, check whether // comparing with either branch of the select always yields the same value. if (MaxRecurse && (isa(LHS) || isa(RHS))) - if (Value *V = ThreadCmpOverSelect(Pred, LHS, RHS, TD, MaxRecurse-1)) + if (Value *V = ThreadCmpOverSelect(Pred, LHS, RHS, TD, DT, MaxRecurse-1)) return V; // If the comparison is with the result of a phi instruction, check whether // doing the compare with each incoming phi value yields a common result. if (MaxRecurse && (isa(LHS) || isa(RHS))) - if (Value *V = ThreadCmpOverPHI(Pred, LHS, RHS, TD, MaxRecurse-1)) + if (Value *V = ThreadCmpOverPHI(Pred, LHS, RHS, TD, DT, MaxRecurse-1)) return V; return 0; } Value *llvm::SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, - const TargetData *TD) { - return ::SimplifyFCmpInst(Predicate, LHS, RHS, TD, MaxRecursionDepth); + const TargetData *TD, const DominatorTree *DT) { + return ::SimplifyFCmpInst(Predicate, LHS, RHS, TD, DT, RecursionLimit); } /// SimplifySelectInst - Given operands for a SelectInst, see if we can fold /// the result. If not, this returns null. Value *llvm::SimplifySelectInst(Value *CondVal, Value *TrueVal, Value *FalseVal, - const TargetData *TD) { + const TargetData *TD, const DominatorTree *) { // select true, X, Y -> X // select false, X, Y -> Y if (ConstantInt *CB = dyn_cast(CondVal)) @@ -597,11 +636,10 @@ Value *llvm::SimplifySelectInst(Value *CondVal, Value *TrueVal, Value *FalseVal, return 0; } - /// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can /// fold the result. If not, this returns null. Value *llvm::SimplifyGEPInst(Value *const *Ops, unsigned NumOps, - const TargetData *TD) { + const TargetData *TD, const DominatorTree *) { // getelementptr P -> P. if (NumOps == 1) return Ops[0]; @@ -631,10 +669,11 @@ Value *llvm::SimplifyGEPInst(Value *const *Ops, unsigned NumOps, /// SimplifyBinOp - Given operands for a BinaryOperator, see if we can /// fold the result. If not, this returns null. static Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, - const TargetData *TD, unsigned MaxRecurse) { + const TargetData *TD, const DominatorTree *DT, + unsigned MaxRecurse) { switch (Opcode) { - case Instruction::And: return SimplifyAndInst(LHS, RHS, TD, MaxRecurse); - case Instruction::Or: return SimplifyOrInst(LHS, RHS, TD, MaxRecurse); + case Instruction::And: return SimplifyAndInst(LHS, RHS, TD, DT, MaxRecurse); + case Instruction::Or: return SimplifyOrInst(LHS, RHS, TD, DT, MaxRecurse); default: if (Constant *CLHS = dyn_cast(LHS)) if (Constant *CRHS = dyn_cast(RHS)) { @@ -645,13 +684,14 @@ static Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, // If the operation is with the result of a select instruction, check whether // operating on either branch of the select always yields the same value. if (MaxRecurse && (isa(LHS) || isa(RHS))) - if (Value *V = ThreadBinOpOverSelect(Opcode, LHS, RHS, TD, MaxRecurse-1)) + if (Value *V = ThreadBinOpOverSelect(Opcode, LHS, RHS, TD, DT, + MaxRecurse-1)) return V; // If the operation is with the result of a phi instruction, check whether // operating on all incoming values of the phi always yields the same value. if (MaxRecurse && (isa(LHS) || isa(RHS))) - if (Value *V = ThreadBinOpOverPHI(Opcode, LHS, RHS, TD, MaxRecurse-1)) + if (Value *V = ThreadBinOpOverPHI(Opcode, LHS, RHS, TD, DT, MaxRecurse-1)) return V; return 0; @@ -659,22 +699,23 @@ static Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, } Value *llvm::SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, - const TargetData *TD) { - return ::SimplifyBinOp(Opcode, LHS, RHS, TD, MaxRecursionDepth); + const TargetData *TD, const DominatorTree *DT) { + return ::SimplifyBinOp(Opcode, LHS, RHS, TD, DT, RecursionLimit); } /// SimplifyCmpInst - Given operands for a CmpInst, see if we can /// fold the result. static Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS, - const TargetData *TD, unsigned MaxRecurse) { + const TargetData *TD, const DominatorTree *DT, + unsigned MaxRecurse) { if (CmpInst::isIntPredicate((CmpInst::Predicate)Predicate)) - return SimplifyICmpInst(Predicate, LHS, RHS, TD, MaxRecurse); - return SimplifyFCmpInst(Predicate, LHS, RHS, TD, MaxRecurse); + return SimplifyICmpInst(Predicate, LHS, RHS, TD, DT, MaxRecurse); + return SimplifyFCmpInst(Predicate, LHS, RHS, TD, DT, MaxRecurse); } Value *llvm::SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS, - const TargetData *TD) { - return ::SimplifyCmpInst(Predicate, LHS, RHS, TD, MaxRecursionDepth); + const TargetData *TD, const DominatorTree *DT) { + return ::SimplifyCmpInst(Predicate, LHS, RHS, TD, DT, RecursionLimit); } /// SimplifyInstruction - See if we can compute a simplified version of this @@ -687,23 +728,24 @@ Value *llvm::SimplifyInstruction(Instruction *I, const TargetData *TD, case Instruction::Add: return SimplifyAddInst(I->getOperand(0), I->getOperand(1), cast(I)->hasNoSignedWrap(), - cast(I)->hasNoUnsignedWrap(), TD); + cast(I)->hasNoUnsignedWrap(), + TD, DT); case Instruction::And: - return SimplifyAndInst(I->getOperand(0), I->getOperand(1), TD); + return SimplifyAndInst(I->getOperand(0), I->getOperand(1), TD, DT); case Instruction::Or: - return SimplifyOrInst(I->getOperand(0), I->getOperand(1), TD); + return SimplifyOrInst(I->getOperand(0), I->getOperand(1), TD, DT); case Instruction::ICmp: return SimplifyICmpInst(cast(I)->getPredicate(), - I->getOperand(0), I->getOperand(1), TD); + I->getOperand(0), I->getOperand(1), TD, DT); case Instruction::FCmp: return SimplifyFCmpInst(cast(I)->getPredicate(), - I->getOperand(0), I->getOperand(1), TD); + I->getOperand(0), I->getOperand(1), TD, DT); case Instruction::Select: return SimplifySelectInst(I->getOperand(0), I->getOperand(1), - I->getOperand(2), TD); + I->getOperand(2), TD, DT); case Instruction::GetElementPtr: { SmallVector Ops(I->op_begin(), I->op_end()); - return SimplifyGEPInst(&Ops[0], Ops.size(), TD); + return SimplifyGEPInst(&Ops[0], Ops.size(), TD, DT); } case Instruction::PHI: return cast(I)->hasConstantValue(DT); diff --git a/lib/Analysis/PHITransAddr.cpp b/lib/Analysis/PHITransAddr.cpp index 8e4fa03f213..a9ccab1f469 100644 --- a/lib/Analysis/PHITransAddr.cpp +++ b/lib/Analysis/PHITransAddr.cpp @@ -217,7 +217,7 @@ Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB, return GEP; // Simplify the GEP to handle 'gep x, 0' -> x etc. - if (Value *V = SimplifyGEPInst(&GEPOps[0], GEPOps.size(), TD)) { + if (Value *V = SimplifyGEPInst(&GEPOps[0], GEPOps.size(), TD, DT)) { for (unsigned i = 0, e = GEPOps.size(); i != e; ++i) RemoveInstInputs(GEPOps[i], InstInputs); @@ -273,7 +273,7 @@ Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB, } // See if the add simplifies away. - if (Value *Res = SimplifyAddInst(LHS, RHS, isNSW, isNUW, TD)) { + if (Value *Res = SimplifyAddInst(LHS, RHS, isNSW, isNUW, TD, DT)) { // If we simplified the operands, the LHS is no longer an input, but Res // is. RemoveInstInputs(LHS, InstInputs); diff --git a/test/Transforms/InstCombine/phi.ll b/test/Transforms/InstCombine/phi.ll index c3e034fb5c1..ff0b43c4ab6 100644 --- a/test/Transforms/InstCombine/phi.ll +++ b/test/Transforms/InstCombine/phi.ll @@ -488,3 +488,18 @@ ret: ; CHECK: @test21 ; CHECK: ret i1 false } + +define void @test22() { +; CHECK: @test22 +entry: + br label %loop +loop: + %phi = phi i32 [ 0, %entry ], [ %y, %loop ] + %y = add i32 %phi, 1 + %o = or i32 %y, %phi + %e = icmp eq i32 %o, %y + br i1 %e, label %loop, label %ret +; CHECK: br i1 %e +ret: + ret void +}