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