forked from OSchip/llvm-project
Introduce ConstantFoldBinaryOpOperands function and migrate some callers of ConstantFoldInstOperands to use it. NFC.
Summary: Although this is a slight cleanup on its own, the main motivation is to refactor the constant folding API to ease migration to opaque pointers. This will be follow-up work. Reviewers: eddyb Subscribers: dblaikie, llvm-commits Differential Revision: http://reviews.llvm.org/D16378 llvm-svn: 258389
This commit is contained in:
parent
56ab5f0289
commit
a61ca37b6d
|
@ -65,6 +65,12 @@ ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS,
|
|||
Constant *RHS, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr);
|
||||
|
||||
/// \brief Attempt to constant fold a binary operation with the specified
|
||||
/// operands. If it fails, it returns a constant expression of the specified
|
||||
/// operands.
|
||||
Constant *ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS,
|
||||
Constant *RHS, const DataLayout &DL);
|
||||
|
||||
/// ConstantFoldInsertValueInstruction - Attempt to constant fold an insertvalue
|
||||
/// instruction with the specified operands and indices. The constant result is
|
||||
/// returned if successful; if not, null is returned.
|
||||
|
|
|
@ -1010,14 +1010,8 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
|
|||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI) {
|
||||
// Handle easy binops first.
|
||||
if (Instruction::isBinaryOp(Opcode)) {
|
||||
if (isa<ConstantExpr>(Ops[0]) || isa<ConstantExpr>(Ops[1])) {
|
||||
if (Constant *C = SymbolicallyEvaluateBinop(Opcode, Ops[0], Ops[1], DL))
|
||||
return C;
|
||||
}
|
||||
|
||||
return ConstantExpr::get(Opcode, Ops[0], Ops[1]);
|
||||
}
|
||||
if (Instruction::isBinaryOp(Opcode))
|
||||
return ConstantFoldBinaryOpOperands(Opcode, Ops[0], Ops[1], DL);
|
||||
|
||||
switch (Opcode) {
|
||||
default: return nullptr;
|
||||
|
@ -1176,14 +1170,23 @@ Constant *llvm::ConstantFoldCompareInstOperands(unsigned Predicate,
|
|||
Predicate, CE0->getOperand(1), Ops1, DL, TLI);
|
||||
unsigned OpC =
|
||||
Predicate == ICmpInst::ICMP_EQ ? Instruction::And : Instruction::Or;
|
||||
Constant *Ops[] = { LHS, RHS };
|
||||
return ConstantFoldInstOperands(OpC, LHS->getType(), Ops, DL, TLI);
|
||||
return ConstantFoldBinaryOpOperands(OpC, LHS, RHS, DL);
|
||||
}
|
||||
}
|
||||
|
||||
return ConstantExpr::getCompare(Predicate, Ops0, Ops1);
|
||||
}
|
||||
|
||||
Constant *llvm::ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS,
|
||||
Constant *RHS,
|
||||
const DataLayout &DL) {
|
||||
assert(Instruction::isBinaryOp(Opcode));
|
||||
if (isa<ConstantExpr>(LHS) || isa<ConstantExpr>(RHS))
|
||||
if (Constant *C = SymbolicallyEvaluateBinop(Opcode, LHS, RHS, DL))
|
||||
return C;
|
||||
|
||||
return ConstantExpr::get(Opcode, LHS, RHS);
|
||||
}
|
||||
|
||||
/// Given a constant and a getelementptr constantexpr, return the constant value
|
||||
/// being addressed by the constant expression, or null if something is funny
|
||||
|
|
|
@ -528,11 +528,8 @@ static Value *ThreadCmpOverPHI(CmpInst::Predicate Pred, Value *LHS, Value *RHS,
|
|||
static Value *SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
|
||||
const Query &Q, unsigned MaxRecurse) {
|
||||
if (Constant *CLHS = dyn_cast<Constant>(Op0)) {
|
||||
if (Constant *CRHS = dyn_cast<Constant>(Op1)) {
|
||||
Constant *Ops[] = { CLHS, CRHS };
|
||||
return ConstantFoldInstOperands(Instruction::Add, CLHS->getType(), Ops,
|
||||
Q.DL, Q.TLI);
|
||||
}
|
||||
if (Constant *CRHS = dyn_cast<Constant>(Op1))
|
||||
return ConstantFoldBinaryOpOperands(Instruction::Add, CLHS, CRHS, Q.DL);
|
||||
|
||||
// Canonicalize the constant to the RHS.
|
||||
std::swap(Op0, Op1);
|
||||
|
@ -660,11 +657,8 @@ static Constant *computePointerDifference(const DataLayout &DL, Value *LHS,
|
|||
static Value *SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
|
||||
const Query &Q, unsigned MaxRecurse) {
|
||||
if (Constant *CLHS = dyn_cast<Constant>(Op0))
|
||||
if (Constant *CRHS = dyn_cast<Constant>(Op1)) {
|
||||
Constant *Ops[] = { CLHS, CRHS };
|
||||
return ConstantFoldInstOperands(Instruction::Sub, CLHS->getType(),
|
||||
Ops, Q.DL, Q.TLI);
|
||||
}
|
||||
if (Constant *CRHS = dyn_cast<Constant>(Op1))
|
||||
return ConstantFoldBinaryOpOperands(Instruction::Sub, CLHS, CRHS, Q.DL);
|
||||
|
||||
// X - undef -> undef
|
||||
// undef - X -> undef
|
||||
|
@ -787,11 +781,8 @@ Value *llvm::SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
|
|||
static Value *SimplifyFAddInst(Value *Op0, Value *Op1, FastMathFlags FMF,
|
||||
const Query &Q, unsigned MaxRecurse) {
|
||||
if (Constant *CLHS = dyn_cast<Constant>(Op0)) {
|
||||
if (Constant *CRHS = dyn_cast<Constant>(Op1)) {
|
||||
Constant *Ops[] = { CLHS, CRHS };
|
||||
return ConstantFoldInstOperands(Instruction::FAdd, CLHS->getType(),
|
||||
Ops, Q.DL, Q.TLI);
|
||||
}
|
||||
if (Constant *CRHS = dyn_cast<Constant>(Op1))
|
||||
return ConstantFoldBinaryOpOperands(Instruction::FAdd, CLHS, CRHS, Q.DL);
|
||||
|
||||
// Canonicalize the constant to the RHS.
|
||||
std::swap(Op0, Op1);
|
||||
|
@ -829,11 +820,8 @@ static Value *SimplifyFAddInst(Value *Op0, Value *Op1, FastMathFlags FMF,
|
|||
static Value *SimplifyFSubInst(Value *Op0, Value *Op1, FastMathFlags FMF,
|
||||
const Query &Q, unsigned MaxRecurse) {
|
||||
if (Constant *CLHS = dyn_cast<Constant>(Op0)) {
|
||||
if (Constant *CRHS = dyn_cast<Constant>(Op1)) {
|
||||
Constant *Ops[] = { CLHS, CRHS };
|
||||
return ConstantFoldInstOperands(Instruction::FSub, CLHS->getType(),
|
||||
Ops, Q.DL, Q.TLI);
|
||||
}
|
||||
if (Constant *CRHS = dyn_cast<Constant>(Op1))
|
||||
return ConstantFoldBinaryOpOperands(Instruction::FSub, CLHS, CRHS, Q.DL);
|
||||
}
|
||||
|
||||
// fsub X, 0 ==> X
|
||||
|
@ -867,11 +855,8 @@ static Value *SimplifyFMulInst(Value *Op0, Value *Op1,
|
|||
const Query &Q,
|
||||
unsigned MaxRecurse) {
|
||||
if (Constant *CLHS = dyn_cast<Constant>(Op0)) {
|
||||
if (Constant *CRHS = dyn_cast<Constant>(Op1)) {
|
||||
Constant *Ops[] = { CLHS, CRHS };
|
||||
return ConstantFoldInstOperands(Instruction::FMul, CLHS->getType(),
|
||||
Ops, Q.DL, Q.TLI);
|
||||
}
|
||||
if (Constant *CRHS = dyn_cast<Constant>(Op1))
|
||||
return ConstantFoldBinaryOpOperands(Instruction::FMul, CLHS, CRHS, Q.DL);
|
||||
|
||||
// Canonicalize the constant to the RHS.
|
||||
std::swap(Op0, Op1);
|
||||
|
@ -893,11 +878,8 @@ static Value *SimplifyFMulInst(Value *Op0, Value *Op1,
|
|||
static Value *SimplifyMulInst(Value *Op0, Value *Op1, const Query &Q,
|
||||
unsigned MaxRecurse) {
|
||||
if (Constant *CLHS = dyn_cast<Constant>(Op0)) {
|
||||
if (Constant *CRHS = dyn_cast<Constant>(Op1)) {
|
||||
Constant *Ops[] = { CLHS, CRHS };
|
||||
return ConstantFoldInstOperands(Instruction::Mul, CLHS->getType(),
|
||||
Ops, Q.DL, Q.TLI);
|
||||
}
|
||||
if (Constant *CRHS = dyn_cast<Constant>(Op1))
|
||||
return ConstantFoldBinaryOpOperands(Instruction::Mul, CLHS, CRHS, Q.DL);
|
||||
|
||||
// Canonicalize the constant to the RHS.
|
||||
std::swap(Op0, Op1);
|
||||
|
@ -992,12 +974,9 @@ Value *llvm::SimplifyMulInst(Value *Op0, Value *Op1, const DataLayout &DL,
|
|||
/// If not, this returns null.
|
||||
static Value *SimplifyDiv(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1,
|
||||
const Query &Q, unsigned MaxRecurse) {
|
||||
if (Constant *C0 = dyn_cast<Constant>(Op0)) {
|
||||
if (Constant *C1 = dyn_cast<Constant>(Op1)) {
|
||||
Constant *Ops[] = { C0, C1 };
|
||||
return ConstantFoldInstOperands(Opcode, C0->getType(), Ops, Q.DL, Q.TLI);
|
||||
}
|
||||
}
|
||||
if (Constant *C0 = dyn_cast<Constant>(Op0))
|
||||
if (Constant *C1 = dyn_cast<Constant>(Op1))
|
||||
return ConstantFoldBinaryOpOperands(Opcode, C0, C1, Q.DL);
|
||||
|
||||
bool isSigned = Opcode == Instruction::SDiv;
|
||||
|
||||
|
@ -1157,12 +1136,9 @@ Value *llvm::SimplifyFDivInst(Value *Op0, Value *Op1, FastMathFlags FMF,
|
|||
/// If not, this returns null.
|
||||
static Value *SimplifyRem(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1,
|
||||
const Query &Q, unsigned MaxRecurse) {
|
||||
if (Constant *C0 = dyn_cast<Constant>(Op0)) {
|
||||
if (Constant *C1 = dyn_cast<Constant>(Op1)) {
|
||||
Constant *Ops[] = { C0, C1 };
|
||||
return ConstantFoldInstOperands(Opcode, C0->getType(), Ops, Q.DL, Q.TLI);
|
||||
}
|
||||
}
|
||||
if (Constant *C0 = dyn_cast<Constant>(Op0))
|
||||
if (Constant *C1 = dyn_cast<Constant>(Op1))
|
||||
return ConstantFoldBinaryOpOperands(Opcode, C0, C1, Q.DL);
|
||||
|
||||
// X % undef -> undef
|
||||
if (match(Op1, m_Undef()))
|
||||
|
@ -1309,12 +1285,9 @@ static bool isUndefShift(Value *Amount) {
|
|||
/// If not, this returns null.
|
||||
static Value *SimplifyShift(unsigned Opcode, Value *Op0, Value *Op1,
|
||||
const Query &Q, unsigned MaxRecurse) {
|
||||
if (Constant *C0 = dyn_cast<Constant>(Op0)) {
|
||||
if (Constant *C1 = dyn_cast<Constant>(Op1)) {
|
||||
Constant *Ops[] = { C0, C1 };
|
||||
return ConstantFoldInstOperands(Opcode, C0->getType(), Ops, Q.DL, Q.TLI);
|
||||
}
|
||||
}
|
||||
if (Constant *C0 = dyn_cast<Constant>(Op0))
|
||||
if (Constant *C1 = dyn_cast<Constant>(Op1))
|
||||
return ConstantFoldBinaryOpOperands(Opcode, C0, C1, Q.DL);
|
||||
|
||||
// 0 shift by X -> 0
|
||||
if (match(Op0, m_Zero()))
|
||||
|
@ -1558,11 +1531,8 @@ static Value *SimplifyAndOfICmps(ICmpInst *Op0, ICmpInst *Op1) {
|
|||
static Value *SimplifyAndInst(Value *Op0, Value *Op1, const Query &Q,
|
||||
unsigned MaxRecurse) {
|
||||
if (Constant *CLHS = dyn_cast<Constant>(Op0)) {
|
||||
if (Constant *CRHS = dyn_cast<Constant>(Op1)) {
|
||||
Constant *Ops[] = { CLHS, CRHS };
|
||||
return ConstantFoldInstOperands(Instruction::And, CLHS->getType(),
|
||||
Ops, Q.DL, Q.TLI);
|
||||
}
|
||||
if (Constant *CRHS = dyn_cast<Constant>(Op1))
|
||||
return ConstantFoldBinaryOpOperands(Instruction::And, CLHS, CRHS, Q.DL);
|
||||
|
||||
// Canonicalize the constant to the RHS.
|
||||
std::swap(Op0, Op1);
|
||||
|
@ -1717,11 +1687,8 @@ static Value *SimplifyOrOfICmps(ICmpInst *Op0, ICmpInst *Op1) {
|
|||
static Value *SimplifyOrInst(Value *Op0, Value *Op1, const Query &Q,
|
||||
unsigned MaxRecurse) {
|
||||
if (Constant *CLHS = dyn_cast<Constant>(Op0)) {
|
||||
if (Constant *CRHS = dyn_cast<Constant>(Op1)) {
|
||||
Constant *Ops[] = { CLHS, CRHS };
|
||||
return ConstantFoldInstOperands(Instruction::Or, CLHS->getType(),
|
||||
Ops, Q.DL, Q.TLI);
|
||||
}
|
||||
if (Constant *CRHS = dyn_cast<Constant>(Op1))
|
||||
return ConstantFoldBinaryOpOperands(Instruction::Or, CLHS, CRHS, Q.DL);
|
||||
|
||||
// Canonicalize the constant to the RHS.
|
||||
std::swap(Op0, Op1);
|
||||
|
@ -1853,11 +1820,8 @@ Value *llvm::SimplifyOrInst(Value *Op0, Value *Op1, const DataLayout &DL,
|
|||
static Value *SimplifyXorInst(Value *Op0, Value *Op1, const Query &Q,
|
||||
unsigned MaxRecurse) {
|
||||
if (Constant *CLHS = dyn_cast<Constant>(Op0)) {
|
||||
if (Constant *CRHS = dyn_cast<Constant>(Op1)) {
|
||||
Constant *Ops[] = { CLHS, CRHS };
|
||||
return ConstantFoldInstOperands(Instruction::Xor, CLHS->getType(),
|
||||
Ops, Q.DL, Q.TLI);
|
||||
}
|
||||
if (Constant *CRHS = dyn_cast<Constant>(Op1))
|
||||
return ConstantFoldBinaryOpOperands(Instruction::Xor, CLHS, CRHS, Q.DL);
|
||||
|
||||
// Canonicalize the constant to the RHS.
|
||||
std::swap(Op0, Op1);
|
||||
|
@ -3730,11 +3694,8 @@ static Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
|
|||
case Instruction::Xor: return SimplifyXorInst(LHS, RHS, Q, MaxRecurse);
|
||||
default:
|
||||
if (Constant *CLHS = dyn_cast<Constant>(LHS))
|
||||
if (Constant *CRHS = dyn_cast<Constant>(RHS)) {
|
||||
Constant *COps[] = {CLHS, CRHS};
|
||||
return ConstantFoldInstOperands(Opcode, LHS->getType(), COps, Q.DL,
|
||||
Q.TLI);
|
||||
}
|
||||
if (Constant *CRHS = dyn_cast<Constant>(RHS))
|
||||
return ConstantFoldBinaryOpOperands(Opcode, CLHS, CRHS, Q.DL);
|
||||
|
||||
// If the operation is associative, try some generic simplifications.
|
||||
if (Instruction::isAssociative(Opcode))
|
||||
|
|
Loading…
Reference in New Issue