aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Analysis
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2012-03-13 14:07:05 +0000
committerDuncan Sands <baldrick@free.fr>2012-03-13 14:07:05 +0000
commitbd0fe5642544d4ec3aee1ede7af60c006bae5cbf (patch)
treed45f0f6639dd84e8c9d8ac651d4a77ccdb46e2e7 /lib/Analysis
parentc347b6f4b600368751f6f79d270bf58f7d54a348 (diff)
downloadexternal_llvm-bd0fe5642544d4ec3aee1ede7af60c006bae5cbf.zip
external_llvm-bd0fe5642544d4ec3aee1ede7af60c006bae5cbf.tar.gz
external_llvm-bd0fe5642544d4ec3aee1ede7af60c006bae5cbf.tar.bz2
Generalize the "trunc(ptrtoint(x)) - trunc(ptrtoint(y)) ->
trunc(ptrtoint(x-y))" optimization introduced by Chandler. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@152626 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis')
-rw-r--r--lib/Analysis/InstructionSimplify.cpp48
1 files changed, 34 insertions, 14 deletions
diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp
index 75afbf1..b095bc4 100644
--- a/lib/Analysis/InstructionSimplify.cpp
+++ b/lib/Analysis/InstructionSimplify.cpp
@@ -56,6 +56,7 @@ static Value *SimplifyCmpInst(unsigned, Value *, Value *, const Query &,
unsigned);
static Value *SimplifyOrInst(Value *, Value *, const Query &, unsigned);
static Value *SimplifyXorInst(Value *, Value *, const Query &, unsigned);
+static Value *SimplifyTruncInst(Value *, Type *, const Query &, unsigned);
/// getFalse - For a boolean type, or a vector of boolean type, return false, or
/// a vector with every element false, as appropriate for the type.
@@ -777,20 +778,6 @@ static Value *SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
match(Op0, m_Shl(m_Specific(Op1), m_One())))
return Op1;
- if (Q.TD) {
- Value *LHSOp, *RHSOp;
- if (match(Op0, m_PtrToInt(m_Value(LHSOp))) &&
- match(Op1, m_PtrToInt(m_Value(RHSOp))))
- if (Constant *Result = computePointerDifference(*Q.TD, LHSOp, RHSOp))
- return ConstantExpr::getIntegerCast(Result, Op0->getType(), true);
-
- // trunc(p)-trunc(q) -> trunc(p-q)
- if (match(Op0, m_Trunc(m_PtrToInt(m_Value(LHSOp)))) &&
- match(Op1, m_Trunc(m_PtrToInt(m_Value(RHSOp)))))
- if (Constant *Result = computePointerDifference(*Q.TD, LHSOp, RHSOp))
- return ConstantExpr::getIntegerCast(Result, Op0->getType(), true);
- }
-
// (X + Y) - Z -> X + (Y - Z) or Y + (X - Z) if everything simplifies.
// For example, (X + Y) - Y -> X; (Y + X) - Y -> X
Value *Y = 0, *Z = Op1;
@@ -848,6 +835,23 @@ static Value *SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
return W;
}
+ // trunc(X) - trunc(Y) -> trunc(X - Y) if everything simplifies.
+ if (MaxRecurse && match(Op0, m_Trunc(m_Value(X))) &&
+ match(Op1, m_Trunc(m_Value(Y))))
+ if (X->getType() == Y->getType())
+ // See if "V === X - Y" simplifies.
+ if (Value *V = SimplifyBinOp(Instruction::Sub, X, Y, Q, MaxRecurse-1))
+ // It does! Now see if "trunc V" simplifies.
+ if (Value *W = SimplifyTruncInst(V, Op0->getType(), Q, MaxRecurse-1))
+ // It does, return the simplified "trunc V".
+ return W;
+
+ // Variations on GEP(base, I, ...) - GEP(base, i, ...) -> GEP(null, I-i, ...).
+ if (Q.TD && match(Op0, m_PtrToInt(m_Value(X))) &&
+ match(Op1, m_PtrToInt(m_Value(Y))))
+ if (Constant *Result = computePointerDifference(*Q.TD, X, Y))
+ return ConstantExpr::getIntegerCast(Result, Op0->getType(), true);
+
// Mul distributes over Sub. Try some generic simplifications based on this.
if (Value *V = FactorizeBinOp(Instruction::Sub, Op0, Op1, Instruction::Mul,
Q, MaxRecurse))
@@ -2598,6 +2602,19 @@ static Value *SimplifyPHINode(PHINode *PN, const Query &Q) {
return CommonValue;
}
+static Value *SimplifyTruncInst(Value *Op, Type *Ty, const Query &Q, unsigned) {
+ if (Constant *C = dyn_cast<Constant>(Op))
+ return ConstantFoldInstOperands(Instruction::Trunc, Ty, C, Q.TD, Q.TLI);
+
+ return 0;
+}
+
+Value *llvm::SimplifyTruncInst(Value *Op, Type *Ty, const TargetData *TD,
+ const TargetLibraryInfo *TLI,
+ const DominatorTree *DT) {
+ return ::SimplifyTruncInst(Op, Ty, Query (TD, TLI, DT), RecursionLimit);
+}
+
//=== Helper functions for higher up the class hierarchy.
/// SimplifyBinOp - Given operands for a BinaryOperator, see if we can
@@ -2786,6 +2803,9 @@ Value *llvm::SimplifyInstruction(Instruction *I, const TargetData *TD,
case Instruction::Call:
Result = SimplifyCallInst(cast<CallInst>(I), Query (TD, TLI, DT));
break;
+ case Instruction::Trunc:
+ Result = SimplifyTruncInst(I->getOperand(0), I->getType(), TD, TLI, DT);
+ break;
}
/// If called on unreachable code, the above logic may report that the