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