aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Analysis/InstructionSimplify.cpp
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2011-01-28 18:50:50 +0000
committerDuncan Sands <baldrick@free.fr>2011-01-28 18:50:50 +0000
commita3e292c7e85efb33899f08238f57a85996a05a0b (patch)
tree41730926197e931843cc60a63b67d9ab6768aff4 /lib/Analysis/InstructionSimplify.cpp
parentd11c57a93753e7fd9fdac110e81c88eb56a847e4 (diff)
downloadexternal_llvm-a3e292c7e85efb33899f08238f57a85996a05a0b.zip
external_llvm-a3e292c7e85efb33899f08238f57a85996a05a0b.tar.gz
external_llvm-a3e292c7e85efb33899f08238f57a85996a05a0b.tar.bz2
Thread divisions over selects and phis. This doesn't fire much and has basically
zero effect on the testsuite (it improves two Ada testcases). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@124496 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/InstructionSimplify.cpp')
-rw-r--r--lib/Analysis/InstructionSimplify.cpp28
1 files changed, 19 insertions, 9 deletions
diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp
index 790b619..54dc6e6 100644
--- a/lib/Analysis/InstructionSimplify.cpp
+++ b/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;
}