Please use GitHub pull requests for new patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 4,096 Lines • ▼ Show 20 Lines | getKnownSign(Value *Op, Instruction *CxtI, const DataLayout &DL, | ||||
Value *X, *Y; | Value *X, *Y; | ||||
if (match(Op, m_NSWSub(m_Value(X), m_Value(Y)))) | if (match(Op, m_NSWSub(m_Value(X), m_Value(Y)))) | ||||
return isImpliedByDomCondition(ICmpInst::ICMP_SLT, X, Y, CxtI, DL); | return isImpliedByDomCondition(ICmpInst::ICMP_SLT, X, Y, CxtI, DL); | ||||
return isImpliedByDomCondition( | return isImpliedByDomCondition( | ||||
ICmpInst::ICMP_SLT, Op, Constant::getNullValue(Op->getType()), CxtI, DL); | ICmpInst::ICMP_SLT, Op, Constant::getNullValue(Op->getType()), CxtI, DL); | ||||
} | } | ||||
static std::optional<bool> getKnownSign(Value *Op, Instruction *CxtI, | |||||
const DataLayout &DL, | |||||
AssumptionCache *AC, | |||||
const DominatorTree *DT) { | |||||
KnownBits Known; | |||||
return getKnownSign(Op, CxtI, DL, AC, DT, Known); | |||||
} | |||||
static Instruction *foldICmpOrXX(ICmpInst &I, const SimplifyQuery &Q, | static Instruction *foldICmpOrXX(ICmpInst &I, const SimplifyQuery &Q, | ||||
InstCombinerImpl &IC) { | InstCombinerImpl &IC) { | ||||
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1), *A; | Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1), *A; | ||||
// Normalize or operand as operand 0. | // Normalize or operand as operand 0. | ||||
CmpInst::Predicate Pred = I.getPredicate(); | CmpInst::Predicate Pred = I.getPredicate(); | ||||
if (match(Op1, m_c_Or(m_Specific(Op0), m_Value()))) { | if (match(Op1, m_c_Or(m_Specific(Op0), m_Value()))) { | ||||
std::swap(Op0, Op1); | std::swap(Op0, Op1); | ||||
Show All 9 Lines | static Instruction *foldICmpOrXX(ICmpInst &I, const SimplifyQuery &Q, | ||||
// icmp (X | Y) u> X --> (X | Y) != X | // icmp (X | Y) u> X --> (X | Y) != X | ||||
else if (Pred == ICmpInst::ICMP_UGT) | else if (Pred == ICmpInst::ICMP_UGT) | ||||
return new ICmpInst(ICmpInst::ICMP_NE, Op0, Op1); | return new ICmpInst(ICmpInst::ICMP_NE, Op0, Op1); | ||||
// icmp (X | noundef Y) eq/ne X | // icmp (X | noundef Y) eq/ne X | ||||
// if (X | noundef Y).hasOneUse() | // if (X | noundef Y).hasOneUse() | ||||
// --> (X & noundef Y) eq/ne noundef Y | // --> (X & noundef Y) eq/ne noundef Y | ||||
if (ICmpInst::isEquality(Pred) && Op0->hasOneUse() && | if (ICmpInst::isEquality(Pred) && Op0->hasOneUse() && | ||||
RKSimon: Maybe move this into the if() to reduce scope
```
if (auto KnownSign = getKnownSign(A, &I, Q.DL… | |||||
isGuaranteedNotToBeUndefOrPoison(A, Q.AC, Q.CxtI, Q.DT, | isGuaranteedNotToBeUndefOrPoison(A, Q.AC, Q.CxtI, Q.DT, | ||||
/*Depth*/ 0)) | /*Depth*/ 0)) | ||||
return new ICmpInst(Pred, IC.Builder.CreateAnd(Op1, A), A); | return new ICmpInst(Pred, IC.Builder.CreateAnd(Op1, A), A); | ||||
if (ICmpInst::isEquality(Pred) || ICmpInst::getSignedPredicate(Pred) != Pred) | |||||
return nullptr; | |||||
auto KnownSign = getKnownSign(A, &I, Q.DL, Q.AC, Q.DT); | |||||
if (KnownSign != std::nullopt) { | |||||
// icmp (X | MinInt) s> X --> false | |||||
// icmp (X | MinInt) s<= X --> true | |||||
// icmp (X | MinInt) s>= X --> X s< 0 | |||||
// icmp (X | MinInt) s< X --> X s>= 0 | |||||
if (*KnownSign /* true is Signed. */ && | |||||
IC.isKnownToBeAPowerOfTwo(A, /*OrZero*/ true, 0, &I)) { | |||||
if (Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_SLE) | |||||
return IC.replaceInstUsesWith( | |||||
I, ConstantInt::get(I.getType(), Pred == ICmpInst::ICMP_SLE)); | |||||
else if (Pred == ICmpInst::ICMP_SGE) | |||||
return new ICmpInst(ICmpInst::ICMP_SLT, Op1, | |||||
Constant::getNullValue(Op0->getType())); | |||||
else | |||||
return new ICmpInst(ICmpInst::ICMP_SGE, Op1, | |||||
Constant::getNullValue(Op0->getType())); | |||||
} | |||||
// icmp (X | Pos_Y) s> X --> (X | Pos_Y) != X | |||||
// icmp (X | Pos_Y) s<= X --> (X | Pos_Y) == X | |||||
else if (!*KnownSign) { | |||||
if (Pred == ICmpInst::ICMP_SGT) | |||||
return new ICmpInst(ICmpInst::ICMP_NE, Op0, Op1); | |||||
else if (Pred == ICmpInst::ICMP_SLE) | |||||
return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1); | |||||
} | |||||
} | |||||
return nullptr; | return nullptr; | ||||
} | } | ||||
static Instruction *foldICmpXorXX(ICmpInst &I, const SimplifyQuery &Q, | static Instruction *foldICmpXorXX(ICmpInst &I, const SimplifyQuery &Q, | ||||
InstCombinerImpl &IC) { | InstCombinerImpl &IC) { | ||||
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1), *A; | Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1), *A; | ||||
// Normalize xor operand as operand 0. | // Normalize xor operand as operand 0. | ||||
▲ Show 20 Lines • Show All 3,230 Lines • Show Last 20 Lines |
Maybe move this into the if() to reduce scope