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/DataLayout.h" 23 #include "llvm/IR/Dominators.h" 24 #include "llvm/IR/Function.h" 25 #include "llvm/IR/IRBuilder.h" 26 #include "llvm/IR/Instructions.h" 27 #include "llvm/IR/PatternMatch.h" 28 #include "llvm/InitializePasses.h" 29 #include "llvm/Pass.h" 30 #include "llvm/Support/Debug.h" 31 #include "llvm/Support/DebugCounter.h" 32 #include "llvm/Support/MathExtras.h" 33 #include "llvm/Transforms/Scalar.h" 34 35 #include <cmath> 36 #include <string> 37 38 using namespace llvm; 39 using namespace PatternMatch; 40 41 #define DEBUG_TYPE "constraint-elimination" 42 43 STATISTIC(NumCondsRemoved, "Number of instructions removed"); 44 DEBUG_COUNTER(EliminatedCounter, "conds-eliminated", 45 "Controls which conditions are eliminated"); 46 47 static int64_t MaxConstraintValue = std::numeric_limits<int64_t>::max(); 48 static int64_t MinSignedConstraintValue = std::numeric_limits<int64_t>::min(); 49 50 namespace { 51 52 class ConstraintInfo; 53 54 struct StackEntry { 55 unsigned NumIn; 56 unsigned NumOut; 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, bool IsSigned, 63 SmallVector<Value *, 2> ValuesToRelease) 64 : NumIn(NumIn), NumOut(NumOut), IsSigned(IsSigned), 65 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 SmallVector<SmallVector<int64_t, 8>> ExtraInfo; 83 84 bool IsSigned = false; 85 bool IsEq = false; 86 87 ConstraintTy() = default; 88 89 ConstraintTy(SmallVector<int64_t, 8> Coefficients, bool IsSigned) 90 : Coefficients(Coefficients), IsSigned(IsSigned) {} 91 92 unsigned size() const { return Coefficients.size(); } 93 94 unsigned empty() const { return Coefficients.empty(); } 95 96 /// Returns true if all preconditions for this list of constraints are 97 /// satisfied given \p CS and the corresponding \p Value2Index mapping. 98 bool isValid(const ConstraintInfo &Info) const; 99 }; 100 101 /// Wrapper encapsulating separate constraint systems and corresponding value 102 /// mappings for both unsigned and signed information. Facts are added to and 103 /// conditions are checked against the corresponding system depending on the 104 /// signed-ness of their predicates. While the information is kept separate 105 /// based on signed-ness, certain conditions can be transferred between the two 106 /// systems. 107 class ConstraintInfo { 108 DenseMap<Value *, unsigned> UnsignedValue2Index; 109 DenseMap<Value *, unsigned> SignedValue2Index; 110 111 ConstraintSystem UnsignedCS; 112 ConstraintSystem SignedCS; 113 114 const DataLayout &DL; 115 116 public: 117 ConstraintInfo(const DataLayout &DL) : DL(DL) {} 118 119 DenseMap<Value *, unsigned> &getValue2Index(bool Signed) { 120 return Signed ? SignedValue2Index : UnsignedValue2Index; 121 } 122 const DenseMap<Value *, unsigned> &getValue2Index(bool Signed) const { 123 return Signed ? SignedValue2Index : UnsignedValue2Index; 124 } 125 126 ConstraintSystem &getCS(bool Signed) { 127 return Signed ? SignedCS : UnsignedCS; 128 } 129 const ConstraintSystem &getCS(bool Signed) const { 130 return Signed ? SignedCS : UnsignedCS; 131 } 132 133 void popLastConstraint(bool Signed) { getCS(Signed).popLastConstraint(); } 134 void popLastNVariables(bool Signed, unsigned N) { 135 getCS(Signed).popLastNVariables(N); 136 } 137 138 bool doesHold(CmpInst::Predicate Pred, Value *A, Value *B) const; 139 140 void addFact(CmpInst::Predicate Pred, Value *A, Value *B, unsigned NumIn, 141 unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack); 142 143 /// Turn a comparison of the form \p Op0 \p Pred \p Op1 into a vector of 144 /// constraints, using indices from the corresponding constraint system. 145 /// New variables that need to be added to the system are collected in 146 /// \p NewVariables. 147 ConstraintTy getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1, 148 SmallVectorImpl<Value *> &NewVariables) const; 149 150 /// Turn a condition \p CmpI into a vector of constraints, using indices from 151 /// the corresponding constraint system. New variables that need to be added 152 /// to the system are collected in \p NewVariables. 153 ConstraintTy getConstraint(CmpInst *Cmp, 154 SmallVectorImpl<Value *> &NewVariables) { 155 return getConstraint(Cmp->getPredicate(), Cmp->getOperand(0), 156 Cmp->getOperand(1), NewVariables); 157 } 158 159 /// Try to add information from \p A \p Pred \p B to the unsigned/signed 160 /// system if \p Pred is signed/unsigned. 161 void transferToOtherSystem(CmpInst::Predicate Pred, Value *A, Value *B, 162 unsigned NumIn, unsigned NumOut, 163 SmallVectorImpl<StackEntry> &DFSInStack); 164 }; 165 166 /// Represents a (Coefficient * Variable) entry after IR decomposition. 167 struct DecompEntry { 168 int64_t Coefficient; 169 Value *Variable; 170 /// True if the variable is known positive in the current constraint. 171 bool IsKnownPositive; 172 173 DecompEntry(int64_t Coefficient, Value *Variable, 174 bool IsKnownPositive = false) 175 : Coefficient(Coefficient), Variable(Variable), 176 IsKnownPositive(IsKnownPositive) {} 177 }; 178 179 } // namespace 180 181 // Decomposes \p V into a vector of entries of the form { Coefficient, Variable 182 // } where Coefficient * Variable. The sum of the pairs equals \p V. The first 183 // pair is the constant-factor and X must be nullptr. If the expression cannot 184 // be decomposed, returns an empty vector. 185 static SmallVector<DecompEntry, 4> 186 decompose(Value *V, SmallVector<PreconditionTy, 4> &Preconditions, 187 bool IsSigned) { 188 189 auto CanUseSExt = [](ConstantInt *CI) { 190 const APInt &Val = CI->getValue(); 191 return Val.sgt(MinSignedConstraintValue) && Val.slt(MaxConstraintValue); 192 }; 193 // Decompose \p V used with a signed predicate. 194 if (IsSigned) { 195 if (auto *CI = dyn_cast<ConstantInt>(V)) { 196 if (CanUseSExt(CI)) 197 return {{CI->getSExtValue(), nullptr}}; 198 } 199 200 return {{0, nullptr}, {1, V}}; 201 } 202 203 if (auto *CI = dyn_cast<ConstantInt>(V)) { 204 if (CI->uge(MaxConstraintValue)) 205 return {}; 206 return {{int64_t(CI->getZExtValue()), nullptr}}; 207 } 208 auto *GEP = dyn_cast<GetElementPtrInst>(V); 209 if (GEP && GEP->getNumOperands() == 2 && GEP->isInBounds()) { 210 Value *Op0, *Op1; 211 ConstantInt *CI; 212 213 // If the index is zero-extended, it is guaranteed to be positive. 214 if (match(GEP->getOperand(GEP->getNumOperands() - 1), 215 m_ZExt(m_Value(Op0)))) { 216 if (match(Op0, m_NUWShl(m_Value(Op1), m_ConstantInt(CI))) && 217 CanUseSExt(CI)) 218 return {{0, nullptr}, 219 {1, GEP->getPointerOperand()}, 220 {int64_t(std::pow(int64_t(2), CI->getSExtValue())), Op1}}; 221 if (match(Op0, m_NSWAdd(m_Value(Op1), m_ConstantInt(CI))) && 222 CanUseSExt(CI)) 223 return {{CI->getSExtValue(), nullptr}, 224 {1, GEP->getPointerOperand()}, 225 {1, Op1}}; 226 return {{0, nullptr}, {1, GEP->getPointerOperand()}, {1, Op0, true}}; 227 } 228 229 if (match(GEP->getOperand(GEP->getNumOperands() - 1), m_ConstantInt(CI)) && 230 !CI->isNegative() && CanUseSExt(CI)) 231 return {{CI->getSExtValue(), nullptr}, {1, GEP->getPointerOperand()}}; 232 233 SmallVector<DecompEntry, 4> Result; 234 if (match(GEP->getOperand(GEP->getNumOperands() - 1), 235 m_NUWShl(m_Value(Op0), m_ConstantInt(CI))) && 236 CanUseSExt(CI)) 237 Result = {{0, nullptr}, 238 {1, GEP->getPointerOperand()}, 239 {int(std::pow(int64_t(2), CI->getSExtValue())), Op0}}; 240 else if (match(GEP->getOperand(GEP->getNumOperands() - 1), 241 m_NSWAdd(m_Value(Op0), m_ConstantInt(CI))) && 242 CanUseSExt(CI)) 243 Result = {{CI->getSExtValue(), nullptr}, 244 {1, GEP->getPointerOperand()}, 245 {1, Op0}}; 246 else { 247 Op0 = GEP->getOperand(GEP->getNumOperands() - 1); 248 Result = {{0, nullptr}, {1, GEP->getPointerOperand()}, {1, Op0}}; 249 } 250 // If Op0 is signed non-negative, the GEP is increasing monotonically and 251 // can be de-composed. 252 Preconditions.emplace_back(CmpInst::ICMP_SGE, Op0, 253 ConstantInt::get(Op0->getType(), 0)); 254 return Result; 255 } 256 257 Value *Op0; 258 bool IsKnownPositive = false; 259 if (match(V, m_ZExt(m_Value(Op0)))) { 260 IsKnownPositive = true; 261 V = Op0; 262 } 263 264 auto MergeResults = [&Preconditions, IsSigned]( 265 Value *A, Value *B, 266 bool IsSignedB) -> SmallVector<DecompEntry, 4> { 267 auto ResA = decompose(A, Preconditions, IsSigned); 268 auto ResB = decompose(B, Preconditions, IsSignedB); 269 if (ResA.empty() || ResB.empty()) 270 return {}; 271 ResA[0].Coefficient += ResB[0].Coefficient; 272 append_range(ResA, drop_begin(ResB)); 273 return ResA; 274 }; 275 Value *Op1; 276 ConstantInt *CI; 277 if (match(V, m_NUWAdd(m_Value(Op0), m_Value(Op1)))) { 278 return MergeResults(Op0, Op1, IsSigned); 279 } 280 if (match(V, m_Add(m_Value(Op0), m_ConstantInt(CI))) && CI->isNegative() && 281 CanUseSExt(CI)) { 282 Preconditions.emplace_back( 283 CmpInst::ICMP_UGE, Op0, 284 ConstantInt::get(Op0->getType(), CI->getSExtValue() * -1)); 285 return MergeResults(Op0, CI, true); 286 } 287 288 if (match(V, m_NUWSub(m_Value(Op0), m_ConstantInt(CI))) && CanUseSExt(CI)) 289 return {{-1 * CI->getSExtValue(), nullptr}, {1, Op0}}; 290 if (match(V, m_NUWSub(m_Value(Op0), m_Value(Op1)))) 291 return {{0, nullptr}, {1, Op0}, {-1, Op1}}; 292 293 return {{0, nullptr}, {1, V, IsKnownPositive}}; 294 } 295 296 ConstraintTy 297 ConstraintInfo::getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1, 298 SmallVectorImpl<Value *> &NewVariables) const { 299 assert(NewVariables.empty() && "NewVariables must be empty when passed in"); 300 bool IsEq = false; 301 // Try to convert Pred to one of ULE/SLT/SLE/SLT. 302 switch (Pred) { 303 case CmpInst::ICMP_UGT: 304 case CmpInst::ICMP_UGE: 305 case CmpInst::ICMP_SGT: 306 case CmpInst::ICMP_SGE: { 307 Pred = CmpInst::getSwappedPredicate(Pred); 308 std::swap(Op0, Op1); 309 break; 310 } 311 case CmpInst::ICMP_EQ: 312 if (match(Op1, m_Zero())) { 313 Pred = CmpInst::ICMP_ULE; 314 } else { 315 IsEq = true; 316 Pred = CmpInst::ICMP_ULE; 317 } 318 break; 319 case CmpInst::ICMP_NE: 320 if (!match(Op1, m_Zero())) 321 return {}; 322 Pred = CmpInst::getSwappedPredicate(CmpInst::ICMP_UGT); 323 std::swap(Op0, Op1); 324 break; 325 default: 326 break; 327 } 328 329 // Only ULE and ULT predicates are supported at the moment. 330 if (Pred != CmpInst::ICMP_ULE && Pred != CmpInst::ICMP_ULT && 331 Pred != CmpInst::ICMP_SLE && Pred != CmpInst::ICMP_SLT) 332 return {}; 333 334 // If both operands are known to be non-negative, change signed predicates to 335 // unsigned ones. This increases the reasoning effectiveness in combination 336 // with the signed <-> unsigned transfer logic. 337 if (CmpInst::isSigned(Pred) && 338 isKnownNonNegative(Op0, DL, /*Depth=*/MaxAnalysisRecursionDepth - 1) && 339 isKnownNonNegative(Op1, DL, /*Depth=*/MaxAnalysisRecursionDepth - 1)) 340 Pred = CmpInst::getUnsignedPredicate(Pred); 341 342 SmallVector<PreconditionTy, 4> Preconditions; 343 bool IsSigned = CmpInst::isSigned(Pred); 344 auto &Value2Index = getValue2Index(IsSigned); 345 auto ADec = decompose(Op0->stripPointerCastsSameRepresentation(), 346 Preconditions, IsSigned); 347 auto BDec = decompose(Op1->stripPointerCastsSameRepresentation(), 348 Preconditions, IsSigned); 349 // Skip if decomposing either of the values failed. 350 if (ADec.empty() || BDec.empty()) 351 return {}; 352 353 int64_t Offset1 = ADec[0].Coefficient; 354 int64_t Offset2 = BDec[0].Coefficient; 355 Offset1 *= -1; 356 357 // Create iterator ranges that skip the constant-factor. 358 auto VariablesA = llvm::drop_begin(ADec); 359 auto VariablesB = llvm::drop_begin(BDec); 360 361 // First try to look up \p V in Value2Index and NewVariables. Otherwise add a 362 // new entry to NewVariables. 363 DenseMap<Value *, unsigned> NewIndexMap; 364 auto GetOrAddIndex = [&Value2Index, &NewVariables, 365 &NewIndexMap](Value *V) -> unsigned { 366 auto V2I = Value2Index.find(V); 367 if (V2I != Value2Index.end()) 368 return V2I->second; 369 auto Insert = 370 NewIndexMap.insert({V, Value2Index.size() + NewVariables.size() + 1}); 371 if (Insert.second) 372 NewVariables.push_back(V); 373 return Insert.first->second; 374 }; 375 376 // Make sure all variables have entries in Value2Index or NewVariables. 377 for (const auto &KV : concat<DecompEntry>(VariablesA, VariablesB)) 378 GetOrAddIndex(KV.Variable); 379 380 // Build result constraint, by first adding all coefficients from A and then 381 // subtracting all coefficients from B. 382 ConstraintTy Res( 383 SmallVector<int64_t, 8>(Value2Index.size() + NewVariables.size() + 1, 0), 384 IsSigned); 385 // Collect variables that are known to be positive in all uses in the 386 // constraint. 387 DenseMap<Value *, bool> KnownPositiveVariables; 388 Res.IsEq = IsEq; 389 auto &R = Res.Coefficients; 390 for (const auto &KV : VariablesA) { 391 R[GetOrAddIndex(KV.Variable)] += KV.Coefficient; 392 auto I = KnownPositiveVariables.insert({KV.Variable, KV.IsKnownPositive}); 393 I.first->second &= KV.IsKnownPositive; 394 } 395 396 for (const auto &KV : VariablesB) { 397 R[GetOrAddIndex(KV.Variable)] -= KV.Coefficient; 398 auto I = KnownPositiveVariables.insert({KV.Variable, KV.IsKnownPositive}); 399 I.first->second &= KV.IsKnownPositive; 400 } 401 402 int64_t OffsetSum; 403 if (AddOverflow(Offset1, Offset2, OffsetSum)) 404 return {}; 405 if (Pred == (IsSigned ? CmpInst::ICMP_SLT : CmpInst::ICMP_ULT)) 406 if (AddOverflow(OffsetSum, int64_t(-1), OffsetSum)) 407 return {}; 408 R[0] = OffsetSum; 409 Res.Preconditions = std::move(Preconditions); 410 411 // Remove any (Coefficient, Variable) entry where the Coefficient is 0 for new 412 // variables. 413 while (!NewVariables.empty()) { 414 int64_t Last = R.back(); 415 if (Last != 0) 416 break; 417 R.pop_back(); 418 Value *RemovedV = NewVariables.pop_back_val(); 419 NewIndexMap.erase(RemovedV); 420 } 421 422 // Add extra constraints for variables that are known positive. 423 for (auto &KV : KnownPositiveVariables) { 424 if (!KV.second || (Value2Index.find(KV.first) == Value2Index.end() && 425 NewIndexMap.find(KV.first) == NewIndexMap.end())) 426 continue; 427 SmallVector<int64_t, 8> C(Value2Index.size() + NewVariables.size() + 1, 0); 428 C[GetOrAddIndex(KV.first)] = -1; 429 Res.ExtraInfo.push_back(C); 430 } 431 return Res; 432 } 433 434 bool ConstraintTy::isValid(const ConstraintInfo &Info) const { 435 return Coefficients.size() > 0 && 436 all_of(Preconditions, [&Info](const PreconditionTy &C) { 437 return Info.doesHold(C.Pred, C.Op0, C.Op1); 438 }); 439 } 440 441 bool ConstraintInfo::doesHold(CmpInst::Predicate Pred, Value *A, 442 Value *B) const { 443 SmallVector<Value *> NewVariables; 444 auto R = getConstraint(Pred, A, B, NewVariables); 445 446 if (!NewVariables.empty()) 447 return false; 448 449 return NewVariables.empty() && R.Preconditions.empty() && !R.IsEq && 450 !R.empty() && getCS(R.IsSigned).isConditionImplied(R.Coefficients); 451 } 452 453 void ConstraintInfo::transferToOtherSystem( 454 CmpInst::Predicate Pred, Value *A, Value *B, unsigned NumIn, 455 unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack) { 456 // Check if we can combine facts from the signed and unsigned systems to 457 // derive additional facts. 458 if (!A->getType()->isIntegerTy()) 459 return; 460 // FIXME: This currently depends on the order we add facts. Ideally we 461 // would first add all known facts and only then try to add additional 462 // facts. 463 switch (Pred) { 464 default: 465 break; 466 case CmpInst::ICMP_ULT: 467 // If B is a signed positive constant, A >=s 0 and A <s B. 468 if (doesHold(CmpInst::ICMP_SGE, B, ConstantInt::get(B->getType(), 0))) { 469 addFact(CmpInst::ICMP_SGE, A, ConstantInt::get(B->getType(), 0), NumIn, 470 NumOut, DFSInStack); 471 addFact(CmpInst::ICMP_SLT, A, B, NumIn, NumOut, DFSInStack); 472 } 473 break; 474 case CmpInst::ICMP_SLT: 475 if (doesHold(CmpInst::ICMP_SGE, A, ConstantInt::get(B->getType(), 0))) 476 addFact(CmpInst::ICMP_ULT, A, B, NumIn, NumOut, DFSInStack); 477 break; 478 case CmpInst::ICMP_SGT: 479 if (doesHold(CmpInst::ICMP_SGE, B, ConstantInt::get(B->getType(), -1))) 480 addFact(CmpInst::ICMP_UGE, A, ConstantInt::get(B->getType(), 0), NumIn, 481 NumOut, DFSInStack); 482 break; 483 case CmpInst::ICMP_SGE: 484 if (doesHold(CmpInst::ICMP_SGE, B, ConstantInt::get(B->getType(), 0))) { 485 addFact(CmpInst::ICMP_UGE, A, B, NumIn, NumOut, DFSInStack); 486 } 487 break; 488 } 489 } 490 491 namespace { 492 /// Represents either a condition that holds on entry to a block or a basic 493 /// block, with their respective Dominator DFS in and out numbers. 494 struct ConstraintOrBlock { 495 unsigned NumIn; 496 unsigned NumOut; 497 bool IsBlock; 498 bool Not; 499 union { 500 BasicBlock *BB; 501 CmpInst *Condition; 502 }; 503 504 ConstraintOrBlock(DomTreeNode *DTN) 505 : NumIn(DTN->getDFSNumIn()), NumOut(DTN->getDFSNumOut()), IsBlock(true), 506 BB(DTN->getBlock()) {} 507 ConstraintOrBlock(DomTreeNode *DTN, CmpInst *Condition, bool Not) 508 : NumIn(DTN->getDFSNumIn()), NumOut(DTN->getDFSNumOut()), IsBlock(false), 509 Not(Not), Condition(Condition) {} 510 }; 511 512 /// Keep state required to build worklist. 513 struct State { 514 DominatorTree &DT; 515 SmallVector<ConstraintOrBlock, 64> WorkList; 516 517 State(DominatorTree &DT) : DT(DT) {} 518 519 /// Process block \p BB and add known facts to work-list. 520 void addInfoFor(BasicBlock &BB); 521 522 /// Returns true if we can add a known condition from BB to its successor 523 /// block Succ. Each predecessor of Succ can either be BB or be dominated 524 /// by Succ (e.g. the case when adding a condition from a pre-header to a 525 /// loop header). 526 bool canAddSuccessor(BasicBlock &BB, BasicBlock *Succ) const { 527 if (BB.getSingleSuccessor()) { 528 assert(BB.getSingleSuccessor() == Succ); 529 return DT.properlyDominates(&BB, Succ); 530 } 531 return any_of(successors(&BB), 532 [Succ](const BasicBlock *S) { return S != Succ; }) && 533 all_of(predecessors(Succ), [&BB, Succ, this](BasicBlock *Pred) { 534 return Pred == &BB || DT.dominates(Succ, Pred); 535 }); 536 } 537 }; 538 539 } // namespace 540 541 #ifndef NDEBUG 542 static void dumpWithNames(const ConstraintSystem &CS, 543 DenseMap<Value *, unsigned> &Value2Index) { 544 SmallVector<std::string> Names(Value2Index.size(), ""); 545 for (auto &KV : Value2Index) { 546 Names[KV.second - 1] = std::string("%") + KV.first->getName().str(); 547 } 548 CS.dump(Names); 549 } 550 551 static void dumpWithNames(ArrayRef<int64_t> C, 552 DenseMap<Value *, unsigned> &Value2Index) { 553 ConstraintSystem CS; 554 CS.addVariableRowFill(C); 555 dumpWithNames(CS, Value2Index); 556 } 557 #endif 558 559 void State::addInfoFor(BasicBlock &BB) { 560 WorkList.emplace_back(DT.getNode(&BB)); 561 562 // True as long as long as the current instruction is guaranteed to execute. 563 bool GuaranteedToExecute = true; 564 // Scan BB for assume calls. 565 // TODO: also use this scan to queue conditions to simplify, so we can 566 // interleave facts from assumes and conditions to simplify in a single 567 // basic block. And to skip another traversal of each basic block when 568 // simplifying. 569 for (Instruction &I : BB) { 570 Value *Cond; 571 // For now, just handle assumes with a single compare as condition. 572 if (match(&I, m_Intrinsic<Intrinsic::assume>(m_Value(Cond))) && 573 isa<ICmpInst>(Cond)) { 574 if (GuaranteedToExecute) { 575 // The assume is guaranteed to execute when BB is entered, hence Cond 576 // holds on entry to BB. 577 WorkList.emplace_back(DT.getNode(&BB), cast<ICmpInst>(Cond), false); 578 } else { 579 // Otherwise the condition only holds in the successors. 580 for (BasicBlock *Succ : successors(&BB)) { 581 if (!canAddSuccessor(BB, Succ)) 582 continue; 583 WorkList.emplace_back(DT.getNode(Succ), cast<ICmpInst>(Cond), false); 584 } 585 } 586 } 587 GuaranteedToExecute &= isGuaranteedToTransferExecutionToSuccessor(&I); 588 } 589 590 auto *Br = dyn_cast<BranchInst>(BB.getTerminator()); 591 if (!Br || !Br->isConditional()) 592 return; 593 594 Value *Cond = Br->getCondition(); 595 596 // If the condition is a chain of ORs/AND and the successor only has the 597 // current block as predecessor, queue conditions for the successor. 598 Value *Op0, *Op1; 599 if (match(Cond, m_LogicalOr(m_Value(Op0), m_Value(Op1))) || 600 match(Cond, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) { 601 bool IsOr = match(Cond, m_LogicalOr()); 602 bool IsAnd = match(Cond, m_LogicalAnd()); 603 // If there's a select that matches both AND and OR, we need to commit to 604 // one of the options. Arbitrarily pick OR. 605 if (IsOr && IsAnd) 606 IsAnd = false; 607 608 BasicBlock *Successor = Br->getSuccessor(IsOr ? 1 : 0); 609 if (canAddSuccessor(BB, Successor)) { 610 SmallVector<Value *> CondWorkList; 611 SmallPtrSet<Value *, 8> SeenCond; 612 auto QueueValue = [&CondWorkList, &SeenCond](Value *V) { 613 if (SeenCond.insert(V).second) 614 CondWorkList.push_back(V); 615 }; 616 QueueValue(Op1); 617 QueueValue(Op0); 618 while (!CondWorkList.empty()) { 619 Value *Cur = CondWorkList.pop_back_val(); 620 if (auto *Cmp = dyn_cast<ICmpInst>(Cur)) { 621 WorkList.emplace_back(DT.getNode(Successor), Cmp, IsOr); 622 continue; 623 } 624 if (IsOr && match(Cur, m_LogicalOr(m_Value(Op0), m_Value(Op1)))) { 625 QueueValue(Op1); 626 QueueValue(Op0); 627 continue; 628 } 629 if (IsAnd && match(Cur, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) { 630 QueueValue(Op1); 631 QueueValue(Op0); 632 continue; 633 } 634 } 635 } 636 return; 637 } 638 639 auto *CmpI = dyn_cast<ICmpInst>(Br->getCondition()); 640 if (!CmpI) 641 return; 642 if (canAddSuccessor(BB, Br->getSuccessor(0))) 643 WorkList.emplace_back(DT.getNode(Br->getSuccessor(0)), CmpI, false); 644 if (canAddSuccessor(BB, Br->getSuccessor(1))) 645 WorkList.emplace_back(DT.getNode(Br->getSuccessor(1)), CmpI, true); 646 } 647 648 void ConstraintInfo::addFact(CmpInst::Predicate Pred, Value *A, Value *B, 649 unsigned NumIn, unsigned NumOut, 650 SmallVectorImpl<StackEntry> &DFSInStack) { 651 // If the constraint has a pre-condition, skip the constraint if it does not 652 // hold. 653 SmallVector<Value *> NewVariables; 654 auto R = getConstraint(Pred, A, B, NewVariables); 655 if (!R.isValid(*this)) 656 return; 657 658 LLVM_DEBUG(dbgs() << "Adding '" << CmpInst::getPredicateName(Pred) << " "; 659 A->printAsOperand(dbgs(), false); dbgs() << ", "; 660 B->printAsOperand(dbgs(), false); dbgs() << "'\n"); 661 bool Added = false; 662 auto &CSToUse = getCS(R.IsSigned); 663 if (R.Coefficients.empty()) 664 return; 665 666 Added |= CSToUse.addVariableRowFill(R.Coefficients); 667 668 // If R has been added to the system, add the new variables and queue it for 669 // removal once it goes out-of-scope. 670 if (Added) { 671 SmallVector<Value *, 2> ValuesToRelease; 672 auto &Value2Index = getValue2Index(R.IsSigned); 673 for (Value *V : NewVariables) { 674 Value2Index.insert({V, Value2Index.size() + 1}); 675 ValuesToRelease.push_back(V); 676 } 677 678 LLVM_DEBUG({ 679 dbgs() << " constraint: "; 680 dumpWithNames(R.Coefficients, getValue2Index(R.IsSigned)); 681 dbgs() << "\n"; 682 }); 683 684 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned, ValuesToRelease); 685 686 if (R.IsEq) { 687 // Also add the inverted constraint for equality constraints. 688 for (auto &Coeff : R.Coefficients) 689 Coeff *= -1; 690 CSToUse.addVariableRowFill(R.Coefficients); 691 692 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned, 693 SmallVector<Value *, 2>()); 694 } 695 } 696 } 697 698 static bool 699 tryToSimplifyOverflowMath(IntrinsicInst *II, ConstraintInfo &Info, 700 SmallVectorImpl<Instruction *> &ToRemove) { 701 auto DoesConditionHold = [](CmpInst::Predicate Pred, Value *A, Value *B, 702 ConstraintInfo &Info) { 703 SmallVector<Value *> NewVariables; 704 auto R = Info.getConstraint(Pred, A, B, NewVariables); 705 if (R.size() < 2 || !NewVariables.empty() || !R.isValid(Info)) 706 return false; 707 708 auto &CSToUse = Info.getCS(R.IsSigned); 709 return CSToUse.isConditionImplied(R.Coefficients); 710 }; 711 712 bool Changed = false; 713 if (II->getIntrinsicID() == Intrinsic::ssub_with_overflow) { 714 // If A s>= B && B s>= 0, ssub.with.overflow(a, b) should not overflow and 715 // can be simplified to a regular sub. 716 Value *A = II->getArgOperand(0); 717 Value *B = II->getArgOperand(1); 718 if (!DoesConditionHold(CmpInst::ICMP_SGE, A, B, Info) || 719 !DoesConditionHold(CmpInst::ICMP_SGE, B, 720 ConstantInt::get(A->getType(), 0), Info)) 721 return false; 722 723 IRBuilder<> Builder(II->getParent(), II->getIterator()); 724 Value *Sub = nullptr; 725 for (User *U : make_early_inc_range(II->users())) { 726 if (match(U, m_ExtractValue<0>(m_Value()))) { 727 if (!Sub) 728 Sub = Builder.CreateSub(A, B); 729 U->replaceAllUsesWith(Sub); 730 Changed = true; 731 } else if (match(U, m_ExtractValue<1>(m_Value()))) { 732 U->replaceAllUsesWith(Builder.getFalse()); 733 Changed = true; 734 } else 735 continue; 736 737 if (U->use_empty()) { 738 auto *I = cast<Instruction>(U); 739 ToRemove.push_back(I); 740 I->setOperand(0, PoisonValue::get(II->getType())); 741 Changed = true; 742 } 743 } 744 745 if (II->use_empty()) { 746 II->eraseFromParent(); 747 Changed = true; 748 } 749 } 750 return Changed; 751 } 752 753 static bool eliminateConstraints(Function &F, DominatorTree &DT) { 754 bool Changed = false; 755 DT.updateDFSNumbers(); 756 757 ConstraintInfo Info(F.getParent()->getDataLayout()); 758 State S(DT); 759 760 // First, collect conditions implied by branches and blocks with their 761 // Dominator DFS in and out numbers. 762 for (BasicBlock &BB : F) { 763 if (!DT.getNode(&BB)) 764 continue; 765 S.addInfoFor(BB); 766 } 767 768 // Next, sort worklist by dominance, so that dominating blocks and conditions 769 // come before blocks and conditions dominated by them. If a block and a 770 // condition have the same numbers, the condition comes before the block, as 771 // it holds on entry to the block. Also make sure conditions with constant 772 // operands come before conditions without constant operands. This increases 773 // the effectiveness of the current signed <-> unsigned fact transfer logic. 774 stable_sort( 775 S.WorkList, [](const ConstraintOrBlock &A, const ConstraintOrBlock &B) { 776 auto HasNoConstOp = [](const ConstraintOrBlock &B) { 777 return !B.IsBlock && !isa<ConstantInt>(B.Condition->getOperand(0)) && 778 !isa<ConstantInt>(B.Condition->getOperand(1)); 779 }; 780 bool NoConstOpA = HasNoConstOp(A); 781 bool NoConstOpB = HasNoConstOp(B); 782 return std::tie(A.NumIn, A.IsBlock, NoConstOpA) < 783 std::tie(B.NumIn, B.IsBlock, NoConstOpB); 784 }); 785 786 SmallVector<Instruction *> ToRemove; 787 788 // Finally, process ordered worklist and eliminate implied conditions. 789 SmallVector<StackEntry, 16> DFSInStack; 790 for (ConstraintOrBlock &CB : S.WorkList) { 791 // First, pop entries from the stack that are out-of-scope for CB. Remove 792 // the corresponding entry from the constraint system. 793 while (!DFSInStack.empty()) { 794 auto &E = DFSInStack.back(); 795 LLVM_DEBUG(dbgs() << "Top of stack : " << E.NumIn << " " << E.NumOut 796 << "\n"); 797 LLVM_DEBUG(dbgs() << "CB: " << CB.NumIn << " " << CB.NumOut << "\n"); 798 assert(E.NumIn <= CB.NumIn); 799 if (CB.NumOut <= E.NumOut) 800 break; 801 LLVM_DEBUG({ 802 dbgs() << "Removing "; 803 dumpWithNames(Info.getCS(E.IsSigned).getLastConstraint(), 804 Info.getValue2Index(E.IsSigned)); 805 dbgs() << "\n"; 806 }); 807 808 Info.popLastConstraint(E.IsSigned); 809 // Remove variables in the system that went out of scope. 810 auto &Mapping = Info.getValue2Index(E.IsSigned); 811 for (Value *V : E.ValuesToRelease) 812 Mapping.erase(V); 813 Info.popLastNVariables(E.IsSigned, E.ValuesToRelease.size()); 814 DFSInStack.pop_back(); 815 } 816 817 LLVM_DEBUG({ 818 dbgs() << "Processing "; 819 if (CB.IsBlock) 820 dbgs() << *CB.BB; 821 else 822 dbgs() << *CB.Condition; 823 dbgs() << "\n"; 824 }); 825 826 // For a block, check if any CmpInsts become known based on the current set 827 // of constraints. 828 if (CB.IsBlock) { 829 for (Instruction &I : make_early_inc_range(*CB.BB)) { 830 if (auto *II = dyn_cast<WithOverflowInst>(&I)) { 831 Changed |= tryToSimplifyOverflowMath(II, Info, ToRemove); 832 continue; 833 } 834 auto *Cmp = dyn_cast<ICmpInst>(&I); 835 if (!Cmp) 836 continue; 837 838 LLVM_DEBUG(dbgs() << "Checking " << *Cmp << "\n"); 839 SmallVector<Value *> NewVariables; 840 auto R = Info.getConstraint(Cmp, NewVariables); 841 if (R.IsEq || R.empty() || !NewVariables.empty() || !R.isValid(Info)) 842 continue; 843 844 auto &CSToUse = Info.getCS(R.IsSigned); 845 846 // If there was extra information collected during decomposition, apply 847 // it now and remove it immediately once we are done with reasoning 848 // about the constraint. 849 for (auto &Row : R.ExtraInfo) 850 CSToUse.addVariableRow(Row); 851 auto InfoRestorer = make_scope_exit([&]() { 852 for (unsigned I = 0; I < R.ExtraInfo.size(); ++I) 853 CSToUse.popLastConstraint(); 854 }); 855 856 if (CSToUse.isConditionImplied(R.Coefficients)) { 857 if (!DebugCounter::shouldExecute(EliminatedCounter)) 858 continue; 859 860 LLVM_DEBUG({ 861 dbgs() << "Condition " << *Cmp 862 << " implied by dominating constraints\n"; 863 dumpWithNames(CSToUse, Info.getValue2Index(R.IsSigned)); 864 }); 865 Cmp->replaceUsesWithIf( 866 ConstantInt::getTrue(F.getParent()->getContext()), [](Use &U) { 867 // Conditions in an assume trivially simplify to true. Skip uses 868 // in assume calls to not destroy the available information. 869 auto *II = dyn_cast<IntrinsicInst>(U.getUser()); 870 return !II || II->getIntrinsicID() != Intrinsic::assume; 871 }); 872 NumCondsRemoved++; 873 Changed = true; 874 } 875 if (CSToUse.isConditionImplied( 876 ConstraintSystem::negate(R.Coefficients))) { 877 if (!DebugCounter::shouldExecute(EliminatedCounter)) 878 continue; 879 880 LLVM_DEBUG({ 881 dbgs() << "Condition !" << *Cmp 882 << " implied by dominating constraints\n"; 883 dumpWithNames(CSToUse, Info.getValue2Index(R.IsSigned)); 884 }); 885 Cmp->replaceAllUsesWith( 886 ConstantInt::getFalse(F.getParent()->getContext())); 887 NumCondsRemoved++; 888 Changed = true; 889 } 890 } 891 continue; 892 } 893 894 ICmpInst::Predicate Pred; 895 Value *A, *B; 896 if (match(CB.Condition, m_ICmp(Pred, m_Value(A), m_Value(B)))) { 897 // Use the inverse predicate if required. 898 if (CB.Not) 899 Pred = CmpInst::getInversePredicate(Pred); 900 901 Info.addFact(Pred, A, B, CB.NumIn, CB.NumOut, DFSInStack); 902 Info.transferToOtherSystem(Pred, A, B, CB.NumIn, CB.NumOut, DFSInStack); 903 } 904 } 905 906 #ifndef NDEBUG 907 unsigned SignedEntries = 908 count_if(DFSInStack, [](const StackEntry &E) { return E.IsSigned; }); 909 assert(Info.getCS(false).size() == DFSInStack.size() - SignedEntries && 910 "updates to CS and DFSInStack are out of sync"); 911 assert(Info.getCS(true).size() == SignedEntries && 912 "updates to CS and DFSInStack are out of sync"); 913 #endif 914 915 for (Instruction *I : ToRemove) 916 I->eraseFromParent(); 917 return Changed; 918 } 919 920 PreservedAnalyses ConstraintEliminationPass::run(Function &F, 921 FunctionAnalysisManager &AM) { 922 auto &DT = AM.getResult<DominatorTreeAnalysis>(F); 923 if (!eliminateConstraints(F, DT)) 924 return PreservedAnalyses::all(); 925 926 PreservedAnalyses PA; 927 PA.preserve<DominatorTreeAnalysis>(); 928 PA.preserveSet<CFGAnalyses>(); 929 return PA; 930 } 931 932 namespace { 933 934 class ConstraintElimination : public FunctionPass { 935 public: 936 static char ID; 937 938 ConstraintElimination() : FunctionPass(ID) { 939 initializeConstraintEliminationPass(*PassRegistry::getPassRegistry()); 940 } 941 942 bool runOnFunction(Function &F) override { 943 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 944 return eliminateConstraints(F, DT); 945 } 946 947 void getAnalysisUsage(AnalysisUsage &AU) const override { 948 AU.setPreservesCFG(); 949 AU.addRequired<DominatorTreeWrapperPass>(); 950 AU.addPreserved<GlobalsAAWrapperPass>(); 951 AU.addPreserved<DominatorTreeWrapperPass>(); 952 } 953 }; 954 955 } // end anonymous namespace 956 957 char ConstraintElimination::ID = 0; 958 959 INITIALIZE_PASS_BEGIN(ConstraintElimination, "constraint-elimination", 960 "Constraint Elimination", false, false) 961 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 962 INITIALIZE_PASS_DEPENDENCY(LazyValueInfoWrapperPass) 963 INITIALIZE_PASS_END(ConstraintElimination, "constraint-elimination", 964 "Constraint Elimination", false, false) 965 966 FunctionPass *llvm::createConstraintEliminationPass() { 967 return new ConstraintElimination(); 968 } 969