mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-04 06:26:28 +00:00
[InstCombine, InstSimplify] Move xforms from Combine to Simplify
There were several SelectInst combines that always returned an existing instruction instead of modifying an old one or creating a new one. These are prime candidates for moving to InstSimplify. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239229 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -276,85 +276,6 @@ Instruction *InstCombiner::FoldSelectIntoOp(SelectInst &SI, Value *TrueVal,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// SimplifyWithOpReplaced - See if V simplifies when its operand Op is
|
||||
/// replaced with RepOp.
|
||||
static Value *SimplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DataLayout &DL, DominatorTree *DT,
|
||||
AssumptionCache *AC) {
|
||||
// Trivial replacement.
|
||||
if (V == Op)
|
||||
return RepOp;
|
||||
|
||||
Instruction *I = dyn_cast<Instruction>(V);
|
||||
if (!I)
|
||||
return nullptr;
|
||||
|
||||
// If this is a binary operator, try to simplify it with the replaced op.
|
||||
if (BinaryOperator *B = dyn_cast<BinaryOperator>(I)) {
|
||||
// Consider:
|
||||
// %cmp = icmp eq i32 %x, 2147483647
|
||||
// %add = add nsw i32 %x, 1
|
||||
// %sel = select i1 %cmp, i32 -2147483648, i32 %add
|
||||
//
|
||||
// We can't replace %sel with %add unless we strip away the flags.
|
||||
if (isa<OverflowingBinaryOperator>(B))
|
||||
if (B->hasNoSignedWrap() || B->hasNoUnsignedWrap())
|
||||
return nullptr;
|
||||
if (isa<PossiblyExactOperator>(B))
|
||||
if (B->isExact())
|
||||
return nullptr;
|
||||
|
||||
if (B->getOperand(0) == Op)
|
||||
return SimplifyBinOp(B->getOpcode(), RepOp, B->getOperand(1), DL, TLI);
|
||||
if (B->getOperand(1) == Op)
|
||||
return SimplifyBinOp(B->getOpcode(), B->getOperand(0), RepOp, DL, TLI);
|
||||
}
|
||||
|
||||
// Same for CmpInsts.
|
||||
if (CmpInst *C = dyn_cast<CmpInst>(I)) {
|
||||
if (C->getOperand(0) == Op)
|
||||
return SimplifyCmpInst(C->getPredicate(), RepOp, C->getOperand(1), DL,
|
||||
TLI, DT, AC);
|
||||
if (C->getOperand(1) == Op)
|
||||
return SimplifyCmpInst(C->getPredicate(), C->getOperand(0), RepOp, DL,
|
||||
TLI, DT, AC);
|
||||
}
|
||||
|
||||
// TODO: We could hand off more cases to instsimplify here.
|
||||
|
||||
// If all operands are constant after substituting Op for RepOp then we can
|
||||
// constant fold the instruction.
|
||||
if (Constant *CRepOp = dyn_cast<Constant>(RepOp)) {
|
||||
// Build a list of all constant operands.
|
||||
SmallVector<Constant*, 8> ConstOps;
|
||||
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
|
||||
if (I->getOperand(i) == Op)
|
||||
ConstOps.push_back(CRepOp);
|
||||
else if (Constant *COp = dyn_cast<Constant>(I->getOperand(i)))
|
||||
ConstOps.push_back(COp);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
// All operands were constants, fold it.
|
||||
if (ConstOps.size() == I->getNumOperands()) {
|
||||
if (CmpInst *C = dyn_cast<CmpInst>(I))
|
||||
return ConstantFoldCompareInstOperands(C->getPredicate(), ConstOps[0],
|
||||
ConstOps[1], DL, TLI);
|
||||
|
||||
if (LoadInst *LI = dyn_cast<LoadInst>(I))
|
||||
if (!LI->isVolatile())
|
||||
return ConstantFoldLoadFromConstPtr(ConstOps[0], DL);
|
||||
|
||||
return ConstantFoldInstOperands(I->getOpcode(), I->getType(), ConstOps,
|
||||
DL, TLI);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// foldSelectICmpAndOr - We want to turn:
|
||||
/// (select (icmp eq (and X, C1), 0), Y, (or Y, C2))
|
||||
/// into:
|
||||
@@ -490,14 +411,6 @@ Instruction *InstCombiner::visitSelectInstWithICmp(SelectInst &SI,
|
||||
// here, so make sure the select is the only user.
|
||||
if (ICI->hasOneUse())
|
||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(CmpRHS)) {
|
||||
// X < MIN ? T : F --> F
|
||||
if ((Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_ULT)
|
||||
&& CI->isMinValue(Pred == ICmpInst::ICMP_SLT))
|
||||
return ReplaceInstUsesWith(SI, FalseVal);
|
||||
// X > MAX ? T : F --> F
|
||||
else if ((Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_UGT)
|
||||
&& CI->isMaxValue(Pred == ICmpInst::ICMP_SGT))
|
||||
return ReplaceInstUsesWith(SI, FalseVal);
|
||||
switch (Pred) {
|
||||
default: break;
|
||||
case ICmpInst::ICMP_ULT:
|
||||
@@ -611,33 +524,6 @@ Instruction *InstCombiner::visitSelectInstWithICmp(SelectInst &SI,
|
||||
}
|
||||
}
|
||||
|
||||
// If we have an equality comparison then we know the value in one of the
|
||||
// arms of the select. See if substituting this value into the arm and
|
||||
// simplifying the result yields the same value as the other arm.
|
||||
if (Pred == ICmpInst::ICMP_EQ) {
|
||||
if (SimplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, TLI, DL, DT, AC) ==
|
||||
TrueVal ||
|
||||
SimplifyWithOpReplaced(FalseVal, CmpRHS, CmpLHS, TLI, DL, DT, AC) ==
|
||||
TrueVal)
|
||||
return ReplaceInstUsesWith(SI, FalseVal);
|
||||
if (SimplifyWithOpReplaced(TrueVal, CmpLHS, CmpRHS, TLI, DL, DT, AC) ==
|
||||
FalseVal ||
|
||||
SimplifyWithOpReplaced(TrueVal, CmpRHS, CmpLHS, TLI, DL, DT, AC) ==
|
||||
FalseVal)
|
||||
return ReplaceInstUsesWith(SI, FalseVal);
|
||||
} else if (Pred == ICmpInst::ICMP_NE) {
|
||||
if (SimplifyWithOpReplaced(TrueVal, CmpLHS, CmpRHS, TLI, DL, DT, AC) ==
|
||||
FalseVal ||
|
||||
SimplifyWithOpReplaced(TrueVal, CmpRHS, CmpLHS, TLI, DL, DT, AC) ==
|
||||
FalseVal)
|
||||
return ReplaceInstUsesWith(SI, TrueVal);
|
||||
if (SimplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, TLI, DL, DT, AC) ==
|
||||
TrueVal ||
|
||||
SimplifyWithOpReplaced(FalseVal, CmpRHS, CmpLHS, TLI, DL, DT, AC) ==
|
||||
TrueVal)
|
||||
return ReplaceInstUsesWith(SI, TrueVal);
|
||||
}
|
||||
|
||||
// NOTE: if we wanted to, this is where to detect integer MIN/MAX
|
||||
|
||||
if (CmpRHS != CmpLHS && isa<Constant>(CmpRHS)) {
|
||||
@@ -652,7 +538,8 @@ Instruction *InstCombiner::visitSelectInstWithICmp(SelectInst &SI,
|
||||
}
|
||||
}
|
||||
|
||||
if (unsigned BitWidth = TrueVal->getType()->getScalarSizeInBits()) {
|
||||
{
|
||||
unsigned BitWidth = DL.getTypeSizeInBits(TrueVal->getType());
|
||||
APInt MinSignedValue = APInt::getSignBit(BitWidth);
|
||||
Value *X;
|
||||
const APInt *Y, *C;
|
||||
|
Reference in New Issue
Block a user