mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-08 19:25:47 +00:00
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
This commit is contained in:
@@ -20,13 +20,14 @@
|
|||||||
#define LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
|
#define LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
class DominatorTree;
|
|
||||||
class Instruction;
|
|
||||||
class Value;
|
|
||||||
class TargetData;
|
|
||||||
class TargetLibraryInfo;
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class ArrayRef;
|
class ArrayRef;
|
||||||
|
class DominatorTree;
|
||||||
|
class Instruction;
|
||||||
|
class TargetData;
|
||||||
|
class TargetLibraryInfo;
|
||||||
|
class Type;
|
||||||
|
class Value;
|
||||||
|
|
||||||
/// SimplifyAddInst - Given operands for an Add, see if we can
|
/// SimplifyAddInst - Given operands for an Add, see if we can
|
||||||
/// fold the result. If not, this returns null.
|
/// fold the result. If not, this returns null.
|
||||||
@@ -158,6 +159,12 @@ namespace llvm {
|
|||||||
const TargetLibraryInfo *TLI = 0,
|
const TargetLibraryInfo *TLI = 0,
|
||||||
const DominatorTree *DT = 0);
|
const DominatorTree *DT = 0);
|
||||||
|
|
||||||
|
/// SimplifyTruncInst - Given operands for an TruncInst, see if we can fold
|
||||||
|
/// the result. If not, this returns null.
|
||||||
|
Value *SimplifyTruncInst(Value *Op, Type *Ty, const TargetData *TD = 0,
|
||||||
|
const TargetLibraryInfo *TLI = 0,
|
||||||
|
const DominatorTree *DT = 0);
|
||||||
|
|
||||||
//=== Helper functions for higher up the class hierarchy.
|
//=== Helper functions for higher up the class hierarchy.
|
||||||
|
|
||||||
|
|
||||||
|
@@ -56,6 +56,7 @@ static Value *SimplifyCmpInst(unsigned, Value *, Value *, const Query &,
|
|||||||
unsigned);
|
unsigned);
|
||||||
static Value *SimplifyOrInst(Value *, Value *, const Query &, unsigned);
|
static Value *SimplifyOrInst(Value *, Value *, const Query &, unsigned);
|
||||||
static Value *SimplifyXorInst(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
|
/// 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.
|
/// 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())))
|
match(Op0, m_Shl(m_Specific(Op1), m_One())))
|
||||||
return Op1;
|
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.
|
// (X + Y) - Z -> X + (Y - Z) or Y + (X - Z) if everything simplifies.
|
||||||
// For example, (X + Y) - Y -> X; (Y + X) - Y -> X
|
// For example, (X + Y) - Y -> X; (Y + X) - Y -> X
|
||||||
Value *Y = 0, *Z = Op1;
|
Value *Y = 0, *Z = Op1;
|
||||||
@@ -848,6 +835,23 @@ static Value *SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
|
|||||||
return W;
|
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.
|
// Mul distributes over Sub. Try some generic simplifications based on this.
|
||||||
if (Value *V = FactorizeBinOp(Instruction::Sub, Op0, Op1, Instruction::Mul,
|
if (Value *V = FactorizeBinOp(Instruction::Sub, Op0, Op1, Instruction::Mul,
|
||||||
Q, MaxRecurse))
|
Q, MaxRecurse))
|
||||||
@@ -2598,6 +2602,19 @@ static Value *SimplifyPHINode(PHINode *PN, const Query &Q) {
|
|||||||
return CommonValue;
|
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.
|
//=== Helper functions for higher up the class hierarchy.
|
||||||
|
|
||||||
/// SimplifyBinOp - Given operands for a BinaryOperator, see if we can
|
/// 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:
|
case Instruction::Call:
|
||||||
Result = SimplifyCallInst(cast<CallInst>(I), Query (TD, TLI, DT));
|
Result = SimplifyCallInst(cast<CallInst>(I), Query (TD, TLI, DT));
|
||||||
break;
|
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
|
/// If called on unreachable code, the above logic may report that the
|
||||||
|
@@ -184,3 +184,12 @@ define i32 @udiv5(i32 %x, i32 %y) {
|
|||||||
; CHECK: ret i32 %x
|
; CHECK: ret i32 %x
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define i16 @trunc1(i32 %x) {
|
||||||
|
; CHECK: @trunc1
|
||||||
|
%y = add i32 %x, 1
|
||||||
|
%tx = trunc i32 %x to i16
|
||||||
|
%ty = trunc i32 %y to i16
|
||||||
|
%d = sub i16 %ty, %tx
|
||||||
|
ret i16 %d
|
||||||
|
; CHECK: ret i16 1
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user