mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-24 04:09:45 +00:00
[InstCombine] add a wrapper for a common pair of transforms; NFCI
Some of the callers are artificially limiting this transform to integer types; this should make it easier to incrementally remove that restriction. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@291620 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
108d72a027
commit
e9fdb8bc46
@ -1371,15 +1371,9 @@ Instruction *InstCombiner::visitFAdd(BinaryOperator &I) {
|
|||||||
SimplifyFAddInst(LHS, RHS, I.getFastMathFlags(), DL, &TLI, &DT, &AC))
|
SimplifyFAddInst(LHS, RHS, I.getFastMathFlags(), DL, &TLI, &DT, &AC))
|
||||||
return replaceInstUsesWith(I, V);
|
return replaceInstUsesWith(I, V);
|
||||||
|
|
||||||
if (isa<Constant>(RHS)) {
|
if (isa<Constant>(RHS))
|
||||||
if (isa<PHINode>(LHS))
|
if (Instruction *FoldedFAdd = foldOpWithConstantIntoOperand(I))
|
||||||
if (Instruction *NV = FoldOpIntoPhi(I))
|
return FoldedFAdd;
|
||||||
return NV;
|
|
||||||
|
|
||||||
if (SelectInst *SI = dyn_cast<SelectInst>(LHS))
|
|
||||||
if (Instruction *NV = FoldOpIntoSelect(I, SI))
|
|
||||||
return NV;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -A + B --> B - A
|
// -A + B --> B - A
|
||||||
// -A + -B --> -(A + B)
|
// -A + -B --> -(A + B)
|
||||||
|
@ -1382,13 +1382,8 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to fold constant and into select arguments.
|
if (Instruction *FoldedLogic = foldOpWithConstantIntoOperand(I))
|
||||||
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
|
return FoldedLogic;
|
||||||
if (Instruction *R = FoldOpIntoSelect(I, SI))
|
|
||||||
return R;
|
|
||||||
if (isa<PHINode>(Op0))
|
|
||||||
if (Instruction *NV = FoldOpIntoPhi(I))
|
|
||||||
return NV;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Instruction *DeMorgan = matchDeMorgansLaws(I, Builder))
|
if (Instruction *DeMorgan = matchDeMorgansLaws(I, Builder))
|
||||||
@ -2125,14 +2120,8 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
|
|||||||
Builder->getInt(C1->getValue() & ~RHS->getValue()));
|
Builder->getInt(C1->getValue() & ~RHS->getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to fold constant and into select arguments.
|
if (Instruction *FoldedLogic = foldOpWithConstantIntoOperand(I))
|
||||||
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
|
return FoldedLogic;
|
||||||
if (Instruction *R = FoldOpIntoSelect(I, SI))
|
|
||||||
return R;
|
|
||||||
|
|
||||||
if (isa<PHINode>(Op0))
|
|
||||||
if (Instruction *NV = FoldOpIntoPhi(I))
|
|
||||||
return NV;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given an OR instruction, check to see if this is a bswap.
|
// Given an OR instruction, check to see if this is a bswap.
|
||||||
@ -2594,13 +2583,8 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to fold constant and into select arguments.
|
if (Instruction *FoldedLogic = foldOpWithConstantIntoOperand(I))
|
||||||
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
|
return FoldedLogic;
|
||||||
if (Instruction *R = FoldOpIntoSelect(I, SI))
|
|
||||||
return R;
|
|
||||||
if (isa<PHINode>(Op0))
|
|
||||||
if (Instruction *NV = FoldOpIntoPhi(I))
|
|
||||||
return NV;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BinaryOperator *Op1I = dyn_cast<BinaryOperator>(Op1);
|
BinaryOperator *Op1I = dyn_cast<BinaryOperator>(Op1);
|
||||||
|
@ -320,7 +320,6 @@ private:
|
|||||||
Value *dyn_castFNegVal(Value *V, bool NoSignedZero = false) const;
|
Value *dyn_castFNegVal(Value *V, bool NoSignedZero = false) const;
|
||||||
Type *FindElementAtOffset(PointerType *PtrTy, int64_t Offset,
|
Type *FindElementAtOffset(PointerType *PtrTy, int64_t Offset,
|
||||||
SmallVectorImpl<Value *> &NewIndices);
|
SmallVectorImpl<Value *> &NewIndices);
|
||||||
Instruction *FoldOpIntoSelect(Instruction &Op, SelectInst *SI);
|
|
||||||
|
|
||||||
/// Classify whether a cast is worth optimizing.
|
/// Classify whether a cast is worth optimizing.
|
||||||
///
|
///
|
||||||
@ -537,13 +536,21 @@ private:
|
|||||||
Value *SimplifyVectorOp(BinaryOperator &Inst);
|
Value *SimplifyVectorOp(BinaryOperator &Inst);
|
||||||
Value *SimplifyBSwap(BinaryOperator &Inst);
|
Value *SimplifyBSwap(BinaryOperator &Inst);
|
||||||
|
|
||||||
// FoldOpIntoPhi - Given a binary operator, cast instruction, or select
|
|
||||||
// which has a PHI node as operand #0, see if we can fold the instruction
|
/// Given a binary operator, cast instruction, or select which has a PHI node
|
||||||
// into the PHI (which is only possible if all operands to the PHI are
|
/// as operand #0, see if we can fold the instruction into the PHI (which is
|
||||||
// constants).
|
/// only possible if all operands to the PHI are constants).
|
||||||
//
|
|
||||||
Instruction *FoldOpIntoPhi(Instruction &I);
|
Instruction *FoldOpIntoPhi(Instruction &I);
|
||||||
|
|
||||||
|
/// Given an instruction with a select as one operand and a constant as the
|
||||||
|
/// other operand, try to fold the binary operator into the select arguments.
|
||||||
|
/// This also works for Cast instructions, which obviously do not have a
|
||||||
|
/// second operand.
|
||||||
|
Instruction *FoldOpIntoSelect(Instruction &Op, SelectInst *SI);
|
||||||
|
|
||||||
|
/// This is a convenience wrapper function for the above two functions.
|
||||||
|
Instruction *foldOpWithConstantIntoOperand(Instruction &I);
|
||||||
|
|
||||||
/// \brief Try to rotate an operation below a PHI node, using PHI nodes for
|
/// \brief Try to rotate an operation below a PHI node, using PHI nodes for
|
||||||
/// its operands.
|
/// its operands.
|
||||||
Instruction *FoldPHIArgOpIntoPHI(PHINode &PN);
|
Instruction *FoldPHIArgOpIntoPHI(PHINode &PN);
|
||||||
|
@ -267,14 +267,8 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
|
|||||||
|
|
||||||
// Simplify mul instructions with a constant RHS.
|
// Simplify mul instructions with a constant RHS.
|
||||||
if (isa<Constant>(Op1)) {
|
if (isa<Constant>(Op1)) {
|
||||||
// Try to fold constant mul into select arguments.
|
if (Instruction *FoldedMul = foldOpWithConstantIntoOperand(I))
|
||||||
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
|
return FoldedMul;
|
||||||
if (Instruction *R = FoldOpIntoSelect(I, SI))
|
|
||||||
return R;
|
|
||||||
|
|
||||||
if (isa<PHINode>(Op0))
|
|
||||||
if (Instruction *NV = FoldOpIntoPhi(I))
|
|
||||||
return NV;
|
|
||||||
|
|
||||||
// Canonicalize (X+C1)*CI -> X*CI+C1*CI.
|
// Canonicalize (X+C1)*CI -> X*CI+C1*CI.
|
||||||
{
|
{
|
||||||
@ -626,14 +620,8 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) {
|
|||||||
|
|
||||||
// Simplify mul instructions with a constant RHS.
|
// Simplify mul instructions with a constant RHS.
|
||||||
if (isa<Constant>(Op1)) {
|
if (isa<Constant>(Op1)) {
|
||||||
// Try to fold constant mul into select arguments.
|
if (Instruction *FoldedMul = foldOpWithConstantIntoOperand(I))
|
||||||
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
|
return FoldedMul;
|
||||||
if (Instruction *R = FoldOpIntoSelect(I, SI))
|
|
||||||
return R;
|
|
||||||
|
|
||||||
if (isa<PHINode>(Op0))
|
|
||||||
if (Instruction *NV = FoldOpIntoPhi(I))
|
|
||||||
return NV;
|
|
||||||
|
|
||||||
// (fmul X, -1.0) --> (fsub -0.0, X)
|
// (fmul X, -1.0) --> (fsub -0.0, X)
|
||||||
if (match(Op1, m_SpecificFP(-1.0))) {
|
if (match(Op1, m_SpecificFP(-1.0))) {
|
||||||
@ -956,14 +944,9 @@ Instruction *InstCombiner::commonIDivTransforms(BinaryOperator &I) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*C2 != 0) { // avoid X udiv 0
|
if (*C2 != 0) // avoid X udiv 0
|
||||||
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
|
if (Instruction *FoldedDiv = foldOpWithConstantIntoOperand(I))
|
||||||
if (Instruction *R = FoldOpIntoSelect(I, SI))
|
return FoldedDiv;
|
||||||
return R;
|
|
||||||
if (isa<PHINode>(Op0))
|
|
||||||
if (Instruction *NV = FoldOpIntoPhi(I))
|
|
||||||
return NV;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,13 +530,8 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, Constant *Op1,
|
|||||||
return BinaryOperator::CreateMul(BO->getOperand(0),
|
return BinaryOperator::CreateMul(BO->getOperand(0),
|
||||||
ConstantExpr::getShl(BOOp, Op1));
|
ConstantExpr::getShl(BOOp, Op1));
|
||||||
|
|
||||||
// Try to fold constant and into select arguments.
|
if (Instruction *FoldedShift = foldOpWithConstantIntoOperand(I))
|
||||||
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
|
return FoldedShift;
|
||||||
if (Instruction *R = FoldOpIntoSelect(I, SI))
|
|
||||||
return R;
|
|
||||||
if (isa<PHINode>(Op0))
|
|
||||||
if (Instruction *NV = FoldOpIntoPhi(I))
|
|
||||||
return NV;
|
|
||||||
|
|
||||||
// Fold shift2(trunc(shift1(x,c1)), c2) -> trunc(shift2(shift1(x,c1),c2))
|
// Fold shift2(trunc(shift1(x,c1)), c2) -> trunc(shift2(shift1(x,c1),c2))
|
||||||
if (TruncInst *TI = dyn_cast<TruncInst>(Op0)) {
|
if (TruncInst *TI = dyn_cast<TruncInst>(Op0)) {
|
||||||
|
@ -770,10 +770,6 @@ static Value *foldOperationIntoSelectOperand(Instruction &I, Value *SO,
|
|||||||
return RI;
|
return RI;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given an instruction with a select as one operand and a constant as the
|
|
||||||
/// other operand, try to fold the binary operator into the select arguments.
|
|
||||||
/// This also works for Cast instructions, which obviously do not have a second
|
|
||||||
/// operand.
|
|
||||||
Instruction *InstCombiner::FoldOpIntoSelect(Instruction &Op, SelectInst *SI) {
|
Instruction *InstCombiner::FoldOpIntoSelect(Instruction &Op, SelectInst *SI) {
|
||||||
// Don't modify shared select instructions.
|
// Don't modify shared select instructions.
|
||||||
if (!SI->hasOneUse())
|
if (!SI->hasOneUse())
|
||||||
@ -824,9 +820,6 @@ Instruction *InstCombiner::FoldOpIntoSelect(Instruction &Op, SelectInst *SI) {
|
|||||||
return SelectInst::Create(SI->getCondition(), NewTV, NewFV, "", nullptr, SI);
|
return SelectInst::Create(SI->getCondition(), NewTV, NewFV, "", nullptr, SI);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given a binary operator, cast instruction, or select which has a PHI node as
|
|
||||||
/// operand #0, see if we can fold the instruction into the PHI (which is only
|
|
||||||
/// possible if all operands to the PHI are constants).
|
|
||||||
Instruction *InstCombiner::FoldOpIntoPhi(Instruction &I) {
|
Instruction *InstCombiner::FoldOpIntoPhi(Instruction &I) {
|
||||||
PHINode *PN = cast<PHINode>(I.getOperand(0));
|
PHINode *PN = cast<PHINode>(I.getOperand(0));
|
||||||
unsigned NumPHIValues = PN->getNumIncomingValues();
|
unsigned NumPHIValues = PN->getNumIncomingValues();
|
||||||
@ -964,6 +957,19 @@ Instruction *InstCombiner::FoldOpIntoPhi(Instruction &I) {
|
|||||||
return replaceInstUsesWith(I, NewPN);
|
return replaceInstUsesWith(I, NewPN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Instruction *InstCombiner::foldOpWithConstantIntoOperand(Instruction &I) {
|
||||||
|
assert(isa<Constant>(I.getOperand(1)) && "Unexpected operand type");
|
||||||
|
|
||||||
|
if (auto *Sel = dyn_cast<SelectInst>(I.getOperand(0))) {
|
||||||
|
if (Instruction *NewSel = FoldOpIntoSelect(I, Sel))
|
||||||
|
return NewSel;
|
||||||
|
} else if (isa<PHINode>(I.getOperand(0))) {
|
||||||
|
if (Instruction *NewPhi = FoldOpIntoPhi(I))
|
||||||
|
return NewPhi;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
/// Given a pointer type and a constant offset, determine whether or not there
|
/// Given a pointer type and a constant offset, determine whether or not there
|
||||||
/// is a sequence of GEP indices into the pointed type that will land us at the
|
/// is a sequence of GEP indices into the pointed type that will land us at the
|
||||||
/// specified offset. If so, fill them into NewIndices and return the resultant
|
/// specified offset. If so, fill them into NewIndices and return the resultant
|
||||||
|
Loading…
Reference in New Issue
Block a user