summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2011-01-14 14:44:12 +0000
committerDuncan Sands <baldrick@free.fr>2011-01-14 14:44:12 +0000
commit571fd9a60652c793c8bdcd7163cd8ee207dc2a84 (patch)
tree4b2113b887b5d3b94ab84d90de6c4b86eb685e29 /llvm/lib/Analysis
parentc3eb0f4b2e4ca9e7665c8fe8aeb0f4c15d59f054 (diff)
downloadbcm5719-llvm-571fd9a60652c793c8bdcd7163cd8ee207dc2a84.tar.gz
bcm5719-llvm-571fd9a60652c793c8bdcd7163cd8ee207dc2a84.zip
Factorize common code out of the InstructionSimplify shift logic. Add in
threading of shifts over selects and phis while there. This fires here and there in the testsuite, to not much effect. For example when compiling spirit it fires 5 times, during early-cse, resulting in 6 more cse simplifications, and 3 more terminators being folded by jump threading, but the final bitcode doesn't change in any interesting way: other optimizations would have caught the opportunity anyway, only later. llvm-svn: 123441
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp100
1 files changed, 38 insertions, 62 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 29ce5cfd430..d5cf626e60f 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -684,31 +684,27 @@ Value *llvm::SimplifyMulInst(Value *Op0, Value *Op1, const TargetData *TD,
return ::SimplifyMulInst(Op0, Op1, TD, DT, RecursionLimit);
}
-/// SimplifyShlInst - Given operands for an Shl, see if we can
+/// SimplifyShift - Given operands for an Shl, LShr or AShr, see if we can
/// fold the result. If not, this returns null.
-static Value *SimplifyShlInst(Value *Op0, Value *Op1, const TargetData *TD,
- const DominatorTree *DT, unsigned MaxRecurse) {
+static Value *SimplifyShift(unsigned Opcode, Value *Op0, Value *Op1,
+ const TargetData *TD, const DominatorTree *DT,
+ unsigned MaxRecurse) {
if (Constant *C0 = dyn_cast<Constant>(Op0)) {
if (Constant *C1 = dyn_cast<Constant>(Op1)) {
Constant *Ops[] = { C0, C1 };
- return ConstantFoldInstOperands(Instruction::Shl, C0->getType(), Ops, 2,
- TD);
+ return ConstantFoldInstOperands(Opcode, C0->getType(), Ops, 2, TD);
}
}
- // 0 << X -> 0
+ // 0 shift by X -> 0
if (match(Op0, m_Zero()))
return Op0;
- // X << 0 -> X
+ // X shift by 0 -> X
if (match(Op1, m_Zero()))
return Op0;
- // undef << X -> 0
- if (isa<UndefValue>(Op0))
- return Constant::getNullValue(Op0->getType());
-
- // X << undef -> undef because it may shift by the bitwidth.
+ // X shift by undef -> undef because it may shift by the bitwidth.
if (isa<UndefValue>(Op1))
return Op1;
@@ -718,6 +714,32 @@ static Value *SimplifyShlInst(Value *Op0, Value *Op1, const TargetData *TD,
Op0->getType()->getScalarSizeInBits())
return UndefValue::get(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;
+}
+
+/// SimplifyShlInst - Given operands for an Shl, see if we can
+/// fold the result. If not, this returns null.
+static Value *SimplifyShlInst(Value *Op0, Value *Op1, const TargetData *TD,
+ const DominatorTree *DT, unsigned MaxRecurse) {
+ if (Value *V = SimplifyShift(Instruction::Shl, Op0, Op1, TD, DT, MaxRecurse))
+ return V;
+
+ // undef << X -> 0
+ if (isa<UndefValue>(Op0))
+ return Constant::getNullValue(Op0->getType());
+
return 0;
}
@@ -730,36 +752,13 @@ Value *llvm::SimplifyShlInst(Value *Op0, Value *Op1, const TargetData *TD,
/// fold the result. If not, this returns null.
static Value *SimplifyLShrInst(Value *Op0, Value *Op1, const TargetData *TD,
const DominatorTree *DT, unsigned MaxRecurse) {
- if (Constant *C0 = dyn_cast<Constant>(Op0)) {
- if (Constant *C1 = dyn_cast<Constant>(Op1)) {
- Constant *Ops[] = { C0, C1 };
- return ConstantFoldInstOperands(Instruction::LShr, C0->getType(), Ops, 2,
- TD);
- }
- }
-
- // 0 >> X -> 0
- if (match(Op0, m_Zero()))
- return Op0;
+ if (Value *V = SimplifyShift(Instruction::LShr, Op0, Op1, TD, DT, MaxRecurse))
+ return V;
// undef >>l X -> 0
if (isa<UndefValue>(Op0))
return Constant::getNullValue(Op0->getType());
- // X >> 0 -> X
- if (match(Op1, m_Zero()))
- return Op0;
-
- // X >> undef -> undef because it may shift by the bitwidth.
- if (isa<UndefValue>(Op1))
- return Op1;
-
- // Shifting by the bitwidth or more is undefined.
- if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1))
- if (CI->getValue().getLimitedValue() >=
- Op0->getType()->getScalarSizeInBits())
- return UndefValue::get(Op0->getType());
-
return 0;
}
@@ -772,17 +771,8 @@ Value *llvm::SimplifyLShrInst(Value *Op0, Value *Op1, const TargetData *TD,
/// fold the result. If not, this returns null.
static Value *SimplifyAShrInst(Value *Op0, Value *Op1, const TargetData *TD,
const DominatorTree *DT, unsigned MaxRecurse) {
- if (Constant *C0 = dyn_cast<Constant>(Op0)) {
- if (Constant *C1 = dyn_cast<Constant>(Op1)) {
- Constant *Ops[] = { C0, C1 };
- return ConstantFoldInstOperands(Instruction::AShr, C0->getType(), Ops, 2,
- TD);
- }
- }
-
- // 0 >> X -> 0
- if (match(Op0, m_Zero()))
- return Op0;
+ if (Value *V = SimplifyShift(Instruction::AShr, Op0, Op1, TD, DT, MaxRecurse))
+ return V;
// all ones >>a X -> all ones
if (match(Op0, m_AllOnes()))
@@ -792,20 +782,6 @@ static Value *SimplifyAShrInst(Value *Op0, Value *Op1, const TargetData *TD,
if (isa<UndefValue>(Op0))
return Constant::getAllOnesValue(Op0->getType());
- // X >> 0 -> X
- if (match(Op1, m_Zero()))
- return Op0;
-
- // X >> undef -> undef because it may shift by the bitwidth.
- if (isa<UndefValue>(Op1))
- return Op1;
-
- // Shifting by the bitwidth or more is undefined.
- if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1))
- if (CI->getValue().getLimitedValue() >=
- Op0->getType()->getScalarSizeInBits())
- return UndefValue::get(Op0->getType());
-
return 0;
}
OpenPOWER on IntegriCloud