|
19 | 19 | #include "llvm/Analysis/ValueLattice.h" |
20 | 20 | #include "llvm/Analysis/ValueLatticeUtils.h" |
21 | 21 | #include "llvm/Analysis/ValueTracking.h" |
| 22 | +#include "llvm/IR/ConstantRange.h" |
22 | 23 | #include "llvm/IR/IRBuilder.h" |
23 | 24 | #include "llvm/IR/InstVisitor.h" |
| 25 | +#include "llvm/IR/Instructions.h" |
24 | 26 | #include "llvm/IR/NoFolder.h" |
25 | 27 | #include "llvm/IR/PatternMatch.h" |
26 | 28 | #include "llvm/Support/Casting.h" |
@@ -284,6 +286,52 @@ static Value *simplifyInstruction(SCCPSolver &Solver, |
284 | 286 | return Sub; |
285 | 287 | } |
286 | 288 |
|
| 289 | + // Relax range checks. |
| 290 | + if (auto *ICmp = dyn_cast<ICmpInst>(&Inst)) { |
| 291 | + Value *X; |
| 292 | + auto MatchTwoInstructionExactRangeCheck = |
| 293 | + [&]() -> std::optional<ConstantRange> { |
| 294 | + const APInt *RHSC; |
| 295 | + if (!match(ICmp->getOperand(1), m_APInt(RHSC))) |
| 296 | + return std::nullopt; |
| 297 | + |
| 298 | + Value *LHS = ICmp->getOperand(0); |
| 299 | + ICmpInst::Predicate Pred = ICmp->getPredicate(); |
| 300 | + unsigned BitWidth = RHSC->getBitWidth(); |
| 301 | + if (Pred == ICmpInst::ICMP_ULT) { |
| 302 | + const APInt *Offset; |
| 303 | + if (match(LHS, m_AddLike(m_Value(X), m_APInt(Offset)))) |
| 304 | + return ConstantRange(APInt::getZero(BitWidth), *RHSC).sub(*Offset); |
| 305 | + return std::nullopt; |
| 306 | + } |
| 307 | + // Match icmp eq/ne X & NegPow2, C |
| 308 | + if (ICmp->isEquality()) { |
| 309 | + const APInt *Mask; |
| 310 | + if (match(LHS, m_And(m_Value(X), m_NegatedPower2(Mask))) && |
| 311 | + RHSC->countr_zero() >= Mask->countr_zero()) { |
| 312 | + ConstantRange CR(*RHSC, *RHSC - *Mask); |
| 313 | + return Pred == ICmpInst::ICMP_EQ ? CR : CR.inverse(); |
| 314 | + } |
| 315 | + } |
| 316 | + return std::nullopt; |
| 317 | + }; |
| 318 | + |
| 319 | + if (auto CR = MatchExactTwoInstructionRangeCheck()) { |
| 320 | + ConstantRange LRange = GetRange(X); |
| 321 | + if (auto NewCR = CR->exactUnionWith(LRange.inverse())) { |
| 322 | + ICmpInst::Predicate Pred; |
| 323 | + APInt RHS; |
| 324 | + if (NewCR->getEquivalentICmp(Pred, RHS)) { |
| 325 | + IRBuilder<NoFolder> Builder(&Inst); |
| 326 | + Value *NewICmp = |
| 327 | + Builder.CreateICmp(Pred, X, ConstantInt::get(X->getType(), RHS)); |
| 328 | + InsertedValues.insert(NewICmp); |
| 329 | + return NewICmp; |
| 330 | + } |
| 331 | + } |
| 332 | + } |
| 333 | + } |
| 334 | + |
287 | 335 | return nullptr; |
288 | 336 | } |
289 | 337 |
|
|
0 commit comments