1 //===-- ConstraintElimination.cpp - Eliminate conds using constraints. ----===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Eliminate conditions based on constraints collected from dominating 10 // conditions. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Transforms/Scalar/ConstraintElimination.h" 15 #include "llvm/ADT/STLExtras.h" 16 #include "llvm/ADT/ScopeExit.h" 17 #include "llvm/ADT/SmallVector.h" 18 #include "llvm/ADT/Statistic.h" 19 #include "llvm/Analysis/ConstraintSystem.h" 20 #include "llvm/Analysis/GlobalsModRef.h" 21 #include "llvm/Analysis/ValueTracking.h" 22 #include "llvm/IR/Dominators.h" 23 #include "llvm/IR/Function.h" 24 #include "llvm/IR/IRBuilder.h" 25 #include "llvm/IR/Instructions.h" 26 #include "llvm/IR/PatternMatch.h" 27 #include "llvm/InitializePasses.h" 28 #include "llvm/Pass.h" 29 #include "llvm/Support/Debug.h" 30 #include "llvm/Support/DebugCounter.h" 31 #include "llvm/Support/MathExtras.h" 32 #include "llvm/Transforms/Scalar.h" 33 34 #include <string> 35 36 using namespace llvm; 37 using namespace PatternMatch; 38 39 #define DEBUG_TYPE "constraint-elimination" 40 41 STATISTIC(NumCondsRemoved, "Number of instructions removed"); 42 DEBUG_COUNTER(EliminatedCounter, "conds-eliminated", 43 "Controls which conditions are eliminated"); 44 45 static int64_t MaxConstraintValue = std::numeric_limits<int64_t>::max(); 46 static int64_t MinSignedConstraintValue = std::numeric_limits<int64_t>::min(); 47 48 namespace { 49 50 class ConstraintInfo; 51 52 struct StackEntry { 53 unsigned NumIn; 54 unsigned NumOut; 55 Instruction *Condition; 56 bool IsNot; 57 bool IsSigned = false; 58 /// Variables that can be removed from the system once the stack entry gets 59 /// removed. 60 SmallVector<Value *, 2> ValuesToRelease; 61 62 StackEntry(unsigned NumIn, unsigned NumOut, CmpInst *Condition, bool IsNot, 63 bool IsSigned, SmallVector<Value *, 2> ValuesToRelease) 64 : NumIn(NumIn), NumOut(NumOut), Condition(Condition), IsNot(IsNot), 65 IsSigned(IsSigned), ValuesToRelease(ValuesToRelease) {} 66 }; 67 68 /// Struct to express a pre-condition of the form %Op0 Pred %Op1. 69 struct PreconditionTy { 70 CmpInst::Predicate Pred; 71 Value *Op0; 72 Value *Op1; 73 74 PreconditionTy(CmpInst::Predicate Pred, Value *Op0, Value *Op1) 75 : Pred(Pred), Op0(Op0), Op1(Op1) {} 76 }; 77 78 struct ConstraintTy { 79 SmallVector<int64_t, 8> Coefficients; 80 SmallVector<PreconditionTy, 2> Preconditions; 81 82 bool IsSigned = false; 83 bool IsEq = false; 84 85 ConstraintTy() = default; 86 87 ConstraintTy(SmallVector<int64_t, 8> Coefficients, bool IsSigned) 88 : Coefficients(Coefficients), IsSigned(IsSigned) {} 89 90 unsigned size() const { return Coefficients.size(); } 91 92 unsigned empty() const { return Coefficients.empty(); } 93 94 /// Returns true if any constraint has a non-zero coefficient for any of the 95 /// newly added indices. Zero coefficients for new indices are removed. If it 96 /// returns true, no new variable need to be added to the system. 97 bool needsNewIndices(const DenseMap<Value *, unsigned> &NewIndices) { 98 for (unsigned I = 0; I < NewIndices.size(); ++I) { 99 int64_t Last = Coefficients.pop_back_val(); 100 if (Last != 0) 101 return true; 102 } 103 return false; 104 } 105 106 /// Returns true if all preconditions for this list of constraints are 107 /// satisfied given \p CS and the corresponding \p Value2Index mapping. 108 bool isValid(const ConstraintInfo &Info) const; 109 }; 110 111 /// Wrapper encapsulating separate constraint systems and corresponding value 112 /// mappings for both unsigned and signed information. Facts are added to and 113 /// conditions are checked against the corresponding system depending on the 114 /// signed-ness of their predicates. While the information is kept separate 115 /// based on signed-ness, certain conditions can be transferred between the two 116 /// systems. 117 class ConstraintInfo { 118 DenseMap<Value *, unsigned> UnsignedValue2Index; 119 DenseMap<Value *, unsigned> SignedValue2Index; 120 121 ConstraintSystem UnsignedCS; 122 ConstraintSystem SignedCS; 123 124 public: 125 DenseMap<Value *, unsigned> &getValue2Index(bool Signed) { 126 return Signed ? SignedValue2Index : UnsignedValue2Index; 127 } 128 const DenseMap<Value *, unsigned> &getValue2Index(bool Signed) const { 129 return Signed ? SignedValue2Index : UnsignedValue2Index; 130 } 131 132 ConstraintSystem &getCS(bool Signed) { 133 return Signed ? SignedCS : UnsignedCS; 134 } 135 const ConstraintSystem &getCS(bool Signed) const { 136 return Signed ? SignedCS : UnsignedCS; 137 } 138 139 void popLastConstraint(bool Signed) { getCS(Signed).popLastConstraint(); } 140 void popLastNVariables(bool Signed, unsigned N) { 141 getCS(Signed).popLastNVariables(N); 142 } 143 144 void addFact(CmpInst *Condition, bool IsNegated, unsigned NumIn, 145 unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack); 146 }; 147 148 } // namespace 149 150 // Decomposes \p V into a vector of pairs of the form { c, X } where c * X. The 151 // sum of the pairs equals \p V. The first pair is the constant-factor and X 152 // must be nullptr. If the expression cannot be decomposed, returns an empty 153 // vector. 154 static SmallVector<std::pair<int64_t, Value *>, 4> 155 decompose(Value *V, SmallVector<PreconditionTy, 4> &Preconditions, 156 bool IsSigned) { 157 158 auto CanUseSExt = [](ConstantInt *CI) { 159 const APInt &Val = CI->getValue(); 160 return Val.sgt(MinSignedConstraintValue) && Val.slt(MaxConstraintValue); 161 }; 162 // Decompose \p V used with a signed predicate. 163 if (IsSigned) { 164 if (auto *CI = dyn_cast<ConstantInt>(V)) { 165 if (CanUseSExt(CI)) 166 return {{CI->getSExtValue(), nullptr}}; 167 } 168 169 return {{0, nullptr}, {1, V}}; 170 } 171 172 if (auto *CI = dyn_cast<ConstantInt>(V)) { 173 if (CI->uge(MaxConstraintValue)) 174 return {}; 175 return {{CI->getZExtValue(), nullptr}}; 176 } 177 auto *GEP = dyn_cast<GetElementPtrInst>(V); 178 if (GEP && GEP->getNumOperands() == 2 && GEP->isInBounds()) { 179 Value *Op0, *Op1; 180 ConstantInt *CI; 181 182 // If the index is zero-extended, it is guaranteed to be positive. 183 if (match(GEP->getOperand(GEP->getNumOperands() - 1), 184 m_ZExt(m_Value(Op0)))) { 185 if (match(Op0, m_NUWShl(m_Value(Op1), m_ConstantInt(CI))) && 186 CanUseSExt(CI)) 187 return {{0, nullptr}, 188 {1, GEP->getPointerOperand()}, 189 {std::pow(int64_t(2), CI->getSExtValue()), Op1}}; 190 if (match(Op0, m_NSWAdd(m_Value(Op1), m_ConstantInt(CI))) && 191 CanUseSExt(CI)) 192 return {{CI->getSExtValue(), nullptr}, 193 {1, GEP->getPointerOperand()}, 194 {1, Op1}}; 195 return {{0, nullptr}, {1, GEP->getPointerOperand()}, {1, Op0}}; 196 } 197 198 if (match(GEP->getOperand(GEP->getNumOperands() - 1), m_ConstantInt(CI)) && 199 !CI->isNegative() && CanUseSExt(CI)) 200 return {{CI->getSExtValue(), nullptr}, {1, GEP->getPointerOperand()}}; 201 202 SmallVector<std::pair<int64_t, Value *>, 4> Result; 203 if (match(GEP->getOperand(GEP->getNumOperands() - 1), 204 m_NUWShl(m_Value(Op0), m_ConstantInt(CI))) && 205 CanUseSExt(CI)) 206 Result = {{0, nullptr}, 207 {1, GEP->getPointerOperand()}, 208 {std::pow(int64_t(2), CI->getSExtValue()), Op0}}; 209 else if (match(GEP->getOperand(GEP->getNumOperands() - 1), 210 m_NSWAdd(m_Value(Op0), m_ConstantInt(CI))) && 211 CanUseSExt(CI)) 212 Result = {{CI->getSExtValue(), nullptr}, 213 {1, GEP->getPointerOperand()}, 214 {1, Op0}}; 215 else { 216 Op0 = GEP->getOperand(GEP->getNumOperands() - 1); 217 Result = {{0, nullptr}, {1, GEP->getPointerOperand()}, {1, Op0}}; 218 } 219 // If Op0 is signed non-negative, the GEP is increasing monotonically and 220 // can be de-composed. 221 Preconditions.emplace_back(CmpInst::ICMP_SGE, Op0, 222 ConstantInt::get(Op0->getType(), 0)); 223 return Result; 224 } 225 226 Value *Op0; 227 if (match(V, m_ZExt(m_Value(Op0)))) 228 V = Op0; 229 230 Value *Op1; 231 ConstantInt *CI; 232 if (match(V, m_NUWAdd(m_Value(Op0), m_ConstantInt(CI))) && 233 !CI->uge(MaxConstraintValue)) 234 return {{CI->getZExtValue(), nullptr}, {1, Op0}}; 235 if (match(V, m_Add(m_Value(Op0), m_ConstantInt(CI))) && CI->isNegative() && 236 CanUseSExt(CI)) { 237 Preconditions.emplace_back( 238 CmpInst::ICMP_UGE, Op0, 239 ConstantInt::get(Op0->getType(), CI->getSExtValue() * -1)); 240 return {{CI->getSExtValue(), nullptr}, {1, Op0}}; 241 } 242 if (match(V, m_NUWAdd(m_Value(Op0), m_Value(Op1)))) 243 return {{0, nullptr}, {1, Op0}, {1, Op1}}; 244 245 if (match(V, m_NUWSub(m_Value(Op0), m_ConstantInt(CI))) && CanUseSExt(CI)) 246 return {{-1 * CI->getSExtValue(), nullptr}, {1, Op0}}; 247 if (match(V, m_NUWSub(m_Value(Op0), m_Value(Op1)))) 248 return {{0, nullptr}, {1, Op0}, {-1, Op1}}; 249 250 return {{0, nullptr}, {1, V}}; 251 } 252 253 /// Turn a condition \p CmpI into a vector of constraints, using indices from \p 254 /// Value2Index. Additional indices for newly discovered values are added to \p 255 /// NewIndices. 256 static ConstraintTy 257 getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1, 258 const DenseMap<Value *, unsigned> &Value2Index, 259 DenseMap<Value *, unsigned> &NewIndices) { 260 bool IsEq = false; 261 // Try to convert Pred to one of ULE/SLT/SLE/SLT. 262 switch (Pred) { 263 case CmpInst::ICMP_UGT: 264 case CmpInst::ICMP_UGE: 265 case CmpInst::ICMP_SGT: 266 case CmpInst::ICMP_SGE: { 267 Pred = CmpInst::getSwappedPredicate(Pred); 268 std::swap(Op0, Op1); 269 break; 270 } 271 case CmpInst::ICMP_EQ: 272 if (match(Op1, m_Zero())) { 273 Pred = CmpInst::ICMP_ULE; 274 } else { 275 IsEq = true; 276 Pred = CmpInst::ICMP_ULE; 277 } 278 break; 279 case CmpInst::ICMP_NE: 280 if (!match(Op1, m_Zero())) 281 return {}; 282 Pred = CmpInst::getSwappedPredicate(CmpInst::ICMP_UGT); 283 std::swap(Op0, Op1); 284 break; 285 default: 286 break; 287 } 288 289 // Only ULE and ULT predicates are supported at the moment. 290 if (Pred != CmpInst::ICMP_ULE && Pred != CmpInst::ICMP_ULT && 291 Pred != CmpInst::ICMP_SLE && Pred != CmpInst::ICMP_SLT) 292 return {}; 293 294 SmallVector<PreconditionTy, 4> Preconditions; 295 bool IsSigned = CmpInst::isSigned(Pred); 296 auto ADec = decompose(Op0->stripPointerCastsSameRepresentation(), 297 Preconditions, IsSigned); 298 auto BDec = decompose(Op1->stripPointerCastsSameRepresentation(), 299 Preconditions, IsSigned); 300 // Skip if decomposing either of the values failed. 301 if (ADec.empty() || BDec.empty()) 302 return {}; 303 304 int64_t Offset1 = ADec[0].first; 305 int64_t Offset2 = BDec[0].first; 306 Offset1 *= -1; 307 308 // Create iterator ranges that skip the constant-factor. 309 auto VariablesA = llvm::drop_begin(ADec); 310 auto VariablesB = llvm::drop_begin(BDec); 311 312 // First try to look up \p V in Value2Index and NewIndices. Otherwise add a 313 // new entry to NewIndices. 314 auto GetOrAddIndex = [&Value2Index, &NewIndices](Value *V) -> unsigned { 315 auto V2I = Value2Index.find(V); 316 if (V2I != Value2Index.end()) 317 return V2I->second; 318 auto Insert = 319 NewIndices.insert({V, Value2Index.size() + NewIndices.size() + 1}); 320 return Insert.first->second; 321 }; 322 323 // Make sure all variables have entries in Value2Index or NewIndices. 324 for (const auto &KV : 325 concat<std::pair<int64_t, Value *>>(VariablesA, VariablesB)) 326 GetOrAddIndex(KV.second); 327 328 // Build result constraint, by first adding all coefficients from A and then 329 // subtracting all coefficients from B. 330 ConstraintTy Res( 331 SmallVector<int64_t, 8>(Value2Index.size() + NewIndices.size() + 1, 0), 332 IsSigned); 333 Res.IsEq = IsEq; 334 auto &R = Res.Coefficients; 335 for (const auto &KV : VariablesA) 336 R[GetOrAddIndex(KV.second)] += KV.first; 337 338 for (const auto &KV : VariablesB) 339 R[GetOrAddIndex(KV.second)] -= KV.first; 340 341 int64_t OffsetSum; 342 if (AddOverflow(Offset1, Offset2, OffsetSum)) 343 return {}; 344 if (Pred == (IsSigned ? CmpInst::ICMP_SLT : CmpInst::ICMP_ULT)) 345 if (AddOverflow(OffsetSum, int64_t(-1), OffsetSum)) 346 return {}; 347 R[0] = OffsetSum; 348 Res.Preconditions = std::move(Preconditions); 349 return Res; 350 } 351 352 static ConstraintTy getConstraint(CmpInst *Cmp, ConstraintInfo &Info, 353 DenseMap<Value *, unsigned> &NewIndices) { 354 return getConstraint( 355 Cmp->getPredicate(), Cmp->getOperand(0), Cmp->getOperand(1), 356 Info.getValue2Index(CmpInst::isSigned(Cmp->getPredicate())), NewIndices); 357 } 358 359 bool ConstraintTy::isValid(const ConstraintInfo &Info) const { 360 return Coefficients.size() > 0 && 361 all_of(Preconditions, [&Info](const PreconditionTy &C) { 362 DenseMap<Value *, unsigned> NewIndices; 363 auto R = getConstraint( 364 C.Pred, C.Op0, C.Op1, 365 Info.getValue2Index(CmpInst::isSigned(C.Pred)), NewIndices); 366 // TODO: properly check NewIndices. 367 return NewIndices.empty() && R.Preconditions.empty() && !R.IsEq && 368 R.size() >= 1 && 369 Info.getCS(CmpInst::isSigned(C.Pred)) 370 .isConditionImplied(R.Coefficients); 371 }); 372 } 373 374 namespace { 375 /// Represents either a condition that holds on entry to a block or a basic 376 /// block, with their respective Dominator DFS in and out numbers. 377 struct ConstraintOrBlock { 378 unsigned NumIn; 379 unsigned NumOut; 380 bool IsBlock; 381 bool Not; 382 union { 383 BasicBlock *BB; 384 CmpInst *Condition; 385 }; 386 387 ConstraintOrBlock(DomTreeNode *DTN) 388 : NumIn(DTN->getDFSNumIn()), NumOut(DTN->getDFSNumOut()), IsBlock(true), 389 BB(DTN->getBlock()) {} 390 ConstraintOrBlock(DomTreeNode *DTN, CmpInst *Condition, bool Not) 391 : NumIn(DTN->getDFSNumIn()), NumOut(DTN->getDFSNumOut()), IsBlock(false), 392 Not(Not), Condition(Condition) {} 393 }; 394 395 /// Keep state required to build worklist. 396 struct State { 397 DominatorTree &DT; 398 SmallVector<ConstraintOrBlock, 64> WorkList; 399 400 State(DominatorTree &DT) : DT(DT) {} 401 402 /// Process block \p BB and add known facts to work-list. 403 void addInfoFor(BasicBlock &BB); 404 405 /// Returns true if we can add a known condition from BB to its successor 406 /// block Succ. Each predecessor of Succ can either be BB or be dominated 407 /// by Succ (e.g. the case when adding a condition from a pre-header to a 408 /// loop header). 409 bool canAddSuccessor(BasicBlock &BB, BasicBlock *Succ) const { 410 if (BB.getSingleSuccessor()) { 411 assert(BB.getSingleSuccessor() == Succ); 412 return DT.properlyDominates(&BB, Succ); 413 } 414 return any_of(successors(&BB), 415 [Succ](const BasicBlock *S) { return S != Succ; }) && 416 all_of(predecessors(Succ), [&BB, Succ, this](BasicBlock *Pred) { 417 return Pred == &BB || DT.dominates(Succ, Pred); 418 }); 419 } 420 }; 421 422 } // namespace 423 424 #ifndef NDEBUG 425 static void dumpWithNames(ConstraintTy &C, 426 DenseMap<Value *, unsigned> &Value2Index) { 427 SmallVector<std::string> Names(Value2Index.size(), ""); 428 for (auto &KV : Value2Index) { 429 Names[KV.second - 1] = std::string("%") + KV.first->getName().str(); 430 } 431 ConstraintSystem CS; 432 CS.addVariableRowFill(C.Coefficients); 433 CS.dump(Names); 434 } 435 #endif 436 437 void State::addInfoFor(BasicBlock &BB) { 438 WorkList.emplace_back(DT.getNode(&BB)); 439 440 // True as long as long as the current instruction is guaranteed to execute. 441 bool GuaranteedToExecute = true; 442 // Scan BB for assume calls. 443 // TODO: also use this scan to queue conditions to simplify, so we can 444 // interleave facts from assumes and conditions to simplify in a single 445 // basic block. And to skip another traversal of each basic block when 446 // simplifying. 447 for (Instruction &I : BB) { 448 Value *Cond; 449 // For now, just handle assumes with a single compare as condition. 450 if (match(&I, m_Intrinsic<Intrinsic::assume>(m_Value(Cond))) && 451 isa<ICmpInst>(Cond)) { 452 if (GuaranteedToExecute) { 453 // The assume is guaranteed to execute when BB is entered, hence Cond 454 // holds on entry to BB. 455 WorkList.emplace_back(DT.getNode(&BB), cast<ICmpInst>(Cond), false); 456 } else { 457 // Otherwise the condition only holds in the successors. 458 for (BasicBlock *Succ : successors(&BB)) { 459 if (!canAddSuccessor(BB, Succ)) 460 continue; 461 WorkList.emplace_back(DT.getNode(Succ), cast<ICmpInst>(Cond), false); 462 } 463 } 464 } 465 GuaranteedToExecute &= isGuaranteedToTransferExecutionToSuccessor(&I); 466 } 467 468 auto *Br = dyn_cast<BranchInst>(BB.getTerminator()); 469 if (!Br || !Br->isConditional()) 470 return; 471 472 // If the condition is an OR of 2 compares and the false successor only has 473 // the current block as predecessor, queue both negated conditions for the 474 // false successor. 475 Value *Op0, *Op1; 476 if (match(Br->getCondition(), m_LogicalOr(m_Value(Op0), m_Value(Op1))) && 477 isa<ICmpInst>(Op0) && isa<ICmpInst>(Op1)) { 478 BasicBlock *FalseSuccessor = Br->getSuccessor(1); 479 if (canAddSuccessor(BB, FalseSuccessor)) { 480 WorkList.emplace_back(DT.getNode(FalseSuccessor), cast<ICmpInst>(Op0), 481 true); 482 WorkList.emplace_back(DT.getNode(FalseSuccessor), cast<ICmpInst>(Op1), 483 true); 484 } 485 return; 486 } 487 488 // If the condition is an AND of 2 compares and the true successor only has 489 // the current block as predecessor, queue both conditions for the true 490 // successor. 491 if (match(Br->getCondition(), m_LogicalAnd(m_Value(Op0), m_Value(Op1))) && 492 isa<ICmpInst>(Op0) && isa<ICmpInst>(Op1)) { 493 BasicBlock *TrueSuccessor = Br->getSuccessor(0); 494 if (canAddSuccessor(BB, TrueSuccessor)) { 495 WorkList.emplace_back(DT.getNode(TrueSuccessor), cast<ICmpInst>(Op0), 496 false); 497 WorkList.emplace_back(DT.getNode(TrueSuccessor), cast<ICmpInst>(Op1), 498 false); 499 } 500 return; 501 } 502 503 auto *CmpI = dyn_cast<ICmpInst>(Br->getCondition()); 504 if (!CmpI) 505 return; 506 if (canAddSuccessor(BB, Br->getSuccessor(0))) 507 WorkList.emplace_back(DT.getNode(Br->getSuccessor(0)), CmpI, false); 508 if (canAddSuccessor(BB, Br->getSuccessor(1))) 509 WorkList.emplace_back(DT.getNode(Br->getSuccessor(1)), CmpI, true); 510 } 511 512 void ConstraintInfo::addFact(CmpInst *Condition, bool IsNegated, unsigned NumIn, 513 unsigned NumOut, 514 SmallVectorImpl<StackEntry> &DFSInStack) { 515 // If the constraint has a pre-condition, skip the constraint if it does not 516 // hold. 517 DenseMap<Value *, unsigned> NewIndices; 518 auto R = getConstraint(Condition, *this, NewIndices); 519 if (!R.isValid(*this)) 520 return; 521 522 LLVM_DEBUG(dbgs() << "Adding " << *Condition << " " << IsNegated << "\n"); 523 bool Added = false; 524 assert(CmpInst::isSigned(Condition->getPredicate()) == R.IsSigned && 525 "condition and constraint signs must match"); 526 auto &CSToUse = getCS(R.IsSigned); 527 if (R.Coefficients.empty()) 528 return; 529 530 Added |= CSToUse.addVariableRowFill(R.Coefficients); 531 532 // If R has been added to the system, queue it for removal once it goes 533 // out-of-scope. 534 if (Added) { 535 SmallVector<Value *, 2> ValuesToRelease; 536 for (auto &KV : NewIndices) { 537 getValue2Index(R.IsSigned).insert(KV); 538 ValuesToRelease.push_back(KV.first); 539 } 540 541 LLVM_DEBUG({ 542 dbgs() << " constraint: "; 543 dumpWithNames(R, getValue2Index(R.IsSigned)); 544 }); 545 546 DFSInStack.emplace_back(NumIn, NumOut, Condition, IsNegated, R.IsSigned, 547 ValuesToRelease); 548 549 if (R.IsEq) { 550 // Also add the inverted constraint for equality constraints. 551 for (auto &Coeff : R.Coefficients) 552 Coeff *= -1; 553 CSToUse.addVariableRowFill(R.Coefficients); 554 555 DFSInStack.emplace_back(NumIn, NumOut, Condition, IsNegated, R.IsSigned, 556 SmallVector<Value *, 2>()); 557 } 558 } 559 } 560 561 static void 562 tryToSimplifyOverflowMath(IntrinsicInst *II, ConstraintInfo &Info, 563 SmallVectorImpl<Instruction *> &ToRemove) { 564 auto DoesConditionHold = [](CmpInst::Predicate Pred, Value *A, Value *B, 565 ConstraintInfo &Info) { 566 DenseMap<Value *, unsigned> NewIndices; 567 auto R = getConstraint( 568 Pred, A, B, Info.getValue2Index(CmpInst::isSigned(Pred)), NewIndices); 569 if (R.size() < 2 || R.needsNewIndices(NewIndices) || !R.isValid(Info)) 570 return false; 571 572 auto &CSToUse = Info.getCS(CmpInst::isSigned(Pred)); 573 return CSToUse.isConditionImplied(R.Coefficients); 574 }; 575 576 if (II->getIntrinsicID() == Intrinsic::ssub_with_overflow) { 577 // If A s>= B && B s>= 0, ssub.with.overflow(a, b) should not overflow and 578 // can be simplified to a regular sub. 579 Value *A = II->getArgOperand(0); 580 Value *B = II->getArgOperand(1); 581 if (!DoesConditionHold(CmpInst::ICMP_SGE, A, B, Info) || 582 !DoesConditionHold(CmpInst::ICMP_SGE, B, 583 ConstantInt::get(A->getType(), 0), Info)) 584 return; 585 586 IRBuilder<> Builder(II->getParent(), II->getIterator()); 587 Value *Sub = nullptr; 588 for (User *U : make_early_inc_range(II->users())) { 589 if (match(U, m_ExtractValue<0>(m_Value()))) { 590 if (!Sub) 591 Sub = Builder.CreateSub(A, B); 592 U->replaceAllUsesWith(Sub); 593 } else if (match(U, m_ExtractValue<1>(m_Value()))) 594 U->replaceAllUsesWith(Builder.getFalse()); 595 else 596 continue; 597 598 if (U->use_empty()) { 599 auto *I = cast<Instruction>(U); 600 ToRemove.push_back(I); 601 I->setOperand(0, PoisonValue::get(II->getType())); 602 } 603 } 604 605 if (II->use_empty()) 606 II->eraseFromParent(); 607 } 608 } 609 610 static bool eliminateConstraints(Function &F, DominatorTree &DT) { 611 bool Changed = false; 612 DT.updateDFSNumbers(); 613 614 ConstraintInfo Info; 615 State S(DT); 616 617 // First, collect conditions implied by branches and blocks with their 618 // Dominator DFS in and out numbers. 619 for (BasicBlock &BB : F) { 620 if (!DT.getNode(&BB)) 621 continue; 622 S.addInfoFor(BB); 623 } 624 625 // Next, sort worklist by dominance, so that dominating blocks and conditions 626 // come before blocks and conditions dominated by them. If a block and a 627 // condition have the same numbers, the condition comes before the block, as 628 // it holds on entry to the block. 629 sort(S.WorkList, [](const ConstraintOrBlock &A, const ConstraintOrBlock &B) { 630 return std::tie(A.NumIn, A.IsBlock) < std::tie(B.NumIn, B.IsBlock); 631 }); 632 633 SmallVector<Instruction *> ToRemove; 634 635 // Finally, process ordered worklist and eliminate implied conditions. 636 SmallVector<StackEntry, 16> DFSInStack; 637 for (ConstraintOrBlock &CB : S.WorkList) { 638 // First, pop entries from the stack that are out-of-scope for CB. Remove 639 // the corresponding entry from the constraint system. 640 while (!DFSInStack.empty()) { 641 auto &E = DFSInStack.back(); 642 LLVM_DEBUG(dbgs() << "Top of stack : " << E.NumIn << " " << E.NumOut 643 << "\n"); 644 LLVM_DEBUG(dbgs() << "CB: " << CB.NumIn << " " << CB.NumOut << "\n"); 645 assert(E.NumIn <= CB.NumIn); 646 if (CB.NumOut <= E.NumOut) 647 break; 648 LLVM_DEBUG(dbgs() << "Removing " << *E.Condition << " " << E.IsNot 649 << "\n"); 650 Info.popLastConstraint(E.IsSigned); 651 // Remove variables in the system that went out of scope. 652 auto &Mapping = Info.getValue2Index(E.IsSigned); 653 for (Value *V : E.ValuesToRelease) 654 Mapping.erase(V); 655 Info.popLastNVariables(E.IsSigned, E.ValuesToRelease.size()); 656 DFSInStack.pop_back(); 657 } 658 659 LLVM_DEBUG({ 660 dbgs() << "Processing "; 661 if (CB.IsBlock) 662 dbgs() << *CB.BB; 663 else 664 dbgs() << *CB.Condition; 665 dbgs() << "\n"; 666 }); 667 668 // For a block, check if any CmpInsts become known based on the current set 669 // of constraints. 670 if (CB.IsBlock) { 671 for (Instruction &I : make_early_inc_range(*CB.BB)) { 672 if (auto *II = dyn_cast<WithOverflowInst>(&I)) { 673 tryToSimplifyOverflowMath(II, Info, ToRemove); 674 continue; 675 } 676 auto *Cmp = dyn_cast<ICmpInst>(&I); 677 if (!Cmp) 678 continue; 679 680 DenseMap<Value *, unsigned> NewIndices; 681 auto R = getConstraint(Cmp, Info, NewIndices); 682 if (R.IsEq || R.empty() || R.needsNewIndices(NewIndices) || 683 !R.isValid(Info)) 684 continue; 685 686 auto &CSToUse = Info.getCS(R.IsSigned); 687 if (CSToUse.isConditionImplied(R.Coefficients)) { 688 if (!DebugCounter::shouldExecute(EliminatedCounter)) 689 continue; 690 691 LLVM_DEBUG(dbgs() << "Condition " << *Cmp 692 << " implied by dominating constraints\n"); 693 LLVM_DEBUG({ 694 for (auto &E : reverse(DFSInStack)) 695 dbgs() << " C " << *E.Condition << " " << E.IsNot << "\n"; 696 }); 697 Cmp->replaceUsesWithIf( 698 ConstantInt::getTrue(F.getParent()->getContext()), [](Use &U) { 699 // Conditions in an assume trivially simplify to true. Skip uses 700 // in assume calls to not destroy the available information. 701 auto *II = dyn_cast<IntrinsicInst>(U.getUser()); 702 return !II || II->getIntrinsicID() != Intrinsic::assume; 703 }); 704 NumCondsRemoved++; 705 Changed = true; 706 } 707 if (CSToUse.isConditionImplied( 708 ConstraintSystem::negate(R.Coefficients))) { 709 if (!DebugCounter::shouldExecute(EliminatedCounter)) 710 continue; 711 712 LLVM_DEBUG(dbgs() << "Condition !" << *Cmp 713 << " implied by dominating constraints\n"); 714 LLVM_DEBUG({ 715 for (auto &E : reverse(DFSInStack)) 716 dbgs() << " C " << *E.Condition << " " << E.IsNot << "\n"; 717 }); 718 Cmp->replaceAllUsesWith( 719 ConstantInt::getFalse(F.getParent()->getContext())); 720 NumCondsRemoved++; 721 Changed = true; 722 } 723 } 724 continue; 725 } 726 727 // Set up a function to restore the predicate at the end of the scope if it 728 // has been negated. Negate the predicate in-place, if required. 729 auto *CI = dyn_cast<ICmpInst>(CB.Condition); 730 auto PredicateRestorer = make_scope_exit([CI, &CB]() { 731 if (CB.Not && CI) 732 CI->setPredicate(CI->getInversePredicate()); 733 }); 734 if (CB.Not) { 735 if (CI) { 736 CI->setPredicate(CI->getInversePredicate()); 737 } else { 738 LLVM_DEBUG(dbgs() << "Can only negate compares so far.\n"); 739 continue; 740 } 741 } 742 743 // Otherwise, add the condition to the system and stack, if we can transform 744 // it into a constraint. 745 Info.addFact(CB.Condition, CB.Not, CB.NumIn, CB.NumOut, DFSInStack); 746 } 747 748 #ifndef NDEBUG 749 unsigned SignedEntries = 750 count_if(DFSInStack, [](const StackEntry &E) { return E.IsSigned; }); 751 assert(Info.getCS(false).size() == DFSInStack.size() - SignedEntries && 752 "updates to CS and DFSInStack are out of sync"); 753 assert(Info.getCS(true).size() == SignedEntries && 754 "updates to CS and DFSInStack are out of sync"); 755 #endif 756 757 for (Instruction *I : ToRemove) 758 I->eraseFromParent(); 759 return Changed; 760 } 761 762 PreservedAnalyses ConstraintEliminationPass::run(Function &F, 763 FunctionAnalysisManager &AM) { 764 auto &DT = AM.getResult<DominatorTreeAnalysis>(F); 765 if (!eliminateConstraints(F, DT)) 766 return PreservedAnalyses::all(); 767 768 PreservedAnalyses PA; 769 PA.preserve<DominatorTreeAnalysis>(); 770 PA.preserveSet<CFGAnalyses>(); 771 return PA; 772 } 773 774 namespace { 775 776 class ConstraintElimination : public FunctionPass { 777 public: 778 static char ID; 779 780 ConstraintElimination() : FunctionPass(ID) { 781 initializeConstraintEliminationPass(*PassRegistry::getPassRegistry()); 782 } 783 784 bool runOnFunction(Function &F) override { 785 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 786 return eliminateConstraints(F, DT); 787 } 788 789 void getAnalysisUsage(AnalysisUsage &AU) const override { 790 AU.setPreservesCFG(); 791 AU.addRequired<DominatorTreeWrapperPass>(); 792 AU.addPreserved<GlobalsAAWrapperPass>(); 793 AU.addPreserved<DominatorTreeWrapperPass>(); 794 } 795 }; 796 797 } // end anonymous namespace 798 799 char ConstraintElimination::ID = 0; 800 801 INITIALIZE_PASS_BEGIN(ConstraintElimination, "constraint-elimination", 802 "Constraint Elimination", false, false) 803 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 804 INITIALIZE_PASS_DEPENDENCY(LazyValueInfoWrapperPass) 805 INITIALIZE_PASS_END(ConstraintElimination, "constraint-elimination", 806 "Constraint Elimination", false, false) 807 808 FunctionPass *llvm::createConstraintEliminationPass() { 809 return new ConstraintElimination(); 810 } 811