aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/InstructionSimplify.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis/InstructionSimplify.cpp')
-rw-r--r--lib/Analysis/InstructionSimplify.cpp100
1 files changed, 38 insertions, 62 deletions
diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp
index 29ce5cfd43..d5cf626e60 100644
--- a/lib/Analysis/InstructionSimplify.cpp
+++ b/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;
}