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