diff options
author | Duncan Sands <baldrick@free.fr> | 2011-01-28 18:50:50 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2011-01-28 18:50:50 +0000 |
commit | 65995fa2a0dfa5141ca2567ac8c93491d3699642 (patch) | |
tree | 7e9c1e8e7fcb3fc397692f868990860cf9bfb616 /llvm/lib/Analysis/InstructionSimplify.cpp | |
parent | 163ae0986bfdce1a3fd01685fca94d90c8594c1f (diff) | |
download | bcm5719-llvm-65995fa2a0dfa5141ca2567ac8c93491d3699642.tar.gz bcm5719-llvm-65995fa2a0dfa5141ca2567ac8c93491d3699642.zip |
Thread divisions over selects and phis. This doesn't fire much and has basically
zero effect on the testsuite (it improves two Ada testcases).
llvm-svn: 124496
Diffstat (limited to 'llvm/lib/Analysis/InstructionSimplify.cpp')
-rw-r--r-- | llvm/lib/Analysis/InstructionSimplify.cpp | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 790b619814c..54dc6e6148e 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -759,6 +759,8 @@ static Value *SimplifyDiv(unsigned Opcode, Value *Op0, Value *Op1, } } + bool isSigned = Opcode == Instruction::SDiv; + // X / undef -> undef if (isa<UndefValue>(Op1)) return Op1; @@ -795,7 +797,6 @@ static Value *SimplifyDiv(unsigned Opcode, Value *Op0, Value *Op1, if (Y != Op1) std::swap(X, Y); // Ensure expression is (X * Y) / Y, Y = Op1 BinaryOperator *Mul = dyn_cast<BinaryOperator>(Op0); // If the Mul knows it does not overflow, then we are good to go. - bool isSigned = Opcode == Instruction::SDiv; if ((isSigned && Mul->hasNoSignedWrap()) || (!isSigned && Mul->hasNoUnsignedWrap())) return X; @@ -805,6 +806,23 @@ static Value *SimplifyDiv(unsigned Opcode, Value *Op0, Value *Op1, return X; } + // (X rem Y) / Y -> 0 + if ((isSigned && match(Op0, m_SRem(m_Value(), m_Specific(Op1)))) || + (!isSigned && match(Op0, m_URem(m_Value(), m_Specific(Op1))))) + return Constant::getNullValue(Op0->getType()); + + // 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 (isa<SelectInst>(Op0) || isa<SelectInst>(Op1)) + if (Value *V = ThreadBinOpOverSelect(Opcode, Op0, Op1, TD, DT, MaxRecurse)) + 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 (isa<PHINode>(Op0) || isa<PHINode>(Op1)) + if (Value *V = ThreadBinOpOverPHI(Opcode, Op0, Op1, TD, DT, MaxRecurse)) + return V; + return 0; } @@ -815,10 +833,6 @@ static Value *SimplifySDivInst(Value *Op0, Value *Op1, const TargetData *TD, if (Value *V = SimplifyDiv(Instruction::SDiv, Op0, Op1, TD, DT, MaxRecurse)) return V; - // (X rem Y) / Y -> 0 - if (match(Op0, m_SRem(m_Value(), m_Specific(Op1)))) - return Constant::getNullValue(Op0->getType()); - return 0; } @@ -834,10 +848,6 @@ static Value *SimplifyUDivInst(Value *Op0, Value *Op1, const TargetData *TD, if (Value *V = SimplifyDiv(Instruction::UDiv, Op0, Op1, TD, DT, MaxRecurse)) return V; - // (X rem Y) / Y -> 0 - if (match(Op0, m_URem(m_Value(), m_Specific(Op1)))) - return Constant::getNullValue(Op0->getType()); - return 0; } |