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/LoopInfo.h" 22 #include "llvm/Analysis/OptimizationRemarkEmitter.h" 23 #include "llvm/Analysis/ScalarEvolution.h" 24 #include "llvm/Analysis/ScalarEvolutionExpressions.h" 25 #include "llvm/Analysis/ValueTracking.h" 26 #include "llvm/IR/DataLayout.h" 27 #include "llvm/IR/Dominators.h" 28 #include "llvm/IR/Function.h" 29 #include "llvm/IR/IRBuilder.h" 30 #include "llvm/IR/InstrTypes.h" 31 #include "llvm/IR/Instructions.h" 32 #include "llvm/IR/Module.h" 33 #include "llvm/IR/PatternMatch.h" 34 #include "llvm/IR/Verifier.h" 35 #include "llvm/Pass.h" 36 #include "llvm/Support/CommandLine.h" 37 #include "llvm/Support/Debug.h" 38 #include "llvm/Support/DebugCounter.h" 39 #include "llvm/Support/MathExtras.h" 40 #include "llvm/Transforms/Utils/Cloning.h" 41 #include "llvm/Transforms/Utils/ValueMapper.h" 42 43 #include <cmath> 44 #include <optional> 45 #include <string> 46 47 using namespace llvm; 48 using namespace PatternMatch; 49 50 #define DEBUG_TYPE "constraint-elimination" 51 52 STATISTIC(NumCondsRemoved, "Number of instructions removed"); 53 DEBUG_COUNTER(EliminatedCounter, "conds-eliminated", 54 "Controls which conditions are eliminated"); 55 56 static cl::opt<unsigned> 57 MaxRows("constraint-elimination-max-rows", cl::init(500), cl::Hidden, 58 cl::desc("Maximum number of rows to keep in constraint system")); 59 60 static cl::opt<bool> DumpReproducers( 61 "constraint-elimination-dump-reproducers", cl::init(false), cl::Hidden, 62 cl::desc("Dump IR to reproduce successful transformations.")); 63 64 static int64_t MaxConstraintValue = std::numeric_limits<int64_t>::max(); 65 static int64_t MinSignedConstraintValue = std::numeric_limits<int64_t>::min(); 66 67 // A helper to multiply 2 signed integers where overflowing is allowed. 68 static int64_t multiplyWithOverflow(int64_t A, int64_t B) { 69 int64_t Result; 70 MulOverflow(A, B, Result); 71 return Result; 72 } 73 74 // A helper to add 2 signed integers where overflowing is allowed. 75 static int64_t addWithOverflow(int64_t A, int64_t B) { 76 int64_t Result; 77 AddOverflow(A, B, Result); 78 return Result; 79 } 80 81 static Instruction *getContextInstForUse(Use &U) { 82 Instruction *UserI = cast<Instruction>(U.getUser()); 83 if (auto *Phi = dyn_cast<PHINode>(UserI)) 84 UserI = Phi->getIncomingBlock(U)->getTerminator(); 85 return UserI; 86 } 87 88 namespace { 89 /// Struct to express a condition of the form %Op0 Pred %Op1. 90 struct ConditionTy { 91 CmpInst::Predicate Pred; 92 Value *Op0; 93 Value *Op1; 94 95 ConditionTy() 96 : Pred(CmpInst::BAD_ICMP_PREDICATE), Op0(nullptr), Op1(nullptr) {} 97 ConditionTy(CmpInst::Predicate Pred, Value *Op0, Value *Op1) 98 : Pred(Pred), Op0(Op0), Op1(Op1) {} 99 }; 100 101 /// Represents either 102 /// * a condition that holds on entry to a block (=condition fact) 103 /// * an assume (=assume fact) 104 /// * a use of a compare instruction to simplify. 105 /// It also tracks the Dominator DFS in and out numbers for each entry. 106 struct FactOrCheck { 107 enum class EntryTy { 108 ConditionFact, /// A condition that holds on entry to a block. 109 InstFact, /// A fact that holds after Inst executed (e.g. an assume or 110 /// min/mix intrinsic. 111 InstCheck, /// An instruction to simplify (e.g. an overflow math 112 /// intrinsics). 113 UseCheck /// An use of a compare instruction to simplify. 114 }; 115 116 union { 117 Instruction *Inst; 118 Use *U; 119 ConditionTy Cond; 120 }; 121 122 /// A pre-condition that must hold for the current fact to be added to the 123 /// system. 124 ConditionTy DoesHold; 125 126 unsigned NumIn; 127 unsigned NumOut; 128 EntryTy Ty; 129 130 FactOrCheck(EntryTy Ty, DomTreeNode *DTN, Instruction *Inst) 131 : Inst(Inst), NumIn(DTN->getDFSNumIn()), NumOut(DTN->getDFSNumOut()), 132 Ty(Ty) {} 133 134 FactOrCheck(DomTreeNode *DTN, Use *U) 135 : U(U), DoesHold(CmpInst::BAD_ICMP_PREDICATE, nullptr, nullptr), 136 NumIn(DTN->getDFSNumIn()), NumOut(DTN->getDFSNumOut()), 137 Ty(EntryTy::UseCheck) {} 138 139 FactOrCheck(DomTreeNode *DTN, CmpInst::Predicate Pred, Value *Op0, Value *Op1, 140 ConditionTy Precond = ConditionTy()) 141 : Cond(Pred, Op0, Op1), DoesHold(Precond), NumIn(DTN->getDFSNumIn()), 142 NumOut(DTN->getDFSNumOut()), Ty(EntryTy::ConditionFact) {} 143 144 static FactOrCheck getConditionFact(DomTreeNode *DTN, CmpInst::Predicate Pred, 145 Value *Op0, Value *Op1, 146 ConditionTy Precond = ConditionTy()) { 147 return FactOrCheck(DTN, Pred, Op0, Op1, Precond); 148 } 149 150 static FactOrCheck getInstFact(DomTreeNode *DTN, Instruction *Inst) { 151 return FactOrCheck(EntryTy::InstFact, DTN, Inst); 152 } 153 154 static FactOrCheck getCheck(DomTreeNode *DTN, Use *U) { 155 return FactOrCheck(DTN, U); 156 } 157 158 static FactOrCheck getCheck(DomTreeNode *DTN, CallInst *CI) { 159 return FactOrCheck(EntryTy::InstCheck, DTN, CI); 160 } 161 162 bool isCheck() const { 163 return Ty == EntryTy::InstCheck || Ty == EntryTy::UseCheck; 164 } 165 166 Instruction *getContextInst() const { 167 assert(!isConditionFact()); 168 if (Ty == EntryTy::UseCheck) 169 return getContextInstForUse(*U); 170 return Inst; 171 } 172 173 Instruction *getInstructionToSimplify() const { 174 assert(isCheck()); 175 if (Ty == EntryTy::InstCheck) 176 return Inst; 177 // The use may have been simplified to a constant already. 178 return dyn_cast<Instruction>(*U); 179 } 180 181 bool isConditionFact() const { return Ty == EntryTy::ConditionFact; } 182 }; 183 184 /// Keep state required to build worklist. 185 struct State { 186 DominatorTree &DT; 187 LoopInfo &LI; 188 ScalarEvolution &SE; 189 SmallVector<FactOrCheck, 64> WorkList; 190 191 State(DominatorTree &DT, LoopInfo &LI, ScalarEvolution &SE) 192 : DT(DT), LI(LI), SE(SE) {} 193 194 /// Process block \p BB and add known facts to work-list. 195 void addInfoFor(BasicBlock &BB); 196 197 /// Try to add facts for loop inductions (AddRecs) in EQ/NE compares 198 /// controlling the loop header. 199 void addInfoForInductions(BasicBlock &BB); 200 201 /// Returns true if we can add a known condition from BB to its successor 202 /// block Succ. 203 bool canAddSuccessor(BasicBlock &BB, BasicBlock *Succ) const { 204 return DT.dominates(BasicBlockEdge(&BB, Succ), Succ); 205 } 206 }; 207 208 class ConstraintInfo; 209 210 struct StackEntry { 211 unsigned NumIn; 212 unsigned NumOut; 213 bool IsSigned = false; 214 /// Variables that can be removed from the system once the stack entry gets 215 /// removed. 216 SmallVector<Value *, 2> ValuesToRelease; 217 218 StackEntry(unsigned NumIn, unsigned NumOut, bool IsSigned, 219 SmallVector<Value *, 2> ValuesToRelease) 220 : NumIn(NumIn), NumOut(NumOut), IsSigned(IsSigned), 221 ValuesToRelease(ValuesToRelease) {} 222 }; 223 224 struct ConstraintTy { 225 SmallVector<int64_t, 8> Coefficients; 226 SmallVector<ConditionTy, 2> Preconditions; 227 228 SmallVector<SmallVector<int64_t, 8>> ExtraInfo; 229 230 bool IsSigned = false; 231 232 ConstraintTy() = default; 233 234 ConstraintTy(SmallVector<int64_t, 8> Coefficients, bool IsSigned, bool IsEq, 235 bool IsNe) 236 : Coefficients(std::move(Coefficients)), IsSigned(IsSigned), IsEq(IsEq), 237 IsNe(IsNe) {} 238 239 unsigned size() const { return Coefficients.size(); } 240 241 unsigned empty() const { return Coefficients.empty(); } 242 243 /// Returns true if all preconditions for this list of constraints are 244 /// satisfied given \p CS and the corresponding \p Value2Index mapping. 245 bool isValid(const ConstraintInfo &Info) const; 246 247 bool isEq() const { return IsEq; } 248 249 bool isNe() const { return IsNe; } 250 251 /// Check if the current constraint is implied by the given ConstraintSystem. 252 /// 253 /// \return true or false if the constraint is proven to be respectively true, 254 /// or false. When the constraint cannot be proven to be either true or false, 255 /// std::nullopt is returned. 256 std::optional<bool> isImpliedBy(const ConstraintSystem &CS) const; 257 258 private: 259 bool IsEq = false; 260 bool IsNe = false; 261 }; 262 263 /// Wrapper encapsulating separate constraint systems and corresponding value 264 /// mappings for both unsigned and signed information. Facts are added to and 265 /// conditions are checked against the corresponding system depending on the 266 /// signed-ness of their predicates. While the information is kept separate 267 /// based on signed-ness, certain conditions can be transferred between the two 268 /// systems. 269 class ConstraintInfo { 270 271 ConstraintSystem UnsignedCS; 272 ConstraintSystem SignedCS; 273 274 const DataLayout &DL; 275 276 public: 277 ConstraintInfo(const DataLayout &DL, ArrayRef<Value *> FunctionArgs) 278 : UnsignedCS(FunctionArgs), SignedCS(FunctionArgs), DL(DL) { 279 auto &Value2Index = getValue2Index(false); 280 // Add Arg > -1 constraints to unsigned system for all function arguments. 281 for (Value *Arg : FunctionArgs) { 282 ConstraintTy VarPos(SmallVector<int64_t, 8>(Value2Index.size() + 1, 0), 283 false, false, false); 284 VarPos.Coefficients[Value2Index[Arg]] = -1; 285 UnsignedCS.addVariableRow(VarPos.Coefficients); 286 } 287 } 288 289 DenseMap<Value *, unsigned> &getValue2Index(bool Signed) { 290 return Signed ? SignedCS.getValue2Index() : UnsignedCS.getValue2Index(); 291 } 292 const DenseMap<Value *, unsigned> &getValue2Index(bool Signed) const { 293 return Signed ? SignedCS.getValue2Index() : UnsignedCS.getValue2Index(); 294 } 295 296 ConstraintSystem &getCS(bool Signed) { 297 return Signed ? SignedCS : UnsignedCS; 298 } 299 const ConstraintSystem &getCS(bool Signed) const { 300 return Signed ? SignedCS : UnsignedCS; 301 } 302 303 void popLastConstraint(bool Signed) { getCS(Signed).popLastConstraint(); } 304 void popLastNVariables(bool Signed, unsigned N) { 305 getCS(Signed).popLastNVariables(N); 306 } 307 308 bool doesHold(CmpInst::Predicate Pred, Value *A, Value *B) const; 309 310 void addFact(CmpInst::Predicate Pred, Value *A, Value *B, unsigned NumIn, 311 unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack); 312 313 /// Turn a comparison of the form \p Op0 \p Pred \p Op1 into a vector of 314 /// constraints, using indices from the corresponding constraint system. 315 /// New variables that need to be added to the system are collected in 316 /// \p NewVariables. 317 ConstraintTy getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1, 318 SmallVectorImpl<Value *> &NewVariables) const; 319 320 /// Turns a comparison of the form \p Op0 \p Pred \p Op1 into a vector of 321 /// constraints using getConstraint. Returns an empty constraint if the result 322 /// cannot be used to query the existing constraint system, e.g. because it 323 /// would require adding new variables. Also tries to convert signed 324 /// predicates to unsigned ones if possible to allow using the unsigned system 325 /// which increases the effectiveness of the signed <-> unsigned transfer 326 /// logic. 327 ConstraintTy getConstraintForSolving(CmpInst::Predicate Pred, Value *Op0, 328 Value *Op1) const; 329 330 /// Try to add information from \p A \p Pred \p B to the unsigned/signed 331 /// system if \p Pred is signed/unsigned. 332 void transferToOtherSystem(CmpInst::Predicate Pred, Value *A, Value *B, 333 unsigned NumIn, unsigned NumOut, 334 SmallVectorImpl<StackEntry> &DFSInStack); 335 }; 336 337 /// Represents a (Coefficient * Variable) entry after IR decomposition. 338 struct DecompEntry { 339 int64_t Coefficient; 340 Value *Variable; 341 /// True if the variable is known positive in the current constraint. 342 bool IsKnownNonNegative; 343 344 DecompEntry(int64_t Coefficient, Value *Variable, 345 bool IsKnownNonNegative = false) 346 : Coefficient(Coefficient), Variable(Variable), 347 IsKnownNonNegative(IsKnownNonNegative) {} 348 }; 349 350 /// Represents an Offset + Coefficient1 * Variable1 + ... decomposition. 351 struct Decomposition { 352 int64_t Offset = 0; 353 SmallVector<DecompEntry, 3> Vars; 354 355 Decomposition(int64_t Offset) : Offset(Offset) {} 356 Decomposition(Value *V, bool IsKnownNonNegative = false) { 357 Vars.emplace_back(1, V, IsKnownNonNegative); 358 } 359 Decomposition(int64_t Offset, ArrayRef<DecompEntry> Vars) 360 : Offset(Offset), Vars(Vars) {} 361 362 void add(int64_t OtherOffset) { 363 Offset = addWithOverflow(Offset, OtherOffset); 364 } 365 366 void add(const Decomposition &Other) { 367 add(Other.Offset); 368 append_range(Vars, Other.Vars); 369 } 370 371 void sub(const Decomposition &Other) { 372 Decomposition Tmp = Other; 373 Tmp.mul(-1); 374 add(Tmp.Offset); 375 append_range(Vars, Tmp.Vars); 376 } 377 378 void mul(int64_t Factor) { 379 Offset = multiplyWithOverflow(Offset, Factor); 380 for (auto &Var : Vars) 381 Var.Coefficient = multiplyWithOverflow(Var.Coefficient, Factor); 382 } 383 }; 384 385 // Variable and constant offsets for a chain of GEPs, with base pointer BasePtr. 386 struct OffsetResult { 387 Value *BasePtr; 388 APInt ConstantOffset; 389 SmallMapVector<Value *, APInt, 4> VariableOffsets; 390 GEPNoWrapFlags NW; 391 392 OffsetResult() : BasePtr(nullptr), ConstantOffset(0, uint64_t(0)) {} 393 394 OffsetResult(GEPOperator &GEP, const DataLayout &DL) 395 : BasePtr(GEP.getPointerOperand()), NW(GEP.getNoWrapFlags()) { 396 ConstantOffset = APInt(DL.getIndexTypeSizeInBits(BasePtr->getType()), 0); 397 } 398 }; 399 } // namespace 400 401 // Try to collect variable and constant offsets for \p GEP, partly traversing 402 // nested GEPs. Returns an OffsetResult with nullptr as BasePtr of collecting 403 // the offset fails. 404 static OffsetResult collectOffsets(GEPOperator &GEP, const DataLayout &DL) { 405 OffsetResult Result(GEP, DL); 406 unsigned BitWidth = Result.ConstantOffset.getBitWidth(); 407 if (!GEP.collectOffset(DL, BitWidth, Result.VariableOffsets, 408 Result.ConstantOffset)) 409 return {}; 410 411 // If we have a nested GEP, check if we can combine the constant offset of the 412 // inner GEP with the outer GEP. 413 if (auto *InnerGEP = dyn_cast<GetElementPtrInst>(Result.BasePtr)) { 414 SmallMapVector<Value *, APInt, 4> VariableOffsets2; 415 APInt ConstantOffset2(BitWidth, 0); 416 bool CanCollectInner = InnerGEP->collectOffset( 417 DL, BitWidth, VariableOffsets2, ConstantOffset2); 418 // TODO: Support cases with more than 1 variable offset. 419 if (!CanCollectInner || Result.VariableOffsets.size() > 1 || 420 VariableOffsets2.size() > 1 || 421 (Result.VariableOffsets.size() >= 1 && VariableOffsets2.size() >= 1)) { 422 // More than 1 variable index, use outer result. 423 return Result; 424 } 425 Result.BasePtr = InnerGEP->getPointerOperand(); 426 Result.ConstantOffset += ConstantOffset2; 427 if (Result.VariableOffsets.size() == 0 && VariableOffsets2.size() == 1) 428 Result.VariableOffsets = VariableOffsets2; 429 Result.NW &= InnerGEP->getNoWrapFlags(); 430 } 431 return Result; 432 } 433 434 static Decomposition decompose(Value *V, 435 SmallVectorImpl<ConditionTy> &Preconditions, 436 bool IsSigned, const DataLayout &DL); 437 438 static bool canUseSExt(ConstantInt *CI) { 439 const APInt &Val = CI->getValue(); 440 return Val.sgt(MinSignedConstraintValue) && Val.slt(MaxConstraintValue); 441 } 442 443 static Decomposition decomposeGEP(GEPOperator &GEP, 444 SmallVectorImpl<ConditionTy> &Preconditions, 445 bool IsSigned, const DataLayout &DL) { 446 // Do not reason about pointers where the index size is larger than 64 bits, 447 // as the coefficients used to encode constraints are 64 bit integers. 448 if (DL.getIndexTypeSizeInBits(GEP.getPointerOperand()->getType()) > 64) 449 return &GEP; 450 451 assert(!IsSigned && "The logic below only supports decomposition for " 452 "unsigned predicates at the moment."); 453 const auto &[BasePtr, ConstantOffset, VariableOffsets, NW] = 454 collectOffsets(GEP, DL); 455 // We support either plain gep nuw, or gep nusw with non-negative offset, 456 // which implies gep nuw. 457 if (!BasePtr || NW == GEPNoWrapFlags::none()) 458 return &GEP; 459 460 Decomposition Result(ConstantOffset.getSExtValue(), DecompEntry(1, BasePtr)); 461 for (auto [Index, Scale] : VariableOffsets) { 462 auto IdxResult = decompose(Index, Preconditions, IsSigned, DL); 463 IdxResult.mul(Scale.getSExtValue()); 464 Result.add(IdxResult); 465 466 if (!NW.hasNoUnsignedWrap()) { 467 // Try to prove nuw from nusw and nneg. 468 assert(NW.hasNoUnsignedSignedWrap() && "Must have nusw flag"); 469 if (!isKnownNonNegative(Index, DL)) 470 Preconditions.emplace_back(CmpInst::ICMP_SGE, Index, 471 ConstantInt::get(Index->getType(), 0)); 472 } 473 } 474 return Result; 475 } 476 477 // Decomposes \p V into a constant offset + list of pairs { Coefficient, 478 // Variable } where Coefficient * Variable. The sum of the constant offset and 479 // pairs equals \p V. 480 static Decomposition decompose(Value *V, 481 SmallVectorImpl<ConditionTy> &Preconditions, 482 bool IsSigned, const DataLayout &DL) { 483 484 auto MergeResults = [&Preconditions, IsSigned, &DL](Value *A, Value *B, 485 bool IsSignedB) { 486 auto ResA = decompose(A, Preconditions, IsSigned, DL); 487 auto ResB = decompose(B, Preconditions, IsSignedB, DL); 488 ResA.add(ResB); 489 return ResA; 490 }; 491 492 Type *Ty = V->getType()->getScalarType(); 493 if (Ty->isPointerTy() && !IsSigned) { 494 if (auto *GEP = dyn_cast<GEPOperator>(V)) 495 return decomposeGEP(*GEP, Preconditions, IsSigned, DL); 496 if (isa<ConstantPointerNull>(V)) 497 return int64_t(0); 498 499 return V; 500 } 501 502 // Don't handle integers > 64 bit. Our coefficients are 64-bit large, so 503 // coefficient add/mul may wrap, while the operation in the full bit width 504 // would not. 505 if (!Ty->isIntegerTy() || Ty->getIntegerBitWidth() > 64) 506 return V; 507 508 bool IsKnownNonNegative = false; 509 510 // Decompose \p V used with a signed predicate. 511 if (IsSigned) { 512 if (auto *CI = dyn_cast<ConstantInt>(V)) { 513 if (canUseSExt(CI)) 514 return CI->getSExtValue(); 515 } 516 Value *Op0; 517 Value *Op1; 518 519 if (match(V, m_SExt(m_Value(Op0)))) 520 V = Op0; 521 else if (match(V, m_NNegZExt(m_Value(Op0)))) { 522 V = Op0; 523 IsKnownNonNegative = true; 524 } 525 526 if (match(V, m_NSWAdd(m_Value(Op0), m_Value(Op1)))) 527 return MergeResults(Op0, Op1, IsSigned); 528 529 ConstantInt *CI; 530 if (match(V, m_NSWMul(m_Value(Op0), m_ConstantInt(CI))) && canUseSExt(CI)) { 531 auto Result = decompose(Op0, Preconditions, IsSigned, DL); 532 Result.mul(CI->getSExtValue()); 533 return Result; 534 } 535 536 // (shl nsw x, shift) is (mul nsw x, (1<<shift)), with the exception of 537 // shift == bw-1. 538 if (match(V, m_NSWShl(m_Value(Op0), m_ConstantInt(CI)))) { 539 uint64_t Shift = CI->getValue().getLimitedValue(); 540 if (Shift < Ty->getIntegerBitWidth() - 1) { 541 assert(Shift < 64 && "Would overflow"); 542 auto Result = decompose(Op0, Preconditions, IsSigned, DL); 543 Result.mul(int64_t(1) << Shift); 544 return Result; 545 } 546 } 547 548 return {V, IsKnownNonNegative}; 549 } 550 551 if (auto *CI = dyn_cast<ConstantInt>(V)) { 552 if (CI->uge(MaxConstraintValue)) 553 return V; 554 return int64_t(CI->getZExtValue()); 555 } 556 557 Value *Op0; 558 if (match(V, m_ZExt(m_Value(Op0)))) { 559 IsKnownNonNegative = true; 560 V = Op0; 561 } 562 563 if (match(V, m_SExt(m_Value(Op0)))) { 564 V = Op0; 565 Preconditions.emplace_back(CmpInst::ICMP_SGE, Op0, 566 ConstantInt::get(Op0->getType(), 0)); 567 } 568 569 Value *Op1; 570 ConstantInt *CI; 571 if (match(V, m_NUWAdd(m_Value(Op0), m_Value(Op1)))) { 572 return MergeResults(Op0, Op1, IsSigned); 573 } 574 if (match(V, m_NSWAdd(m_Value(Op0), m_Value(Op1)))) { 575 if (!isKnownNonNegative(Op0, DL)) 576 Preconditions.emplace_back(CmpInst::ICMP_SGE, Op0, 577 ConstantInt::get(Op0->getType(), 0)); 578 if (!isKnownNonNegative(Op1, DL)) 579 Preconditions.emplace_back(CmpInst::ICMP_SGE, Op1, 580 ConstantInt::get(Op1->getType(), 0)); 581 582 return MergeResults(Op0, Op1, IsSigned); 583 } 584 585 if (match(V, m_Add(m_Value(Op0), m_ConstantInt(CI))) && CI->isNegative() && 586 canUseSExt(CI)) { 587 Preconditions.emplace_back( 588 CmpInst::ICMP_UGE, Op0, 589 ConstantInt::get(Op0->getType(), CI->getSExtValue() * -1)); 590 return MergeResults(Op0, CI, true); 591 } 592 593 // Decompose or as an add if there are no common bits between the operands. 594 if (match(V, m_DisjointOr(m_Value(Op0), m_ConstantInt(CI)))) 595 return MergeResults(Op0, CI, IsSigned); 596 597 if (match(V, m_NUWShl(m_Value(Op1), m_ConstantInt(CI))) && canUseSExt(CI)) { 598 if (CI->getSExtValue() < 0 || CI->getSExtValue() >= 64) 599 return {V, IsKnownNonNegative}; 600 auto Result = decompose(Op1, Preconditions, IsSigned, DL); 601 Result.mul(int64_t{1} << CI->getSExtValue()); 602 return Result; 603 } 604 605 if (match(V, m_NUWMul(m_Value(Op1), m_ConstantInt(CI))) && canUseSExt(CI) && 606 (!CI->isNegative())) { 607 auto Result = decompose(Op1, Preconditions, IsSigned, DL); 608 Result.mul(CI->getSExtValue()); 609 return Result; 610 } 611 612 if (match(V, m_NUWSub(m_Value(Op0), m_Value(Op1)))) { 613 auto ResA = decompose(Op0, Preconditions, IsSigned, DL); 614 auto ResB = decompose(Op1, Preconditions, IsSigned, DL); 615 ResA.sub(ResB); 616 return ResA; 617 } 618 619 return {V, IsKnownNonNegative}; 620 } 621 622 ConstraintTy 623 ConstraintInfo::getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1, 624 SmallVectorImpl<Value *> &NewVariables) const { 625 assert(NewVariables.empty() && "NewVariables must be empty when passed in"); 626 bool IsEq = false; 627 bool IsNe = false; 628 629 // Try to convert Pred to one of ULE/SLT/SLE/SLT. 630 switch (Pred) { 631 case CmpInst::ICMP_UGT: 632 case CmpInst::ICMP_UGE: 633 case CmpInst::ICMP_SGT: 634 case CmpInst::ICMP_SGE: { 635 Pred = CmpInst::getSwappedPredicate(Pred); 636 std::swap(Op0, Op1); 637 break; 638 } 639 case CmpInst::ICMP_EQ: 640 if (match(Op1, m_Zero())) { 641 Pred = CmpInst::ICMP_ULE; 642 } else { 643 IsEq = true; 644 Pred = CmpInst::ICMP_ULE; 645 } 646 break; 647 case CmpInst::ICMP_NE: 648 if (match(Op1, m_Zero())) { 649 Pred = CmpInst::getSwappedPredicate(CmpInst::ICMP_UGT); 650 std::swap(Op0, Op1); 651 } else { 652 IsNe = true; 653 Pred = CmpInst::ICMP_ULE; 654 } 655 break; 656 default: 657 break; 658 } 659 660 if (Pred != CmpInst::ICMP_ULE && Pred != CmpInst::ICMP_ULT && 661 Pred != CmpInst::ICMP_SLE && Pred != CmpInst::ICMP_SLT) 662 return {}; 663 664 SmallVector<ConditionTy, 4> Preconditions; 665 bool IsSigned = CmpInst::isSigned(Pred); 666 auto &Value2Index = getValue2Index(IsSigned); 667 auto ADec = decompose(Op0->stripPointerCastsSameRepresentation(), 668 Preconditions, IsSigned, DL); 669 auto BDec = decompose(Op1->stripPointerCastsSameRepresentation(), 670 Preconditions, IsSigned, DL); 671 int64_t Offset1 = ADec.Offset; 672 int64_t Offset2 = BDec.Offset; 673 Offset1 *= -1; 674 675 auto &VariablesA = ADec.Vars; 676 auto &VariablesB = BDec.Vars; 677 678 // First try to look up \p V in Value2Index and NewVariables. Otherwise add a 679 // new entry to NewVariables. 680 SmallDenseMap<Value *, unsigned> NewIndexMap; 681 auto GetOrAddIndex = [&Value2Index, &NewVariables, 682 &NewIndexMap](Value *V) -> unsigned { 683 auto V2I = Value2Index.find(V); 684 if (V2I != Value2Index.end()) 685 return V2I->second; 686 auto Insert = 687 NewIndexMap.insert({V, Value2Index.size() + NewVariables.size() + 1}); 688 if (Insert.second) 689 NewVariables.push_back(V); 690 return Insert.first->second; 691 }; 692 693 // Make sure all variables have entries in Value2Index or NewVariables. 694 for (const auto &KV : concat<DecompEntry>(VariablesA, VariablesB)) 695 GetOrAddIndex(KV.Variable); 696 697 // Build result constraint, by first adding all coefficients from A and then 698 // subtracting all coefficients from B. 699 ConstraintTy Res( 700 SmallVector<int64_t, 8>(Value2Index.size() + NewVariables.size() + 1, 0), 701 IsSigned, IsEq, IsNe); 702 // Collect variables that are known to be positive in all uses in the 703 // constraint. 704 SmallDenseMap<Value *, bool> KnownNonNegativeVariables; 705 auto &R = Res.Coefficients; 706 for (const auto &KV : VariablesA) { 707 R[GetOrAddIndex(KV.Variable)] += KV.Coefficient; 708 auto I = 709 KnownNonNegativeVariables.insert({KV.Variable, KV.IsKnownNonNegative}); 710 I.first->second &= KV.IsKnownNonNegative; 711 } 712 713 for (const auto &KV : VariablesB) { 714 if (SubOverflow(R[GetOrAddIndex(KV.Variable)], KV.Coefficient, 715 R[GetOrAddIndex(KV.Variable)])) 716 return {}; 717 auto I = 718 KnownNonNegativeVariables.insert({KV.Variable, KV.IsKnownNonNegative}); 719 I.first->second &= KV.IsKnownNonNegative; 720 } 721 722 int64_t OffsetSum; 723 if (AddOverflow(Offset1, Offset2, OffsetSum)) 724 return {}; 725 if (Pred == (IsSigned ? CmpInst::ICMP_SLT : CmpInst::ICMP_ULT)) 726 if (AddOverflow(OffsetSum, int64_t(-1), OffsetSum)) 727 return {}; 728 R[0] = OffsetSum; 729 Res.Preconditions = std::move(Preconditions); 730 731 // Remove any (Coefficient, Variable) entry where the Coefficient is 0 for new 732 // variables. 733 while (!NewVariables.empty()) { 734 int64_t Last = R.back(); 735 if (Last != 0) 736 break; 737 R.pop_back(); 738 Value *RemovedV = NewVariables.pop_back_val(); 739 NewIndexMap.erase(RemovedV); 740 } 741 742 // Add extra constraints for variables that are known positive. 743 for (auto &KV : KnownNonNegativeVariables) { 744 if (!KV.second || 745 (!Value2Index.contains(KV.first) && !NewIndexMap.contains(KV.first))) 746 continue; 747 SmallVector<int64_t, 8> C(Value2Index.size() + NewVariables.size() + 1, 0); 748 C[GetOrAddIndex(KV.first)] = -1; 749 Res.ExtraInfo.push_back(C); 750 } 751 return Res; 752 } 753 754 ConstraintTy ConstraintInfo::getConstraintForSolving(CmpInst::Predicate Pred, 755 Value *Op0, 756 Value *Op1) const { 757 Constant *NullC = Constant::getNullValue(Op0->getType()); 758 // Handle trivially true compares directly to avoid adding V UGE 0 constraints 759 // for all variables in the unsigned system. 760 if ((Pred == CmpInst::ICMP_ULE && Op0 == NullC) || 761 (Pred == CmpInst::ICMP_UGE && Op1 == NullC)) { 762 auto &Value2Index = getValue2Index(false); 763 // Return constraint that's trivially true. 764 return ConstraintTy(SmallVector<int64_t, 8>(Value2Index.size(), 0), false, 765 false, false); 766 } 767 768 // If both operands are known to be non-negative, change signed predicates to 769 // unsigned ones. This increases the reasoning effectiveness in combination 770 // with the signed <-> unsigned transfer logic. 771 if (CmpInst::isSigned(Pred) && 772 isKnownNonNegative(Op0, DL, /*Depth=*/MaxAnalysisRecursionDepth - 1) && 773 isKnownNonNegative(Op1, DL, /*Depth=*/MaxAnalysisRecursionDepth - 1)) 774 Pred = ICmpInst::getUnsignedPredicate(Pred); 775 776 SmallVector<Value *> NewVariables; 777 ConstraintTy R = getConstraint(Pred, Op0, Op1, NewVariables); 778 if (!NewVariables.empty()) 779 return {}; 780 return R; 781 } 782 783 bool ConstraintTy::isValid(const ConstraintInfo &Info) const { 784 return Coefficients.size() > 0 && 785 all_of(Preconditions, [&Info](const ConditionTy &C) { 786 return Info.doesHold(C.Pred, C.Op0, C.Op1); 787 }); 788 } 789 790 std::optional<bool> 791 ConstraintTy::isImpliedBy(const ConstraintSystem &CS) const { 792 bool IsConditionImplied = CS.isConditionImplied(Coefficients); 793 794 if (IsEq || IsNe) { 795 auto NegatedOrEqual = ConstraintSystem::negateOrEqual(Coefficients); 796 bool IsNegatedOrEqualImplied = 797 !NegatedOrEqual.empty() && CS.isConditionImplied(NegatedOrEqual); 798 799 // In order to check that `%a == %b` is true (equality), both conditions `%a 800 // >= %b` and `%a <= %b` must hold true. When checking for equality (`IsEq` 801 // is true), we return true if they both hold, false in the other cases. 802 if (IsConditionImplied && IsNegatedOrEqualImplied) 803 return IsEq; 804 805 auto Negated = ConstraintSystem::negate(Coefficients); 806 bool IsNegatedImplied = !Negated.empty() && CS.isConditionImplied(Negated); 807 808 auto StrictLessThan = ConstraintSystem::toStrictLessThan(Coefficients); 809 bool IsStrictLessThanImplied = 810 !StrictLessThan.empty() && CS.isConditionImplied(StrictLessThan); 811 812 // In order to check that `%a != %b` is true (non-equality), either 813 // condition `%a > %b` or `%a < %b` must hold true. When checking for 814 // non-equality (`IsNe` is true), we return true if one of the two holds, 815 // false in the other cases. 816 if (IsNegatedImplied || IsStrictLessThanImplied) 817 return IsNe; 818 819 return std::nullopt; 820 } 821 822 if (IsConditionImplied) 823 return true; 824 825 auto Negated = ConstraintSystem::negate(Coefficients); 826 auto IsNegatedImplied = !Negated.empty() && CS.isConditionImplied(Negated); 827 if (IsNegatedImplied) 828 return false; 829 830 // Neither the condition nor its negated holds, did not prove anything. 831 return std::nullopt; 832 } 833 834 bool ConstraintInfo::doesHold(CmpInst::Predicate Pred, Value *A, 835 Value *B) const { 836 auto R = getConstraintForSolving(Pred, A, B); 837 return R.isValid(*this) && 838 getCS(R.IsSigned).isConditionImplied(R.Coefficients); 839 } 840 841 void ConstraintInfo::transferToOtherSystem( 842 CmpInst::Predicate Pred, Value *A, Value *B, unsigned NumIn, 843 unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack) { 844 auto IsKnownNonNegative = [this](Value *V) { 845 return doesHold(CmpInst::ICMP_SGE, V, ConstantInt::get(V->getType(), 0)) || 846 isKnownNonNegative(V, DL, /*Depth=*/MaxAnalysisRecursionDepth - 1); 847 }; 848 // Check if we can combine facts from the signed and unsigned systems to 849 // derive additional facts. 850 if (!A->getType()->isIntegerTy()) 851 return; 852 // FIXME: This currently depends on the order we add facts. Ideally we 853 // would first add all known facts and only then try to add additional 854 // facts. 855 switch (Pred) { 856 default: 857 break; 858 case CmpInst::ICMP_ULT: 859 case CmpInst::ICMP_ULE: 860 // If B is a signed positive constant, then A >=s 0 and A <s (or <=s) B. 861 if (IsKnownNonNegative(B)) { 862 addFact(CmpInst::ICMP_SGE, A, ConstantInt::get(B->getType(), 0), NumIn, 863 NumOut, DFSInStack); 864 addFact(ICmpInst::getSignedPredicate(Pred), A, B, NumIn, NumOut, 865 DFSInStack); 866 } 867 break; 868 case CmpInst::ICMP_UGE: 869 case CmpInst::ICMP_UGT: 870 // If A is a signed positive constant, then B >=s 0 and A >s (or >=s) B. 871 if (IsKnownNonNegative(A)) { 872 addFact(CmpInst::ICMP_SGE, B, ConstantInt::get(B->getType(), 0), NumIn, 873 NumOut, DFSInStack); 874 addFact(ICmpInst::getSignedPredicate(Pred), A, B, NumIn, NumOut, 875 DFSInStack); 876 } 877 break; 878 case CmpInst::ICMP_SLT: 879 if (IsKnownNonNegative(A)) 880 addFact(CmpInst::ICMP_ULT, A, B, NumIn, NumOut, DFSInStack); 881 break; 882 case CmpInst::ICMP_SGT: { 883 if (doesHold(CmpInst::ICMP_SGE, B, Constant::getAllOnesValue(B->getType()))) 884 addFact(CmpInst::ICMP_UGE, A, ConstantInt::get(B->getType(), 0), NumIn, 885 NumOut, DFSInStack); 886 if (IsKnownNonNegative(B)) 887 addFact(CmpInst::ICMP_UGT, A, B, NumIn, NumOut, DFSInStack); 888 889 break; 890 } 891 case CmpInst::ICMP_SGE: 892 if (IsKnownNonNegative(B)) 893 addFact(CmpInst::ICMP_UGE, A, B, NumIn, NumOut, DFSInStack); 894 break; 895 } 896 } 897 898 #ifndef NDEBUG 899 900 static void dumpConstraint(ArrayRef<int64_t> C, 901 const DenseMap<Value *, unsigned> &Value2Index) { 902 ConstraintSystem CS(Value2Index); 903 CS.addVariableRowFill(C); 904 CS.dump(); 905 } 906 #endif 907 908 void State::addInfoForInductions(BasicBlock &BB) { 909 auto *L = LI.getLoopFor(&BB); 910 if (!L || L->getHeader() != &BB) 911 return; 912 913 Value *A; 914 Value *B; 915 CmpInst::Predicate Pred; 916 917 if (!match(BB.getTerminator(), 918 m_Br(m_ICmp(Pred, m_Value(A), m_Value(B)), m_Value(), m_Value()))) 919 return; 920 PHINode *PN = dyn_cast<PHINode>(A); 921 if (!PN) { 922 Pred = CmpInst::getSwappedPredicate(Pred); 923 std::swap(A, B); 924 PN = dyn_cast<PHINode>(A); 925 } 926 927 if (!PN || PN->getParent() != &BB || PN->getNumIncomingValues() != 2 || 928 !SE.isSCEVable(PN->getType())) 929 return; 930 931 BasicBlock *InLoopSucc = nullptr; 932 if (Pred == CmpInst::ICMP_NE) 933 InLoopSucc = cast<BranchInst>(BB.getTerminator())->getSuccessor(0); 934 else if (Pred == CmpInst::ICMP_EQ) 935 InLoopSucc = cast<BranchInst>(BB.getTerminator())->getSuccessor(1); 936 else 937 return; 938 939 if (!L->contains(InLoopSucc) || !L->isLoopExiting(&BB) || InLoopSucc == &BB) 940 return; 941 942 auto *AR = dyn_cast_or_null<SCEVAddRecExpr>(SE.getSCEV(PN)); 943 BasicBlock *LoopPred = L->getLoopPredecessor(); 944 if (!AR || AR->getLoop() != L || !LoopPred) 945 return; 946 947 const SCEV *StartSCEV = AR->getStart(); 948 Value *StartValue = nullptr; 949 if (auto *C = dyn_cast<SCEVConstant>(StartSCEV)) { 950 StartValue = C->getValue(); 951 } else { 952 StartValue = PN->getIncomingValueForBlock(LoopPred); 953 assert(SE.getSCEV(StartValue) == StartSCEV && "inconsistent start value"); 954 } 955 956 DomTreeNode *DTN = DT.getNode(InLoopSucc); 957 auto IncUnsigned = SE.getMonotonicPredicateType(AR, CmpInst::ICMP_UGT); 958 auto IncSigned = SE.getMonotonicPredicateType(AR, CmpInst::ICMP_SGT); 959 bool MonotonicallyIncreasingUnsigned = 960 IncUnsigned && *IncUnsigned == ScalarEvolution::MonotonicallyIncreasing; 961 bool MonotonicallyIncreasingSigned = 962 IncSigned && *IncSigned == ScalarEvolution::MonotonicallyIncreasing; 963 // If SCEV guarantees that AR does not wrap, PN >= StartValue can be added 964 // unconditionally. 965 if (MonotonicallyIncreasingUnsigned) 966 WorkList.push_back( 967 FactOrCheck::getConditionFact(DTN, CmpInst::ICMP_UGE, PN, StartValue)); 968 if (MonotonicallyIncreasingSigned) 969 WorkList.push_back( 970 FactOrCheck::getConditionFact(DTN, CmpInst::ICMP_SGE, PN, StartValue)); 971 972 APInt StepOffset; 973 if (auto *C = dyn_cast<SCEVConstant>(AR->getStepRecurrence(SE))) 974 StepOffset = C->getAPInt(); 975 else 976 return; 977 978 // Make sure the bound B is loop-invariant. 979 if (!L->isLoopInvariant(B)) 980 return; 981 982 // Handle negative steps. 983 if (StepOffset.isNegative()) { 984 // TODO: Extend to allow steps > -1. 985 if (!(-StepOffset).isOne()) 986 return; 987 988 // AR may wrap. 989 // Add StartValue >= PN conditional on B <= StartValue which guarantees that 990 // the loop exits before wrapping with a step of -1. 991 WorkList.push_back(FactOrCheck::getConditionFact( 992 DTN, CmpInst::ICMP_UGE, StartValue, PN, 993 ConditionTy(CmpInst::ICMP_ULE, B, StartValue))); 994 WorkList.push_back(FactOrCheck::getConditionFact( 995 DTN, CmpInst::ICMP_SGE, StartValue, PN, 996 ConditionTy(CmpInst::ICMP_SLE, B, StartValue))); 997 // Add PN > B conditional on B <= StartValue which guarantees that the loop 998 // exits when reaching B with a step of -1. 999 WorkList.push_back(FactOrCheck::getConditionFact( 1000 DTN, CmpInst::ICMP_UGT, PN, B, 1001 ConditionTy(CmpInst::ICMP_ULE, B, StartValue))); 1002 WorkList.push_back(FactOrCheck::getConditionFact( 1003 DTN, CmpInst::ICMP_SGT, PN, B, 1004 ConditionTy(CmpInst::ICMP_SLE, B, StartValue))); 1005 return; 1006 } 1007 1008 // Make sure AR either steps by 1 or that the value we compare against is a 1009 // GEP based on the same start value and all offsets are a multiple of the 1010 // step size, to guarantee that the induction will reach the value. 1011 if (StepOffset.isZero() || StepOffset.isNegative()) 1012 return; 1013 1014 if (!StepOffset.isOne()) { 1015 // Check whether B-Start is known to be a multiple of StepOffset. 1016 const SCEV *BMinusStart = SE.getMinusSCEV(SE.getSCEV(B), StartSCEV); 1017 if (isa<SCEVCouldNotCompute>(BMinusStart) || 1018 !SE.getConstantMultiple(BMinusStart).urem(StepOffset).isZero()) 1019 return; 1020 } 1021 1022 // AR may wrap. Add PN >= StartValue conditional on StartValue <= B which 1023 // guarantees that the loop exits before wrapping in combination with the 1024 // restrictions on B and the step above. 1025 if (!MonotonicallyIncreasingUnsigned) 1026 WorkList.push_back(FactOrCheck::getConditionFact( 1027 DTN, CmpInst::ICMP_UGE, PN, StartValue, 1028 ConditionTy(CmpInst::ICMP_ULE, StartValue, B))); 1029 if (!MonotonicallyIncreasingSigned) 1030 WorkList.push_back(FactOrCheck::getConditionFact( 1031 DTN, CmpInst::ICMP_SGE, PN, StartValue, 1032 ConditionTy(CmpInst::ICMP_SLE, StartValue, B))); 1033 1034 WorkList.push_back(FactOrCheck::getConditionFact( 1035 DTN, CmpInst::ICMP_ULT, PN, B, 1036 ConditionTy(CmpInst::ICMP_ULE, StartValue, B))); 1037 WorkList.push_back(FactOrCheck::getConditionFact( 1038 DTN, CmpInst::ICMP_SLT, PN, B, 1039 ConditionTy(CmpInst::ICMP_SLE, StartValue, B))); 1040 1041 // Try to add condition from header to the dedicated exit blocks. When exiting 1042 // either with EQ or NE in the header, we know that the induction value must 1043 // be u<= B, as other exits may only exit earlier. 1044 assert(!StepOffset.isNegative() && "induction must be increasing"); 1045 assert((Pred == CmpInst::ICMP_EQ || Pred == CmpInst::ICMP_NE) && 1046 "unsupported predicate"); 1047 ConditionTy Precond = {CmpInst::ICMP_ULE, StartValue, B}; 1048 SmallVector<BasicBlock *> ExitBBs; 1049 L->getExitBlocks(ExitBBs); 1050 for (BasicBlock *EB : ExitBBs) { 1051 // Bail out on non-dedicated exits. 1052 if (DT.dominates(&BB, EB)) { 1053 WorkList.emplace_back(FactOrCheck::getConditionFact( 1054 DT.getNode(EB), CmpInst::ICMP_ULE, A, B, Precond)); 1055 } 1056 } 1057 } 1058 1059 void State::addInfoFor(BasicBlock &BB) { 1060 addInfoForInductions(BB); 1061 1062 // True as long as long as the current instruction is guaranteed to execute. 1063 bool GuaranteedToExecute = true; 1064 // Queue conditions and assumes. 1065 for (Instruction &I : BB) { 1066 if (auto Cmp = dyn_cast<ICmpInst>(&I)) { 1067 for (Use &U : Cmp->uses()) { 1068 auto *UserI = getContextInstForUse(U); 1069 auto *DTN = DT.getNode(UserI->getParent()); 1070 if (!DTN) 1071 continue; 1072 WorkList.push_back(FactOrCheck::getCheck(DTN, &U)); 1073 } 1074 continue; 1075 } 1076 1077 auto *II = dyn_cast<IntrinsicInst>(&I); 1078 Intrinsic::ID ID = II ? II->getIntrinsicID() : Intrinsic::not_intrinsic; 1079 switch (ID) { 1080 case Intrinsic::assume: { 1081 Value *A, *B; 1082 CmpInst::Predicate Pred; 1083 if (!match(I.getOperand(0), m_ICmp(Pred, m_Value(A), m_Value(B)))) 1084 break; 1085 if (GuaranteedToExecute) { 1086 // The assume is guaranteed to execute when BB is entered, hence Cond 1087 // holds on entry to BB. 1088 WorkList.emplace_back(FactOrCheck::getConditionFact( 1089 DT.getNode(I.getParent()), Pred, A, B)); 1090 } else { 1091 WorkList.emplace_back( 1092 FactOrCheck::getInstFact(DT.getNode(I.getParent()), &I)); 1093 } 1094 break; 1095 } 1096 // Enqueue ssub_with_overflow for simplification. 1097 case Intrinsic::ssub_with_overflow: 1098 case Intrinsic::ucmp: 1099 case Intrinsic::scmp: 1100 WorkList.push_back( 1101 FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I))); 1102 break; 1103 // Enqueue the intrinsics to add extra info. 1104 case Intrinsic::umin: 1105 case Intrinsic::umax: 1106 case Intrinsic::smin: 1107 case Intrinsic::smax: 1108 // TODO: handle llvm.abs as well 1109 WorkList.push_back( 1110 FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I))); 1111 // TODO: Check if it is possible to instead only added the min/max facts 1112 // when simplifying uses of the min/max intrinsics. 1113 if (!isGuaranteedNotToBePoison(&I)) 1114 break; 1115 [[fallthrough]]; 1116 case Intrinsic::abs: 1117 WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I)); 1118 break; 1119 } 1120 1121 GuaranteedToExecute &= isGuaranteedToTransferExecutionToSuccessor(&I); 1122 } 1123 1124 if (auto *Switch = dyn_cast<SwitchInst>(BB.getTerminator())) { 1125 for (auto &Case : Switch->cases()) { 1126 BasicBlock *Succ = Case.getCaseSuccessor(); 1127 Value *V = Case.getCaseValue(); 1128 if (!canAddSuccessor(BB, Succ)) 1129 continue; 1130 WorkList.emplace_back(FactOrCheck::getConditionFact( 1131 DT.getNode(Succ), CmpInst::ICMP_EQ, Switch->getCondition(), V)); 1132 } 1133 return; 1134 } 1135 1136 auto *Br = dyn_cast<BranchInst>(BB.getTerminator()); 1137 if (!Br || !Br->isConditional()) 1138 return; 1139 1140 Value *Cond = Br->getCondition(); 1141 1142 // If the condition is a chain of ORs/AND and the successor only has the 1143 // current block as predecessor, queue conditions for the successor. 1144 Value *Op0, *Op1; 1145 if (match(Cond, m_LogicalOr(m_Value(Op0), m_Value(Op1))) || 1146 match(Cond, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) { 1147 bool IsOr = match(Cond, m_LogicalOr()); 1148 bool IsAnd = match(Cond, m_LogicalAnd()); 1149 // If there's a select that matches both AND and OR, we need to commit to 1150 // one of the options. Arbitrarily pick OR. 1151 if (IsOr && IsAnd) 1152 IsAnd = false; 1153 1154 BasicBlock *Successor = Br->getSuccessor(IsOr ? 1 : 0); 1155 if (canAddSuccessor(BB, Successor)) { 1156 SmallVector<Value *> CondWorkList; 1157 SmallPtrSet<Value *, 8> SeenCond; 1158 auto QueueValue = [&CondWorkList, &SeenCond](Value *V) { 1159 if (SeenCond.insert(V).second) 1160 CondWorkList.push_back(V); 1161 }; 1162 QueueValue(Op1); 1163 QueueValue(Op0); 1164 while (!CondWorkList.empty()) { 1165 Value *Cur = CondWorkList.pop_back_val(); 1166 if (auto *Cmp = dyn_cast<ICmpInst>(Cur)) { 1167 WorkList.emplace_back(FactOrCheck::getConditionFact( 1168 DT.getNode(Successor), 1169 IsOr ? CmpInst::getInversePredicate(Cmp->getPredicate()) 1170 : Cmp->getPredicate(), 1171 Cmp->getOperand(0), Cmp->getOperand(1))); 1172 continue; 1173 } 1174 if (IsOr && match(Cur, m_LogicalOr(m_Value(Op0), m_Value(Op1)))) { 1175 QueueValue(Op1); 1176 QueueValue(Op0); 1177 continue; 1178 } 1179 if (IsAnd && match(Cur, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) { 1180 QueueValue(Op1); 1181 QueueValue(Op0); 1182 continue; 1183 } 1184 } 1185 } 1186 return; 1187 } 1188 1189 auto *CmpI = dyn_cast<ICmpInst>(Br->getCondition()); 1190 if (!CmpI) 1191 return; 1192 if (canAddSuccessor(BB, Br->getSuccessor(0))) 1193 WorkList.emplace_back(FactOrCheck::getConditionFact( 1194 DT.getNode(Br->getSuccessor(0)), CmpI->getPredicate(), 1195 CmpI->getOperand(0), CmpI->getOperand(1))); 1196 if (canAddSuccessor(BB, Br->getSuccessor(1))) 1197 WorkList.emplace_back(FactOrCheck::getConditionFact( 1198 DT.getNode(Br->getSuccessor(1)), 1199 CmpInst::getInversePredicate(CmpI->getPredicate()), CmpI->getOperand(0), 1200 CmpI->getOperand(1))); 1201 } 1202 1203 #ifndef NDEBUG 1204 static void dumpUnpackedICmp(raw_ostream &OS, ICmpInst::Predicate Pred, 1205 Value *LHS, Value *RHS) { 1206 OS << "icmp " << Pred << ' '; 1207 LHS->printAsOperand(OS, /*PrintType=*/true); 1208 OS << ", "; 1209 RHS->printAsOperand(OS, /*PrintType=*/false); 1210 } 1211 #endif 1212 1213 namespace { 1214 /// Helper to keep track of a condition and if it should be treated as negated 1215 /// for reproducer construction. 1216 /// Pred == Predicate::BAD_ICMP_PREDICATE indicates that this entry is a 1217 /// placeholder to keep the ReproducerCondStack in sync with DFSInStack. 1218 struct ReproducerEntry { 1219 ICmpInst::Predicate Pred; 1220 Value *LHS; 1221 Value *RHS; 1222 1223 ReproducerEntry(ICmpInst::Predicate Pred, Value *LHS, Value *RHS) 1224 : Pred(Pred), LHS(LHS), RHS(RHS) {} 1225 }; 1226 } // namespace 1227 1228 /// Helper function to generate a reproducer function for simplifying \p Cond. 1229 /// The reproducer function contains a series of @llvm.assume calls, one for 1230 /// each condition in \p Stack. For each condition, the operand instruction are 1231 /// cloned until we reach operands that have an entry in \p Value2Index. Those 1232 /// will then be added as function arguments. \p DT is used to order cloned 1233 /// instructions. The reproducer function will get added to \p M, if it is 1234 /// non-null. Otherwise no reproducer function is generated. 1235 static void generateReproducer(CmpInst *Cond, Module *M, 1236 ArrayRef<ReproducerEntry> Stack, 1237 ConstraintInfo &Info, DominatorTree &DT) { 1238 if (!M) 1239 return; 1240 1241 LLVMContext &Ctx = Cond->getContext(); 1242 1243 LLVM_DEBUG(dbgs() << "Creating reproducer for " << *Cond << "\n"); 1244 1245 ValueToValueMapTy Old2New; 1246 SmallVector<Value *> Args; 1247 SmallPtrSet<Value *, 8> Seen; 1248 // Traverse Cond and its operands recursively until we reach a value that's in 1249 // Value2Index or not an instruction, or not a operation that 1250 // ConstraintElimination can decompose. Such values will be considered as 1251 // external inputs to the reproducer, they are collected and added as function 1252 // arguments later. 1253 auto CollectArguments = [&](ArrayRef<Value *> Ops, bool IsSigned) { 1254 auto &Value2Index = Info.getValue2Index(IsSigned); 1255 SmallVector<Value *, 4> WorkList(Ops); 1256 while (!WorkList.empty()) { 1257 Value *V = WorkList.pop_back_val(); 1258 if (!Seen.insert(V).second) 1259 continue; 1260 if (Old2New.find(V) != Old2New.end()) 1261 continue; 1262 if (isa<Constant>(V)) 1263 continue; 1264 1265 auto *I = dyn_cast<Instruction>(V); 1266 if (Value2Index.contains(V) || !I || 1267 !isa<CmpInst, BinaryOperator, GEPOperator, CastInst>(V)) { 1268 Old2New[V] = V; 1269 Args.push_back(V); 1270 LLVM_DEBUG(dbgs() << " found external input " << *V << "\n"); 1271 } else { 1272 append_range(WorkList, I->operands()); 1273 } 1274 } 1275 }; 1276 1277 for (auto &Entry : Stack) 1278 if (Entry.Pred != ICmpInst::BAD_ICMP_PREDICATE) 1279 CollectArguments({Entry.LHS, Entry.RHS}, ICmpInst::isSigned(Entry.Pred)); 1280 CollectArguments(Cond, ICmpInst::isSigned(Cond->getPredicate())); 1281 1282 SmallVector<Type *> ParamTys; 1283 for (auto *P : Args) 1284 ParamTys.push_back(P->getType()); 1285 1286 FunctionType *FTy = FunctionType::get(Cond->getType(), ParamTys, 1287 /*isVarArg=*/false); 1288 Function *F = Function::Create(FTy, Function::ExternalLinkage, 1289 Cond->getModule()->getName() + 1290 Cond->getFunction()->getName() + "repro", 1291 M); 1292 // Add arguments to the reproducer function for each external value collected. 1293 for (unsigned I = 0; I < Args.size(); ++I) { 1294 F->getArg(I)->setName(Args[I]->getName()); 1295 Old2New[Args[I]] = F->getArg(I); 1296 } 1297 1298 BasicBlock *Entry = BasicBlock::Create(Ctx, "entry", F); 1299 IRBuilder<> Builder(Entry); 1300 Builder.CreateRet(Builder.getTrue()); 1301 Builder.SetInsertPoint(Entry->getTerminator()); 1302 1303 // Clone instructions in \p Ops and their operands recursively until reaching 1304 // an value in Value2Index (external input to the reproducer). Update Old2New 1305 // mapping for the original and cloned instructions. Sort instructions to 1306 // clone by dominance, then insert the cloned instructions in the function. 1307 auto CloneInstructions = [&](ArrayRef<Value *> Ops, bool IsSigned) { 1308 SmallVector<Value *, 4> WorkList(Ops); 1309 SmallVector<Instruction *> ToClone; 1310 auto &Value2Index = Info.getValue2Index(IsSigned); 1311 while (!WorkList.empty()) { 1312 Value *V = WorkList.pop_back_val(); 1313 if (Old2New.find(V) != Old2New.end()) 1314 continue; 1315 1316 auto *I = dyn_cast<Instruction>(V); 1317 if (!Value2Index.contains(V) && I) { 1318 Old2New[V] = nullptr; 1319 ToClone.push_back(I); 1320 append_range(WorkList, I->operands()); 1321 } 1322 } 1323 1324 sort(ToClone, 1325 [&DT](Instruction *A, Instruction *B) { return DT.dominates(A, B); }); 1326 for (Instruction *I : ToClone) { 1327 Instruction *Cloned = I->clone(); 1328 Old2New[I] = Cloned; 1329 Old2New[I]->setName(I->getName()); 1330 Cloned->insertBefore(&*Builder.GetInsertPoint()); 1331 Cloned->dropUnknownNonDebugMetadata(); 1332 Cloned->setDebugLoc({}); 1333 } 1334 }; 1335 1336 // Materialize the assumptions for the reproducer using the entries in Stack. 1337 // That is, first clone the operands of the condition recursively until we 1338 // reach an external input to the reproducer and add them to the reproducer 1339 // function. Then add an ICmp for the condition (with the inverse predicate if 1340 // the entry is negated) and an assert using the ICmp. 1341 for (auto &Entry : Stack) { 1342 if (Entry.Pred == ICmpInst::BAD_ICMP_PREDICATE) 1343 continue; 1344 1345 LLVM_DEBUG(dbgs() << " Materializing assumption "; 1346 dumpUnpackedICmp(dbgs(), Entry.Pred, Entry.LHS, Entry.RHS); 1347 dbgs() << "\n"); 1348 CloneInstructions({Entry.LHS, Entry.RHS}, CmpInst::isSigned(Entry.Pred)); 1349 1350 auto *Cmp = Builder.CreateICmp(Entry.Pred, Entry.LHS, Entry.RHS); 1351 Builder.CreateAssumption(Cmp); 1352 } 1353 1354 // Finally, clone the condition to reproduce and remap instruction operands in 1355 // the reproducer using Old2New. 1356 CloneInstructions(Cond, CmpInst::isSigned(Cond->getPredicate())); 1357 Entry->getTerminator()->setOperand(0, Cond); 1358 remapInstructionsInBlocks({Entry}, Old2New); 1359 1360 assert(!verifyFunction(*F, &dbgs())); 1361 } 1362 1363 static std::optional<bool> checkCondition(CmpInst::Predicate Pred, Value *A, 1364 Value *B, Instruction *CheckInst, 1365 ConstraintInfo &Info) { 1366 LLVM_DEBUG(dbgs() << "Checking " << *CheckInst << "\n"); 1367 1368 auto R = Info.getConstraintForSolving(Pred, A, B); 1369 if (R.empty() || !R.isValid(Info)){ 1370 LLVM_DEBUG(dbgs() << " failed to decompose condition\n"); 1371 return std::nullopt; 1372 } 1373 1374 auto &CSToUse = Info.getCS(R.IsSigned); 1375 1376 // If there was extra information collected during decomposition, apply 1377 // it now and remove it immediately once we are done with reasoning 1378 // about the constraint. 1379 for (auto &Row : R.ExtraInfo) 1380 CSToUse.addVariableRow(Row); 1381 auto InfoRestorer = make_scope_exit([&]() { 1382 for (unsigned I = 0; I < R.ExtraInfo.size(); ++I) 1383 CSToUse.popLastConstraint(); 1384 }); 1385 1386 if (auto ImpliedCondition = R.isImpliedBy(CSToUse)) { 1387 if (!DebugCounter::shouldExecute(EliminatedCounter)) 1388 return std::nullopt; 1389 1390 LLVM_DEBUG({ 1391 dbgs() << "Condition "; 1392 dumpUnpackedICmp( 1393 dbgs(), *ImpliedCondition ? Pred : CmpInst::getInversePredicate(Pred), 1394 A, B); 1395 dbgs() << " implied by dominating constraints\n"; 1396 CSToUse.dump(); 1397 }); 1398 return ImpliedCondition; 1399 } 1400 1401 return std::nullopt; 1402 } 1403 1404 static bool checkAndReplaceCondition( 1405 CmpInst *Cmp, ConstraintInfo &Info, unsigned NumIn, unsigned NumOut, 1406 Instruction *ContextInst, Module *ReproducerModule, 1407 ArrayRef<ReproducerEntry> ReproducerCondStack, DominatorTree &DT, 1408 SmallVectorImpl<Instruction *> &ToRemove) { 1409 auto ReplaceCmpWithConstant = [&](CmpInst *Cmp, bool IsTrue) { 1410 generateReproducer(Cmp, ReproducerModule, ReproducerCondStack, Info, DT); 1411 Constant *ConstantC = ConstantInt::getBool( 1412 CmpInst::makeCmpResultType(Cmp->getType()), IsTrue); 1413 Cmp->replaceUsesWithIf(ConstantC, [&DT, NumIn, NumOut, 1414 ContextInst](Use &U) { 1415 auto *UserI = getContextInstForUse(U); 1416 auto *DTN = DT.getNode(UserI->getParent()); 1417 if (!DTN || DTN->getDFSNumIn() < NumIn || DTN->getDFSNumOut() > NumOut) 1418 return false; 1419 if (UserI->getParent() == ContextInst->getParent() && 1420 UserI->comesBefore(ContextInst)) 1421 return false; 1422 1423 // Conditions in an assume trivially simplify to true. Skip uses 1424 // in assume calls to not destroy the available information. 1425 auto *II = dyn_cast<IntrinsicInst>(U.getUser()); 1426 return !II || II->getIntrinsicID() != Intrinsic::assume; 1427 }); 1428 NumCondsRemoved++; 1429 if (Cmp->use_empty()) 1430 ToRemove.push_back(Cmp); 1431 return true; 1432 }; 1433 1434 if (auto ImpliedCondition = 1435 checkCondition(Cmp->getPredicate(), Cmp->getOperand(0), 1436 Cmp->getOperand(1), Cmp, Info)) 1437 return ReplaceCmpWithConstant(Cmp, *ImpliedCondition); 1438 return false; 1439 } 1440 1441 static bool checkAndReplaceMinMax(MinMaxIntrinsic *MinMax, ConstraintInfo &Info, 1442 SmallVectorImpl<Instruction *> &ToRemove) { 1443 auto ReplaceMinMaxWithOperand = [&](MinMaxIntrinsic *MinMax, bool UseLHS) { 1444 // TODO: generate reproducer for min/max. 1445 MinMax->replaceAllUsesWith(MinMax->getOperand(UseLHS ? 0 : 1)); 1446 ToRemove.push_back(MinMax); 1447 return true; 1448 }; 1449 1450 ICmpInst::Predicate Pred = 1451 ICmpInst::getNonStrictPredicate(MinMax->getPredicate()); 1452 if (auto ImpliedCondition = checkCondition( 1453 Pred, MinMax->getOperand(0), MinMax->getOperand(1), MinMax, Info)) 1454 return ReplaceMinMaxWithOperand(MinMax, *ImpliedCondition); 1455 if (auto ImpliedCondition = checkCondition( 1456 Pred, MinMax->getOperand(1), MinMax->getOperand(0), MinMax, Info)) 1457 return ReplaceMinMaxWithOperand(MinMax, !*ImpliedCondition); 1458 return false; 1459 } 1460 1461 static bool checkAndReplaceCmp(CmpIntrinsic *I, ConstraintInfo &Info, 1462 SmallVectorImpl<Instruction *> &ToRemove) { 1463 Value *LHS = I->getOperand(0); 1464 Value *RHS = I->getOperand(1); 1465 if (checkCondition(I->getGTPredicate(), LHS, RHS, I, Info).value_or(false)) { 1466 I->replaceAllUsesWith(ConstantInt::get(I->getType(), 1)); 1467 ToRemove.push_back(I); 1468 return true; 1469 } 1470 if (checkCondition(I->getLTPredicate(), LHS, RHS, I, Info).value_or(false)) { 1471 I->replaceAllUsesWith(ConstantInt::getSigned(I->getType(), -1)); 1472 ToRemove.push_back(I); 1473 return true; 1474 } 1475 if (checkCondition(ICmpInst::ICMP_EQ, LHS, RHS, I, Info).value_or(false)) { 1476 I->replaceAllUsesWith(ConstantInt::get(I->getType(), 0)); 1477 ToRemove.push_back(I); 1478 return true; 1479 } 1480 return false; 1481 } 1482 1483 static void 1484 removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info, 1485 Module *ReproducerModule, 1486 SmallVectorImpl<ReproducerEntry> &ReproducerCondStack, 1487 SmallVectorImpl<StackEntry> &DFSInStack) { 1488 Info.popLastConstraint(E.IsSigned); 1489 // Remove variables in the system that went out of scope. 1490 auto &Mapping = Info.getValue2Index(E.IsSigned); 1491 for (Value *V : E.ValuesToRelease) 1492 Mapping.erase(V); 1493 Info.popLastNVariables(E.IsSigned, E.ValuesToRelease.size()); 1494 DFSInStack.pop_back(); 1495 if (ReproducerModule) 1496 ReproducerCondStack.pop_back(); 1497 } 1498 1499 /// Check if either the first condition of an AND or OR is implied by the 1500 /// (negated in case of OR) second condition or vice versa. 1501 static bool checkOrAndOpImpliedByOther( 1502 FactOrCheck &CB, ConstraintInfo &Info, Module *ReproducerModule, 1503 SmallVectorImpl<ReproducerEntry> &ReproducerCondStack, 1504 SmallVectorImpl<StackEntry> &DFSInStack) { 1505 Instruction *JoinOp = CB.getContextInst(); 1506 CmpInst *CmpToCheck = cast<CmpInst>(CB.getInstructionToSimplify()); 1507 unsigned OtherOpIdx = JoinOp->getOperand(0) == CmpToCheck ? 1 : 0; 1508 1509 // Don't try to simplify the first condition of a select by the second, as 1510 // this may make the select more poisonous than the original one. 1511 // TODO: check if the first operand may be poison. 1512 if (OtherOpIdx != 0 && isa<SelectInst>(JoinOp)) 1513 return false; 1514 1515 unsigned OldSize = DFSInStack.size(); 1516 auto InfoRestorer = make_scope_exit([&]() { 1517 // Remove entries again. 1518 while (OldSize < DFSInStack.size()) { 1519 StackEntry E = DFSInStack.back(); 1520 removeEntryFromStack(E, Info, ReproducerModule, ReproducerCondStack, 1521 DFSInStack); 1522 } 1523 }); 1524 bool IsOr = match(JoinOp, m_LogicalOr()); 1525 SmallVector<Value *, 4> Worklist({JoinOp->getOperand(OtherOpIdx)}); 1526 // Do a traversal of the AND/OR tree to add facts from leaf compares. 1527 while (!Worklist.empty()) { 1528 Value *Val = Worklist.pop_back_val(); 1529 Value *LHS, *RHS; 1530 ICmpInst::Predicate Pred; 1531 if (match(Val, m_ICmp(Pred, m_Value(LHS), m_Value(RHS)))) { 1532 // For OR, check if the negated condition implies CmpToCheck. 1533 if (IsOr) 1534 Pred = CmpInst::getInversePredicate(Pred); 1535 // Optimistically add fact from the other compares in the AND/OR. 1536 Info.addFact(Pred, LHS, RHS, CB.NumIn, CB.NumOut, DFSInStack); 1537 continue; 1538 } 1539 if (IsOr ? match(Val, m_LogicalOr(m_Value(LHS), m_Value(RHS))) 1540 : match(Val, m_LogicalAnd(m_Value(LHS), m_Value(RHS)))) { 1541 Worklist.push_back(LHS); 1542 Worklist.push_back(RHS); 1543 } 1544 } 1545 if (OldSize == DFSInStack.size()) 1546 return false; 1547 1548 // Check if the second condition can be simplified now. 1549 if (auto ImpliedCondition = 1550 checkCondition(CmpToCheck->getPredicate(), CmpToCheck->getOperand(0), 1551 CmpToCheck->getOperand(1), CmpToCheck, Info)) { 1552 if (IsOr && isa<SelectInst>(JoinOp)) { 1553 JoinOp->setOperand( 1554 OtherOpIdx == 0 ? 2 : 0, 1555 ConstantInt::getBool(JoinOp->getType(), *ImpliedCondition)); 1556 } else 1557 JoinOp->setOperand( 1558 1 - OtherOpIdx, 1559 ConstantInt::getBool(JoinOp->getType(), *ImpliedCondition)); 1560 1561 return true; 1562 } 1563 1564 return false; 1565 } 1566 1567 void ConstraintInfo::addFact(CmpInst::Predicate Pred, Value *A, Value *B, 1568 unsigned NumIn, unsigned NumOut, 1569 SmallVectorImpl<StackEntry> &DFSInStack) { 1570 // If the constraint has a pre-condition, skip the constraint if it does not 1571 // hold. 1572 SmallVector<Value *> NewVariables; 1573 auto R = getConstraint(Pred, A, B, NewVariables); 1574 1575 // TODO: Support non-equality for facts as well. 1576 if (!R.isValid(*this) || R.isNe()) 1577 return; 1578 1579 LLVM_DEBUG(dbgs() << "Adding '"; dumpUnpackedICmp(dbgs(), Pred, A, B); 1580 dbgs() << "'\n"); 1581 bool Added = false; 1582 auto &CSToUse = getCS(R.IsSigned); 1583 if (R.Coefficients.empty()) 1584 return; 1585 1586 Added |= CSToUse.addVariableRowFill(R.Coefficients); 1587 1588 // If R has been added to the system, add the new variables and queue it for 1589 // removal once it goes out-of-scope. 1590 if (Added) { 1591 SmallVector<Value *, 2> ValuesToRelease; 1592 auto &Value2Index = getValue2Index(R.IsSigned); 1593 for (Value *V : NewVariables) { 1594 Value2Index.insert({V, Value2Index.size() + 1}); 1595 ValuesToRelease.push_back(V); 1596 } 1597 1598 LLVM_DEBUG({ 1599 dbgs() << " constraint: "; 1600 dumpConstraint(R.Coefficients, getValue2Index(R.IsSigned)); 1601 dbgs() << "\n"; 1602 }); 1603 1604 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned, 1605 std::move(ValuesToRelease)); 1606 1607 if (!R.IsSigned) { 1608 for (Value *V : NewVariables) { 1609 ConstraintTy VarPos(SmallVector<int64_t, 8>(Value2Index.size() + 1, 0), 1610 false, false, false); 1611 VarPos.Coefficients[Value2Index[V]] = -1; 1612 CSToUse.addVariableRow(VarPos.Coefficients); 1613 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned, 1614 SmallVector<Value *, 2>()); 1615 } 1616 } 1617 1618 if (R.isEq()) { 1619 // Also add the inverted constraint for equality constraints. 1620 for (auto &Coeff : R.Coefficients) 1621 Coeff *= -1; 1622 CSToUse.addVariableRowFill(R.Coefficients); 1623 1624 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned, 1625 SmallVector<Value *, 2>()); 1626 } 1627 } 1628 } 1629 1630 static bool replaceSubOverflowUses(IntrinsicInst *II, Value *A, Value *B, 1631 SmallVectorImpl<Instruction *> &ToRemove) { 1632 bool Changed = false; 1633 IRBuilder<> Builder(II->getParent(), II->getIterator()); 1634 Value *Sub = nullptr; 1635 for (User *U : make_early_inc_range(II->users())) { 1636 if (match(U, m_ExtractValue<0>(m_Value()))) { 1637 if (!Sub) 1638 Sub = Builder.CreateSub(A, B); 1639 U->replaceAllUsesWith(Sub); 1640 Changed = true; 1641 } else if (match(U, m_ExtractValue<1>(m_Value()))) { 1642 U->replaceAllUsesWith(Builder.getFalse()); 1643 Changed = true; 1644 } else 1645 continue; 1646 1647 if (U->use_empty()) { 1648 auto *I = cast<Instruction>(U); 1649 ToRemove.push_back(I); 1650 I->setOperand(0, PoisonValue::get(II->getType())); 1651 Changed = true; 1652 } 1653 } 1654 1655 if (II->use_empty()) { 1656 II->eraseFromParent(); 1657 Changed = true; 1658 } 1659 return Changed; 1660 } 1661 1662 static bool 1663 tryToSimplifyOverflowMath(IntrinsicInst *II, ConstraintInfo &Info, 1664 SmallVectorImpl<Instruction *> &ToRemove) { 1665 auto DoesConditionHold = [](CmpInst::Predicate Pred, Value *A, Value *B, 1666 ConstraintInfo &Info) { 1667 auto R = Info.getConstraintForSolving(Pred, A, B); 1668 if (R.size() < 2 || !R.isValid(Info)) 1669 return false; 1670 1671 auto &CSToUse = Info.getCS(R.IsSigned); 1672 return CSToUse.isConditionImplied(R.Coefficients); 1673 }; 1674 1675 bool Changed = false; 1676 if (II->getIntrinsicID() == Intrinsic::ssub_with_overflow) { 1677 // If A s>= B && B s>= 0, ssub.with.overflow(a, b) should not overflow and 1678 // can be simplified to a regular sub. 1679 Value *A = II->getArgOperand(0); 1680 Value *B = II->getArgOperand(1); 1681 if (!DoesConditionHold(CmpInst::ICMP_SGE, A, B, Info) || 1682 !DoesConditionHold(CmpInst::ICMP_SGE, B, 1683 ConstantInt::get(A->getType(), 0), Info)) 1684 return false; 1685 Changed = replaceSubOverflowUses(II, A, B, ToRemove); 1686 } 1687 return Changed; 1688 } 1689 1690 static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI, 1691 ScalarEvolution &SE, 1692 OptimizationRemarkEmitter &ORE) { 1693 bool Changed = false; 1694 DT.updateDFSNumbers(); 1695 SmallVector<Value *> FunctionArgs; 1696 for (Value &Arg : F.args()) 1697 FunctionArgs.push_back(&Arg); 1698 ConstraintInfo Info(F.getDataLayout(), FunctionArgs); 1699 State S(DT, LI, SE); 1700 std::unique_ptr<Module> ReproducerModule( 1701 DumpReproducers ? new Module(F.getName(), F.getContext()) : nullptr); 1702 1703 // First, collect conditions implied by branches and blocks with their 1704 // Dominator DFS in and out numbers. 1705 for (BasicBlock &BB : F) { 1706 if (!DT.getNode(&BB)) 1707 continue; 1708 S.addInfoFor(BB); 1709 } 1710 1711 // Next, sort worklist by dominance, so that dominating conditions to check 1712 // and facts come before conditions and facts dominated by them. If a 1713 // condition to check and a fact have the same numbers, conditional facts come 1714 // first. Assume facts and checks are ordered according to their relative 1715 // order in the containing basic block. Also make sure conditions with 1716 // constant operands come before conditions without constant operands. This 1717 // increases the effectiveness of the current signed <-> unsigned fact 1718 // transfer logic. 1719 stable_sort(S.WorkList, [](const FactOrCheck &A, const FactOrCheck &B) { 1720 auto HasNoConstOp = [](const FactOrCheck &B) { 1721 Value *V0 = B.isConditionFact() ? B.Cond.Op0 : B.Inst->getOperand(0); 1722 Value *V1 = B.isConditionFact() ? B.Cond.Op1 : B.Inst->getOperand(1); 1723 return !isa<ConstantInt>(V0) && !isa<ConstantInt>(V1); 1724 }; 1725 // If both entries have the same In numbers, conditional facts come first. 1726 // Otherwise use the relative order in the basic block. 1727 if (A.NumIn == B.NumIn) { 1728 if (A.isConditionFact() && B.isConditionFact()) { 1729 bool NoConstOpA = HasNoConstOp(A); 1730 bool NoConstOpB = HasNoConstOp(B); 1731 return NoConstOpA < NoConstOpB; 1732 } 1733 if (A.isConditionFact()) 1734 return true; 1735 if (B.isConditionFact()) 1736 return false; 1737 auto *InstA = A.getContextInst(); 1738 auto *InstB = B.getContextInst(); 1739 return InstA->comesBefore(InstB); 1740 } 1741 return A.NumIn < B.NumIn; 1742 }); 1743 1744 SmallVector<Instruction *> ToRemove; 1745 1746 // Finally, process ordered worklist and eliminate implied conditions. 1747 SmallVector<StackEntry, 16> DFSInStack; 1748 SmallVector<ReproducerEntry> ReproducerCondStack; 1749 for (FactOrCheck &CB : S.WorkList) { 1750 // First, pop entries from the stack that are out-of-scope for CB. Remove 1751 // the corresponding entry from the constraint system. 1752 while (!DFSInStack.empty()) { 1753 auto &E = DFSInStack.back(); 1754 LLVM_DEBUG(dbgs() << "Top of stack : " << E.NumIn << " " << E.NumOut 1755 << "\n"); 1756 LLVM_DEBUG(dbgs() << "CB: " << CB.NumIn << " " << CB.NumOut << "\n"); 1757 assert(E.NumIn <= CB.NumIn); 1758 if (CB.NumOut <= E.NumOut) 1759 break; 1760 LLVM_DEBUG({ 1761 dbgs() << "Removing "; 1762 dumpConstraint(Info.getCS(E.IsSigned).getLastConstraint(), 1763 Info.getValue2Index(E.IsSigned)); 1764 dbgs() << "\n"; 1765 }); 1766 removeEntryFromStack(E, Info, ReproducerModule.get(), ReproducerCondStack, 1767 DFSInStack); 1768 } 1769 1770 // For a block, check if any CmpInsts become known based on the current set 1771 // of constraints. 1772 if (CB.isCheck()) { 1773 Instruction *Inst = CB.getInstructionToSimplify(); 1774 if (!Inst) 1775 continue; 1776 LLVM_DEBUG(dbgs() << "Processing condition to simplify: " << *Inst 1777 << "\n"); 1778 if (auto *II = dyn_cast<WithOverflowInst>(Inst)) { 1779 Changed |= tryToSimplifyOverflowMath(II, Info, ToRemove); 1780 } else if (auto *Cmp = dyn_cast<ICmpInst>(Inst)) { 1781 bool Simplified = checkAndReplaceCondition( 1782 Cmp, Info, CB.NumIn, CB.NumOut, CB.getContextInst(), 1783 ReproducerModule.get(), ReproducerCondStack, S.DT, ToRemove); 1784 if (!Simplified && 1785 match(CB.getContextInst(), m_LogicalOp(m_Value(), m_Value()))) { 1786 Simplified = 1787 checkOrAndOpImpliedByOther(CB, Info, ReproducerModule.get(), 1788 ReproducerCondStack, DFSInStack); 1789 } 1790 Changed |= Simplified; 1791 } else if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(Inst)) { 1792 Changed |= checkAndReplaceMinMax(MinMax, Info, ToRemove); 1793 } else if (auto *CmpIntr = dyn_cast<CmpIntrinsic>(Inst)) { 1794 Changed |= checkAndReplaceCmp(CmpIntr, Info, ToRemove); 1795 } 1796 continue; 1797 } 1798 1799 auto AddFact = [&](CmpInst::Predicate Pred, Value *A, Value *B) { 1800 LLVM_DEBUG(dbgs() << "Processing fact to add to the system: "; 1801 dumpUnpackedICmp(dbgs(), Pred, A, B); dbgs() << "\n"); 1802 if (Info.getCS(CmpInst::isSigned(Pred)).size() > MaxRows) { 1803 LLVM_DEBUG( 1804 dbgs() 1805 << "Skip adding constraint because system has too many rows.\n"); 1806 return; 1807 } 1808 1809 Info.addFact(Pred, A, B, CB.NumIn, CB.NumOut, DFSInStack); 1810 if (ReproducerModule && DFSInStack.size() > ReproducerCondStack.size()) 1811 ReproducerCondStack.emplace_back(Pred, A, B); 1812 1813 Info.transferToOtherSystem(Pred, A, B, CB.NumIn, CB.NumOut, DFSInStack); 1814 if (ReproducerModule && DFSInStack.size() > ReproducerCondStack.size()) { 1815 // Add dummy entries to ReproducerCondStack to keep it in sync with 1816 // DFSInStack. 1817 for (unsigned I = 0, 1818 E = (DFSInStack.size() - ReproducerCondStack.size()); 1819 I < E; ++I) { 1820 ReproducerCondStack.emplace_back(ICmpInst::BAD_ICMP_PREDICATE, 1821 nullptr, nullptr); 1822 } 1823 } 1824 }; 1825 1826 ICmpInst::Predicate Pred; 1827 if (!CB.isConditionFact()) { 1828 Value *X; 1829 if (match(CB.Inst, m_Intrinsic<Intrinsic::abs>(m_Value(X)))) { 1830 // If is_int_min_poison is true then we may assume llvm.abs >= 0. 1831 if (cast<ConstantInt>(CB.Inst->getOperand(1))->isOne()) 1832 AddFact(CmpInst::ICMP_SGE, CB.Inst, 1833 ConstantInt::get(CB.Inst->getType(), 0)); 1834 AddFact(CmpInst::ICMP_SGE, CB.Inst, X); 1835 continue; 1836 } 1837 1838 if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(CB.Inst)) { 1839 Pred = ICmpInst::getNonStrictPredicate(MinMax->getPredicate()); 1840 AddFact(Pred, MinMax, MinMax->getLHS()); 1841 AddFact(Pred, MinMax, MinMax->getRHS()); 1842 continue; 1843 } 1844 } 1845 1846 Value *A = nullptr, *B = nullptr; 1847 if (CB.isConditionFact()) { 1848 Pred = CB.Cond.Pred; 1849 A = CB.Cond.Op0; 1850 B = CB.Cond.Op1; 1851 if (CB.DoesHold.Pred != CmpInst::BAD_ICMP_PREDICATE && 1852 !Info.doesHold(CB.DoesHold.Pred, CB.DoesHold.Op0, CB.DoesHold.Op1)) { 1853 LLVM_DEBUG({ 1854 dbgs() << "Not adding fact "; 1855 dumpUnpackedICmp(dbgs(), Pred, A, B); 1856 dbgs() << " because precondition "; 1857 dumpUnpackedICmp(dbgs(), CB.DoesHold.Pred, CB.DoesHold.Op0, 1858 CB.DoesHold.Op1); 1859 dbgs() << " does not hold.\n"; 1860 }); 1861 continue; 1862 } 1863 } else { 1864 bool Matched = match(CB.Inst, m_Intrinsic<Intrinsic::assume>( 1865 m_ICmp(Pred, m_Value(A), m_Value(B)))); 1866 (void)Matched; 1867 assert(Matched && "Must have an assume intrinsic with a icmp operand"); 1868 } 1869 AddFact(Pred, A, B); 1870 } 1871 1872 if (ReproducerModule && !ReproducerModule->functions().empty()) { 1873 std::string S; 1874 raw_string_ostream StringS(S); 1875 ReproducerModule->print(StringS, nullptr); 1876 OptimizationRemark Rem(DEBUG_TYPE, "Reproducer", &F); 1877 Rem << ore::NV("module") << S; 1878 ORE.emit(Rem); 1879 } 1880 1881 #ifndef NDEBUG 1882 unsigned SignedEntries = 1883 count_if(DFSInStack, [](const StackEntry &E) { return E.IsSigned; }); 1884 assert(Info.getCS(false).size() - FunctionArgs.size() == 1885 DFSInStack.size() - SignedEntries && 1886 "updates to CS and DFSInStack are out of sync"); 1887 assert(Info.getCS(true).size() == SignedEntries && 1888 "updates to CS and DFSInStack are out of sync"); 1889 #endif 1890 1891 for (Instruction *I : ToRemove) 1892 I->eraseFromParent(); 1893 return Changed; 1894 } 1895 1896 PreservedAnalyses ConstraintEliminationPass::run(Function &F, 1897 FunctionAnalysisManager &AM) { 1898 auto &DT = AM.getResult<DominatorTreeAnalysis>(F); 1899 auto &LI = AM.getResult<LoopAnalysis>(F); 1900 auto &SE = AM.getResult<ScalarEvolutionAnalysis>(F); 1901 auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F); 1902 if (!eliminateConstraints(F, DT, LI, SE, ORE)) 1903 return PreservedAnalyses::all(); 1904 1905 PreservedAnalyses PA; 1906 PA.preserve<DominatorTreeAnalysis>(); 1907 PA.preserve<LoopAnalysis>(); 1908 PA.preserve<ScalarEvolutionAnalysis>(); 1909 PA.preserveSet<CFGAnalyses>(); 1910 return PA; 1911 } 1912