1 //===- GuardWidening.cpp - ---- Guard widening ----------------------------===// 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 // This file implements the guard widening pass. The semantics of the 10 // @llvm.experimental.guard intrinsic lets LLVM transform it so that it fails 11 // more often that it did before the transform. This optimization is called 12 // "widening" and can be used hoist and common runtime checks in situations like 13 // these: 14 // 15 // %cmp0 = 7 u< Length 16 // call @llvm.experimental.guard(i1 %cmp0) [ "deopt"(...) ] 17 // call @unknown_side_effects() 18 // %cmp1 = 9 u< Length 19 // call @llvm.experimental.guard(i1 %cmp1) [ "deopt"(...) ] 20 // ... 21 // 22 // => 23 // 24 // %cmp0 = 9 u< Length 25 // call @llvm.experimental.guard(i1 %cmp0) [ "deopt"(...) ] 26 // call @unknown_side_effects() 27 // ... 28 // 29 // If %cmp0 is false, @llvm.experimental.guard will "deoptimize" back to a 30 // generic implementation of the same function, which will have the correct 31 // semantics from that point onward. It is always _legal_ to deoptimize (so 32 // replacing %cmp0 with false is "correct"), though it may not always be 33 // profitable to do so. 34 // 35 // NB! This pass is a work in progress. It hasn't been tuned to be "production 36 // ready" yet. It is known to have quadriatic running time and will not scale 37 // to large numbers of guards 38 // 39 //===----------------------------------------------------------------------===// 40 41 #include "llvm/Transforms/Scalar/GuardWidening.h" 42 #include "llvm/ADT/DenseMap.h" 43 #include "llvm/ADT/DepthFirstIterator.h" 44 #include "llvm/ADT/Statistic.h" 45 #include "llvm/Analysis/GuardUtils.h" 46 #include "llvm/Analysis/LoopInfo.h" 47 #include "llvm/Analysis/LoopPass.h" 48 #include "llvm/Analysis/MemorySSAUpdater.h" 49 #include "llvm/Analysis/PostDominators.h" 50 #include "llvm/Analysis/ValueTracking.h" 51 #include "llvm/IR/ConstantRange.h" 52 #include "llvm/IR/Dominators.h" 53 #include "llvm/IR/IntrinsicInst.h" 54 #include "llvm/IR/PatternMatch.h" 55 #include "llvm/InitializePasses.h" 56 #include "llvm/Pass.h" 57 #include "llvm/Support/CommandLine.h" 58 #include "llvm/Support/Debug.h" 59 #include "llvm/Support/KnownBits.h" 60 #include "llvm/Transforms/Scalar.h" 61 #include "llvm/Transforms/Utils/GuardUtils.h" 62 #include "llvm/Transforms/Utils/LoopUtils.h" 63 #include <functional> 64 65 using namespace llvm; 66 67 #define DEBUG_TYPE "guard-widening" 68 69 STATISTIC(GuardsEliminated, "Number of eliminated guards"); 70 STATISTIC(CondBranchEliminated, "Number of eliminated conditional branches"); 71 72 static cl::opt<bool> 73 WidenBranchGuards("guard-widening-widen-branch-guards", cl::Hidden, 74 cl::desc("Whether or not we should widen guards " 75 "expressed as branches by widenable conditions"), 76 cl::init(true)); 77 78 namespace { 79 80 // Get the condition of \p I. It can either be a guard or a conditional branch. 81 static Value *getCondition(Instruction *I) { 82 if (IntrinsicInst *GI = dyn_cast<IntrinsicInst>(I)) { 83 assert(GI->getIntrinsicID() == Intrinsic::experimental_guard && 84 "Bad guard intrinsic?"); 85 return GI->getArgOperand(0); 86 } 87 Value *Cond, *WC; 88 BasicBlock *IfTrueBB, *IfFalseBB; 89 if (parseWidenableBranch(I, Cond, WC, IfTrueBB, IfFalseBB)) 90 return Cond; 91 92 return cast<BranchInst>(I)->getCondition(); 93 } 94 95 // Set the condition for \p I to \p NewCond. \p I can either be a guard or a 96 // conditional branch. 97 static void setCondition(Instruction *I, Value *NewCond) { 98 if (IntrinsicInst *GI = dyn_cast<IntrinsicInst>(I)) { 99 assert(GI->getIntrinsicID() == Intrinsic::experimental_guard && 100 "Bad guard intrinsic?"); 101 GI->setArgOperand(0, NewCond); 102 return; 103 } 104 cast<BranchInst>(I)->setCondition(NewCond); 105 } 106 107 // Eliminates the guard instruction properly. 108 static void eliminateGuard(Instruction *GuardInst, MemorySSAUpdater *MSSAU) { 109 GuardInst->eraseFromParent(); 110 if (MSSAU) 111 MSSAU->removeMemoryAccess(GuardInst); 112 ++GuardsEliminated; 113 } 114 115 class GuardWideningImpl { 116 DominatorTree &DT; 117 PostDominatorTree *PDT; 118 LoopInfo &LI; 119 MemorySSAUpdater *MSSAU; 120 121 /// Together, these describe the region of interest. This might be all of 122 /// the blocks within a function, or only a given loop's blocks and preheader. 123 DomTreeNode *Root; 124 std::function<bool(BasicBlock*)> BlockFilter; 125 126 /// The set of guards and conditional branches whose conditions have been 127 /// widened into dominating guards. 128 SmallVector<Instruction *, 16> EliminatedGuardsAndBranches; 129 130 /// The set of guards which have been widened to include conditions to other 131 /// guards. 132 DenseSet<Instruction *> WidenedGuards; 133 134 /// Try to eliminate instruction \p Instr by widening it into an earlier 135 /// dominating guard. \p DFSI is the DFS iterator on the dominator tree that 136 /// is currently visiting the block containing \p Guard, and \p GuardsPerBlock 137 /// maps BasicBlocks to the set of guards seen in that block. 138 bool eliminateInstrViaWidening( 139 Instruction *Instr, const df_iterator<DomTreeNode *> &DFSI, 140 const DenseMap<BasicBlock *, SmallVector<Instruction *, 8>> & 141 GuardsPerBlock, bool InvertCondition = false); 142 143 /// Used to keep track of which widening potential is more effective. 144 enum WideningScore { 145 /// Don't widen. 146 WS_IllegalOrNegative, 147 148 /// Widening is performance neutral as far as the cycles spent in check 149 /// conditions goes (but can still help, e.g., code layout, having less 150 /// deopt state). 151 WS_Neutral, 152 153 /// Widening is profitable. 154 WS_Positive, 155 156 /// Widening is very profitable. Not significantly different from \c 157 /// WS_Positive, except by the order. 158 WS_VeryPositive 159 }; 160 161 static StringRef scoreTypeToString(WideningScore WS); 162 163 /// Compute the score for widening the condition in \p DominatedInstr 164 /// into \p DominatingGuard. If \p InvertCond is set, then we widen the 165 /// inverted condition of the dominating guard. 166 WideningScore computeWideningScore(Instruction *DominatedInstr, 167 Instruction *DominatingGuard, 168 bool InvertCond); 169 170 /// Helper to check if \p V can be hoisted to \p InsertPos. 171 bool isAvailableAt(const Value *V, const Instruction *InsertPos) const { 172 SmallPtrSet<const Instruction *, 8> Visited; 173 return isAvailableAt(V, InsertPos, Visited); 174 } 175 176 bool isAvailableAt(const Value *V, const Instruction *InsertPos, 177 SmallPtrSetImpl<const Instruction *> &Visited) const; 178 179 /// Helper to hoist \p V to \p InsertPos. Guaranteed to succeed if \c 180 /// isAvailableAt returned true. 181 void makeAvailableAt(Value *V, Instruction *InsertPos) const; 182 183 /// Common helper used by \c widenGuard and \c isWideningCondProfitable. Try 184 /// to generate an expression computing the logical AND of \p Cond0 and (\p 185 /// Cond1 XOR \p InvertCondition). 186 /// Return true if the expression computing the AND is only as 187 /// expensive as computing one of the two. If \p InsertPt is true then 188 /// actually generate the resulting expression, make it available at \p 189 /// InsertPt and return it in \p Result (else no change to the IR is made). 190 bool widenCondCommon(Value *Cond0, Value *Cond1, Instruction *InsertPt, 191 Value *&Result, bool InvertCondition); 192 193 /// Represents a range check of the form \c Base + \c Offset u< \c Length, 194 /// with the constraint that \c Length is not negative. \c CheckInst is the 195 /// pre-existing instruction in the IR that computes the result of this range 196 /// check. 197 class RangeCheck { 198 const Value *Base; 199 const ConstantInt *Offset; 200 const Value *Length; 201 ICmpInst *CheckInst; 202 203 public: 204 explicit RangeCheck(const Value *Base, const ConstantInt *Offset, 205 const Value *Length, ICmpInst *CheckInst) 206 : Base(Base), Offset(Offset), Length(Length), CheckInst(CheckInst) {} 207 208 void setBase(const Value *NewBase) { Base = NewBase; } 209 void setOffset(const ConstantInt *NewOffset) { Offset = NewOffset; } 210 211 const Value *getBase() const { return Base; } 212 const ConstantInt *getOffset() const { return Offset; } 213 const APInt &getOffsetValue() const { return getOffset()->getValue(); } 214 const Value *getLength() const { return Length; }; 215 ICmpInst *getCheckInst() const { return CheckInst; } 216 217 void print(raw_ostream &OS, bool PrintTypes = false) { 218 OS << "Base: "; 219 Base->printAsOperand(OS, PrintTypes); 220 OS << " Offset: "; 221 Offset->printAsOperand(OS, PrintTypes); 222 OS << " Length: "; 223 Length->printAsOperand(OS, PrintTypes); 224 } 225 226 LLVM_DUMP_METHOD void dump() { 227 print(dbgs()); 228 dbgs() << "\n"; 229 } 230 }; 231 232 /// Parse \p CheckCond into a conjunction (logical-and) of range checks; and 233 /// append them to \p Checks. Returns true on success, may clobber \c Checks 234 /// on failure. 235 bool parseRangeChecks(Value *CheckCond, SmallVectorImpl<RangeCheck> &Checks) { 236 SmallPtrSet<const Value *, 8> Visited; 237 return parseRangeChecks(CheckCond, Checks, Visited); 238 } 239 240 bool parseRangeChecks(Value *CheckCond, SmallVectorImpl<RangeCheck> &Checks, 241 SmallPtrSetImpl<const Value *> &Visited); 242 243 /// Combine the checks in \p Checks into a smaller set of checks and append 244 /// them into \p CombinedChecks. Return true on success (i.e. all of checks 245 /// in \p Checks were combined into \p CombinedChecks). Clobbers \p Checks 246 /// and \p CombinedChecks on success and on failure. 247 bool combineRangeChecks(SmallVectorImpl<RangeCheck> &Checks, 248 SmallVectorImpl<RangeCheck> &CombinedChecks) const; 249 250 /// Can we compute the logical AND of \p Cond0 and \p Cond1 for the price of 251 /// computing only one of the two expressions? 252 bool isWideningCondProfitable(Value *Cond0, Value *Cond1, bool InvertCond) { 253 Value *ResultUnused; 254 return widenCondCommon(Cond0, Cond1, /*InsertPt=*/nullptr, ResultUnused, 255 InvertCond); 256 } 257 258 /// If \p InvertCondition is false, Widen \p ToWiden to fail if 259 /// \p NewCondition is false, otherwise make it fail if \p NewCondition is 260 /// true (in addition to whatever it is already checking). 261 void widenGuard(Instruction *ToWiden, Value *NewCondition, 262 bool InvertCondition) { 263 Value *Result; 264 265 widenCondCommon(getCondition(ToWiden), NewCondition, ToWiden, Result, 266 InvertCondition); 267 if (isGuardAsWidenableBranch(ToWiden)) { 268 setWidenableBranchCond(cast<BranchInst>(ToWiden), Result); 269 return; 270 } 271 setCondition(ToWiden, Result); 272 } 273 274 public: 275 explicit GuardWideningImpl(DominatorTree &DT, PostDominatorTree *PDT, 276 LoopInfo &LI, MemorySSAUpdater *MSSAU, 277 DomTreeNode *Root, 278 std::function<bool(BasicBlock*)> BlockFilter) 279 : DT(DT), PDT(PDT), LI(LI), MSSAU(MSSAU), Root(Root), 280 BlockFilter(BlockFilter) {} 281 282 /// The entry point for this pass. 283 bool run(); 284 }; 285 } 286 287 static bool isSupportedGuardInstruction(const Instruction *Insn) { 288 if (isGuard(Insn)) 289 return true; 290 if (WidenBranchGuards && isGuardAsWidenableBranch(Insn)) 291 return true; 292 return false; 293 } 294 295 bool GuardWideningImpl::run() { 296 DenseMap<BasicBlock *, SmallVector<Instruction *, 8>> GuardsInBlock; 297 bool Changed = false; 298 for (auto DFI = df_begin(Root), DFE = df_end(Root); 299 DFI != DFE; ++DFI) { 300 auto *BB = (*DFI)->getBlock(); 301 if (!BlockFilter(BB)) 302 continue; 303 304 auto &CurrentList = GuardsInBlock[BB]; 305 306 for (auto &I : *BB) 307 if (isSupportedGuardInstruction(&I)) 308 CurrentList.push_back(cast<Instruction>(&I)); 309 310 for (auto *II : CurrentList) 311 Changed |= eliminateInstrViaWidening(II, DFI, GuardsInBlock); 312 } 313 314 assert(EliminatedGuardsAndBranches.empty() || Changed); 315 for (auto *I : EliminatedGuardsAndBranches) 316 if (!WidenedGuards.count(I)) { 317 assert(isa<ConstantInt>(getCondition(I)) && "Should be!"); 318 if (isSupportedGuardInstruction(I)) 319 eliminateGuard(I, MSSAU); 320 else { 321 assert(isa<BranchInst>(I) && 322 "Eliminated something other than guard or branch?"); 323 ++CondBranchEliminated; 324 } 325 } 326 327 return Changed; 328 } 329 330 bool GuardWideningImpl::eliminateInstrViaWidening( 331 Instruction *Instr, const df_iterator<DomTreeNode *> &DFSI, 332 const DenseMap<BasicBlock *, SmallVector<Instruction *, 8>> & 333 GuardsInBlock, bool InvertCondition) { 334 // Ignore trivial true or false conditions. These instructions will be 335 // trivially eliminated by any cleanup pass. Do not erase them because other 336 // guards can possibly be widened into them. 337 if (isa<ConstantInt>(getCondition(Instr))) 338 return false; 339 340 Instruction *BestSoFar = nullptr; 341 auto BestScoreSoFar = WS_IllegalOrNegative; 342 343 // In the set of dominating guards, find the one we can merge GuardInst with 344 // for the most profit. 345 for (unsigned i = 0, e = DFSI.getPathLength(); i != e; ++i) { 346 auto *CurBB = DFSI.getPath(i)->getBlock(); 347 if (!BlockFilter(CurBB)) 348 break; 349 assert(GuardsInBlock.count(CurBB) && "Must have been populated by now!"); 350 const auto &GuardsInCurBB = GuardsInBlock.find(CurBB)->second; 351 352 auto I = GuardsInCurBB.begin(); 353 auto E = Instr->getParent() == CurBB ? find(GuardsInCurBB, Instr) 354 : GuardsInCurBB.end(); 355 356 #ifndef NDEBUG 357 { 358 unsigned Index = 0; 359 for (auto &I : *CurBB) { 360 if (Index == GuardsInCurBB.size()) 361 break; 362 if (GuardsInCurBB[Index] == &I) 363 Index++; 364 } 365 assert(Index == GuardsInCurBB.size() && 366 "Guards expected to be in order!"); 367 } 368 #endif 369 370 assert((i == (e - 1)) == (Instr->getParent() == CurBB) && "Bad DFS?"); 371 372 for (auto *Candidate : make_range(I, E)) { 373 auto Score = computeWideningScore(Instr, Candidate, InvertCondition); 374 LLVM_DEBUG(dbgs() << "Score between " << *getCondition(Instr) 375 << " and " << *getCondition(Candidate) << " is " 376 << scoreTypeToString(Score) << "\n"); 377 if (Score > BestScoreSoFar) { 378 BestScoreSoFar = Score; 379 BestSoFar = Candidate; 380 } 381 } 382 } 383 384 if (BestScoreSoFar == WS_IllegalOrNegative) { 385 LLVM_DEBUG(dbgs() << "Did not eliminate guard " << *Instr << "\n"); 386 return false; 387 } 388 389 assert(BestSoFar != Instr && "Should have never visited same guard!"); 390 assert(DT.dominates(BestSoFar, Instr) && "Should be!"); 391 392 LLVM_DEBUG(dbgs() << "Widening " << *Instr << " into " << *BestSoFar 393 << " with score " << scoreTypeToString(BestScoreSoFar) 394 << "\n"); 395 widenGuard(BestSoFar, getCondition(Instr), InvertCondition); 396 auto NewGuardCondition = InvertCondition 397 ? ConstantInt::getFalse(Instr->getContext()) 398 : ConstantInt::getTrue(Instr->getContext()); 399 setCondition(Instr, NewGuardCondition); 400 EliminatedGuardsAndBranches.push_back(Instr); 401 WidenedGuards.insert(BestSoFar); 402 return true; 403 } 404 405 GuardWideningImpl::WideningScore 406 GuardWideningImpl::computeWideningScore(Instruction *DominatedInstr, 407 Instruction *DominatingGuard, 408 bool InvertCond) { 409 Loop *DominatedInstrLoop = LI.getLoopFor(DominatedInstr->getParent()); 410 Loop *DominatingGuardLoop = LI.getLoopFor(DominatingGuard->getParent()); 411 bool HoistingOutOfLoop = false; 412 413 if (DominatingGuardLoop != DominatedInstrLoop) { 414 // Be conservative and don't widen into a sibling loop. TODO: If the 415 // sibling is colder, we should consider allowing this. 416 if (DominatingGuardLoop && 417 !DominatingGuardLoop->contains(DominatedInstrLoop)) 418 return WS_IllegalOrNegative; 419 420 HoistingOutOfLoop = true; 421 } 422 423 if (!isAvailableAt(getCondition(DominatedInstr), DominatingGuard)) 424 return WS_IllegalOrNegative; 425 426 // If the guard was conditional executed, it may never be reached 427 // dynamically. There are two potential downsides to hoisting it out of the 428 // conditionally executed region: 1) we may spuriously deopt without need and 429 // 2) we have the extra cost of computing the guard condition in the common 430 // case. At the moment, we really only consider the second in our heuristic 431 // here. TODO: evaluate cost model for spurious deopt 432 // NOTE: As written, this also lets us hoist right over another guard which 433 // is essentially just another spelling for control flow. 434 if (isWideningCondProfitable(getCondition(DominatedInstr), 435 getCondition(DominatingGuard), InvertCond)) 436 return HoistingOutOfLoop ? WS_VeryPositive : WS_Positive; 437 438 if (HoistingOutOfLoop) 439 return WS_Positive; 440 441 // Returns true if we might be hoisting above explicit control flow. Note 442 // that this completely ignores implicit control flow (guards, calls which 443 // throw, etc...). That choice appears arbitrary. 444 auto MaybeHoistingOutOfIf = [&]() { 445 auto *DominatingBlock = DominatingGuard->getParent(); 446 auto *DominatedBlock = DominatedInstr->getParent(); 447 if (isGuardAsWidenableBranch(DominatingGuard)) 448 DominatingBlock = cast<BranchInst>(DominatingGuard)->getSuccessor(0); 449 450 // Same Block? 451 if (DominatedBlock == DominatingBlock) 452 return false; 453 // Obvious successor (common loop header/preheader case) 454 if (DominatedBlock == DominatingBlock->getUniqueSuccessor()) 455 return false; 456 // TODO: diamond, triangle cases 457 if (!PDT) return true; 458 return !PDT->dominates(DominatedBlock, DominatingBlock); 459 }; 460 461 return MaybeHoistingOutOfIf() ? WS_IllegalOrNegative : WS_Neutral; 462 } 463 464 bool GuardWideningImpl::isAvailableAt( 465 const Value *V, const Instruction *Loc, 466 SmallPtrSetImpl<const Instruction *> &Visited) const { 467 auto *Inst = dyn_cast<Instruction>(V); 468 if (!Inst || DT.dominates(Inst, Loc) || Visited.count(Inst)) 469 return true; 470 471 if (!isSafeToSpeculativelyExecute(Inst, Loc, &DT) || 472 Inst->mayReadFromMemory()) 473 return false; 474 475 Visited.insert(Inst); 476 477 // We only want to go _up_ the dominance chain when recursing. 478 assert(!isa<PHINode>(Loc) && 479 "PHIs should return false for isSafeToSpeculativelyExecute"); 480 assert(DT.isReachableFromEntry(Inst->getParent()) && 481 "We did a DFS from the block entry!"); 482 return all_of(Inst->operands(), 483 [&](Value *Op) { return isAvailableAt(Op, Loc, Visited); }); 484 } 485 486 void GuardWideningImpl::makeAvailableAt(Value *V, Instruction *Loc) const { 487 auto *Inst = dyn_cast<Instruction>(V); 488 if (!Inst || DT.dominates(Inst, Loc)) 489 return; 490 491 assert(isSafeToSpeculativelyExecute(Inst, Loc, &DT) && 492 !Inst->mayReadFromMemory() && "Should've checked with isAvailableAt!"); 493 494 for (Value *Op : Inst->operands()) 495 makeAvailableAt(Op, Loc); 496 497 Inst->moveBefore(Loc); 498 // If we moved instruction before guard we must clean nuw, nsw flags. 499 Inst->setHasNoUnsignedWrap(false); 500 Inst->setHasNoSignedWrap(false); 501 } 502 503 bool GuardWideningImpl::widenCondCommon(Value *Cond0, Value *Cond1, 504 Instruction *InsertPt, Value *&Result, 505 bool InvertCondition) { 506 using namespace llvm::PatternMatch; 507 508 { 509 // L >u C0 && L >u C1 -> L >u max(C0, C1) 510 ConstantInt *RHS0, *RHS1; 511 Value *LHS; 512 ICmpInst::Predicate Pred0, Pred1; 513 if (match(Cond0, m_ICmp(Pred0, m_Value(LHS), m_ConstantInt(RHS0))) && 514 match(Cond1, m_ICmp(Pred1, m_Specific(LHS), m_ConstantInt(RHS1)))) { 515 if (InvertCondition) 516 Pred1 = ICmpInst::getInversePredicate(Pred1); 517 518 ConstantRange CR0 = 519 ConstantRange::makeExactICmpRegion(Pred0, RHS0->getValue()); 520 ConstantRange CR1 = 521 ConstantRange::makeExactICmpRegion(Pred1, RHS1->getValue()); 522 523 // Given what we're doing here and the semantics of guards, it would 524 // be correct to use a subset intersection, but that may be too 525 // aggressive in cases we care about. 526 if (Optional<ConstantRange> Intersect = CR0.exactIntersectWith(CR1)) { 527 APInt NewRHSAP; 528 CmpInst::Predicate Pred; 529 if (Intersect->getEquivalentICmp(Pred, NewRHSAP)) { 530 if (InsertPt) { 531 ConstantInt *NewRHS = 532 ConstantInt::get(Cond0->getContext(), NewRHSAP); 533 Result = new ICmpInst(InsertPt, Pred, LHS, NewRHS, "wide.chk"); 534 } 535 return true; 536 } 537 } 538 } 539 } 540 541 { 542 SmallVector<GuardWideningImpl::RangeCheck, 4> Checks, CombinedChecks; 543 // TODO: Support InvertCondition case? 544 if (!InvertCondition && 545 parseRangeChecks(Cond0, Checks) && parseRangeChecks(Cond1, Checks) && 546 combineRangeChecks(Checks, CombinedChecks)) { 547 if (InsertPt) { 548 Result = nullptr; 549 for (auto &RC : CombinedChecks) { 550 makeAvailableAt(RC.getCheckInst(), InsertPt); 551 if (Result) 552 Result = BinaryOperator::CreateAnd(RC.getCheckInst(), Result, "", 553 InsertPt); 554 else 555 Result = RC.getCheckInst(); 556 } 557 assert(Result && "Failed to find result value"); 558 Result->setName("wide.chk"); 559 } 560 return true; 561 } 562 } 563 564 // Base case -- just logical-and the two conditions together. 565 566 if (InsertPt) { 567 makeAvailableAt(Cond0, InsertPt); 568 makeAvailableAt(Cond1, InsertPt); 569 if (InvertCondition) 570 Cond1 = BinaryOperator::CreateNot(Cond1, "inverted", InsertPt); 571 Result = BinaryOperator::CreateAnd(Cond0, Cond1, "wide.chk", InsertPt); 572 } 573 574 // We were not able to compute Cond0 AND Cond1 for the price of one. 575 return false; 576 } 577 578 bool GuardWideningImpl::parseRangeChecks( 579 Value *CheckCond, SmallVectorImpl<GuardWideningImpl::RangeCheck> &Checks, 580 SmallPtrSetImpl<const Value *> &Visited) { 581 if (!Visited.insert(CheckCond).second) 582 return true; 583 584 using namespace llvm::PatternMatch; 585 586 { 587 Value *AndLHS, *AndRHS; 588 if (match(CheckCond, m_And(m_Value(AndLHS), m_Value(AndRHS)))) 589 return parseRangeChecks(AndLHS, Checks) && 590 parseRangeChecks(AndRHS, Checks); 591 } 592 593 auto *IC = dyn_cast<ICmpInst>(CheckCond); 594 if (!IC || !IC->getOperand(0)->getType()->isIntegerTy() || 595 (IC->getPredicate() != ICmpInst::ICMP_ULT && 596 IC->getPredicate() != ICmpInst::ICMP_UGT)) 597 return false; 598 599 const Value *CmpLHS = IC->getOperand(0), *CmpRHS = IC->getOperand(1); 600 if (IC->getPredicate() == ICmpInst::ICMP_UGT) 601 std::swap(CmpLHS, CmpRHS); 602 603 auto &DL = IC->getModule()->getDataLayout(); 604 605 GuardWideningImpl::RangeCheck Check( 606 CmpLHS, cast<ConstantInt>(ConstantInt::getNullValue(CmpRHS->getType())), 607 CmpRHS, IC); 608 609 if (!isKnownNonNegative(Check.getLength(), DL)) 610 return false; 611 612 // What we have in \c Check now is a correct interpretation of \p CheckCond. 613 // Try to see if we can move some constant offsets into the \c Offset field. 614 615 bool Changed; 616 auto &Ctx = CheckCond->getContext(); 617 618 do { 619 Value *OpLHS; 620 ConstantInt *OpRHS; 621 Changed = false; 622 623 #ifndef NDEBUG 624 auto *BaseInst = dyn_cast<Instruction>(Check.getBase()); 625 assert((!BaseInst || DT.isReachableFromEntry(BaseInst->getParent())) && 626 "Unreachable instruction?"); 627 #endif 628 629 if (match(Check.getBase(), m_Add(m_Value(OpLHS), m_ConstantInt(OpRHS)))) { 630 Check.setBase(OpLHS); 631 APInt NewOffset = Check.getOffsetValue() + OpRHS->getValue(); 632 Check.setOffset(ConstantInt::get(Ctx, NewOffset)); 633 Changed = true; 634 } else if (match(Check.getBase(), 635 m_Or(m_Value(OpLHS), m_ConstantInt(OpRHS)))) { 636 KnownBits Known = computeKnownBits(OpLHS, DL); 637 if ((OpRHS->getValue() & Known.Zero) == OpRHS->getValue()) { 638 Check.setBase(OpLHS); 639 APInt NewOffset = Check.getOffsetValue() + OpRHS->getValue(); 640 Check.setOffset(ConstantInt::get(Ctx, NewOffset)); 641 Changed = true; 642 } 643 } 644 } while (Changed); 645 646 Checks.push_back(Check); 647 return true; 648 } 649 650 bool GuardWideningImpl::combineRangeChecks( 651 SmallVectorImpl<GuardWideningImpl::RangeCheck> &Checks, 652 SmallVectorImpl<GuardWideningImpl::RangeCheck> &RangeChecksOut) const { 653 unsigned OldCount = Checks.size(); 654 while (!Checks.empty()) { 655 // Pick all of the range checks with a specific base and length, and try to 656 // merge them. 657 const Value *CurrentBase = Checks.front().getBase(); 658 const Value *CurrentLength = Checks.front().getLength(); 659 660 SmallVector<GuardWideningImpl::RangeCheck, 3> CurrentChecks; 661 662 auto IsCurrentCheck = [&](GuardWideningImpl::RangeCheck &RC) { 663 return RC.getBase() == CurrentBase && RC.getLength() == CurrentLength; 664 }; 665 666 copy_if(Checks, std::back_inserter(CurrentChecks), IsCurrentCheck); 667 erase_if(Checks, IsCurrentCheck); 668 669 assert(CurrentChecks.size() != 0 && "We know we have at least one!"); 670 671 if (CurrentChecks.size() < 3) { 672 llvm::append_range(RangeChecksOut, CurrentChecks); 673 continue; 674 } 675 676 // CurrentChecks.size() will typically be 3 here, but so far there has been 677 // no need to hard-code that fact. 678 679 llvm::sort(CurrentChecks, [&](const GuardWideningImpl::RangeCheck &LHS, 680 const GuardWideningImpl::RangeCheck &RHS) { 681 return LHS.getOffsetValue().slt(RHS.getOffsetValue()); 682 }); 683 684 // Note: std::sort should not invalidate the ChecksStart iterator. 685 686 const ConstantInt *MinOffset = CurrentChecks.front().getOffset(); 687 const ConstantInt *MaxOffset = CurrentChecks.back().getOffset(); 688 689 unsigned BitWidth = MaxOffset->getValue().getBitWidth(); 690 if ((MaxOffset->getValue() - MinOffset->getValue()) 691 .ugt(APInt::getSignedMinValue(BitWidth))) 692 return false; 693 694 APInt MaxDiff = MaxOffset->getValue() - MinOffset->getValue(); 695 const APInt &HighOffset = MaxOffset->getValue(); 696 auto OffsetOK = [&](const GuardWideningImpl::RangeCheck &RC) { 697 return (HighOffset - RC.getOffsetValue()).ult(MaxDiff); 698 }; 699 700 if (MaxDiff.isMinValue() || !all_of(drop_begin(CurrentChecks), OffsetOK)) 701 return false; 702 703 // We have a series of f+1 checks as: 704 // 705 // I+k_0 u< L ... Chk_0 706 // I+k_1 u< L ... Chk_1 707 // ... 708 // I+k_f u< L ... Chk_f 709 // 710 // with forall i in [0,f]: k_f-k_i u< k_f-k_0 ... Precond_0 711 // k_f-k_0 u< INT_MIN+k_f ... Precond_1 712 // k_f != k_0 ... Precond_2 713 // 714 // Claim: 715 // Chk_0 AND Chk_f implies all the other checks 716 // 717 // Informal proof sketch: 718 // 719 // We will show that the integer range [I+k_0,I+k_f] does not unsigned-wrap 720 // (i.e. going from I+k_0 to I+k_f does not cross the -1,0 boundary) and 721 // thus I+k_f is the greatest unsigned value in that range. 722 // 723 // This combined with Ckh_(f+1) shows that everything in that range is u< L. 724 // Via Precond_0 we know that all of the indices in Chk_0 through Chk_(f+1) 725 // lie in [I+k_0,I+k_f], this proving our claim. 726 // 727 // To see that [I+k_0,I+k_f] is not a wrapping range, note that there are 728 // two possibilities: I+k_0 u< I+k_f or I+k_0 >u I+k_f (they can't be equal 729 // since k_0 != k_f). In the former case, [I+k_0,I+k_f] is not a wrapping 730 // range by definition, and the latter case is impossible: 731 // 732 // 0-----I+k_f---I+k_0----L---INT_MAX,INT_MIN------------------(-1) 733 // xxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 734 // 735 // For Chk_0 to succeed, we'd have to have k_f-k_0 (the range highlighted 736 // with 'x' above) to be at least >u INT_MIN. 737 738 RangeChecksOut.emplace_back(CurrentChecks.front()); 739 RangeChecksOut.emplace_back(CurrentChecks.back()); 740 } 741 742 assert(RangeChecksOut.size() <= OldCount && "We pessimized!"); 743 return RangeChecksOut.size() != OldCount; 744 } 745 746 #ifndef NDEBUG 747 StringRef GuardWideningImpl::scoreTypeToString(WideningScore WS) { 748 switch (WS) { 749 case WS_IllegalOrNegative: 750 return "IllegalOrNegative"; 751 case WS_Neutral: 752 return "Neutral"; 753 case WS_Positive: 754 return "Positive"; 755 case WS_VeryPositive: 756 return "VeryPositive"; 757 } 758 759 llvm_unreachable("Fully covered switch above!"); 760 } 761 #endif 762 763 PreservedAnalyses GuardWideningPass::run(Function &F, 764 FunctionAnalysisManager &AM) { 765 auto &DT = AM.getResult<DominatorTreeAnalysis>(F); 766 auto &LI = AM.getResult<LoopAnalysis>(F); 767 auto &PDT = AM.getResult<PostDominatorTreeAnalysis>(F); 768 auto *MSSAA = AM.getCachedResult<MemorySSAAnalysis>(F); 769 std::unique_ptr<MemorySSAUpdater> MSSAU; 770 if (MSSAA) 771 MSSAU = std::make_unique<MemorySSAUpdater>(&MSSAA->getMSSA()); 772 if (!GuardWideningImpl(DT, &PDT, LI, MSSAU ? MSSAU.get() : nullptr, 773 DT.getRootNode(), [](BasicBlock *) { return true; }) 774 .run()) 775 return PreservedAnalyses::all(); 776 777 PreservedAnalyses PA; 778 PA.preserveSet<CFGAnalyses>(); 779 PA.preserve<MemorySSAAnalysis>(); 780 return PA; 781 } 782 783 PreservedAnalyses GuardWideningPass::run(Loop &L, LoopAnalysisManager &AM, 784 LoopStandardAnalysisResults &AR, 785 LPMUpdater &U) { 786 BasicBlock *RootBB = L.getLoopPredecessor(); 787 if (!RootBB) 788 RootBB = L.getHeader(); 789 auto BlockFilter = [&](BasicBlock *BB) { 790 return BB == RootBB || L.contains(BB); 791 }; 792 std::unique_ptr<MemorySSAUpdater> MSSAU; 793 if (AR.MSSA) 794 MSSAU = std::make_unique<MemorySSAUpdater>(AR.MSSA); 795 if (!GuardWideningImpl(AR.DT, nullptr, AR.LI, MSSAU ? MSSAU.get() : nullptr, 796 AR.DT.getNode(RootBB), BlockFilter).run()) 797 return PreservedAnalyses::all(); 798 799 auto PA = getLoopPassPreservedAnalyses(); 800 if (AR.MSSA) 801 PA.preserve<MemorySSAAnalysis>(); 802 return PA; 803 } 804 805 namespace { 806 struct GuardWideningLegacyPass : public FunctionPass { 807 static char ID; 808 809 GuardWideningLegacyPass() : FunctionPass(ID) { 810 initializeGuardWideningLegacyPassPass(*PassRegistry::getPassRegistry()); 811 } 812 813 bool runOnFunction(Function &F) override { 814 if (skipFunction(F)) 815 return false; 816 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 817 auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); 818 auto &PDT = getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree(); 819 auto *MSSAWP = getAnalysisIfAvailable<MemorySSAWrapperPass>(); 820 std::unique_ptr<MemorySSAUpdater> MSSAU; 821 if (MSSAWP) 822 MSSAU = std::make_unique<MemorySSAUpdater>(&MSSAWP->getMSSA()); 823 return GuardWideningImpl(DT, &PDT, LI, MSSAU ? MSSAU.get() : nullptr, 824 DT.getRootNode(), 825 [](BasicBlock *) { return true; }) 826 .run(); 827 } 828 829 void getAnalysisUsage(AnalysisUsage &AU) const override { 830 AU.setPreservesCFG(); 831 AU.addRequired<DominatorTreeWrapperPass>(); 832 AU.addRequired<PostDominatorTreeWrapperPass>(); 833 AU.addRequired<LoopInfoWrapperPass>(); 834 AU.addPreserved<MemorySSAWrapperPass>(); 835 } 836 }; 837 838 /// Same as above, but restricted to a single loop at a time. Can be 839 /// scheduled with other loop passes w/o breaking out of LPM 840 struct LoopGuardWideningLegacyPass : public LoopPass { 841 static char ID; 842 843 LoopGuardWideningLegacyPass() : LoopPass(ID) { 844 initializeLoopGuardWideningLegacyPassPass(*PassRegistry::getPassRegistry()); 845 } 846 847 bool runOnLoop(Loop *L, LPPassManager &LPM) override { 848 if (skipLoop(L)) 849 return false; 850 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 851 auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); 852 auto *PDTWP = getAnalysisIfAvailable<PostDominatorTreeWrapperPass>(); 853 auto *PDT = PDTWP ? &PDTWP->getPostDomTree() : nullptr; 854 auto *MSSAWP = getAnalysisIfAvailable<MemorySSAWrapperPass>(); 855 std::unique_ptr<MemorySSAUpdater> MSSAU; 856 if (MSSAWP) 857 MSSAU = std::make_unique<MemorySSAUpdater>(&MSSAWP->getMSSA()); 858 859 BasicBlock *RootBB = L->getLoopPredecessor(); 860 if (!RootBB) 861 RootBB = L->getHeader(); 862 auto BlockFilter = [&](BasicBlock *BB) { 863 return BB == RootBB || L->contains(BB); 864 }; 865 return GuardWideningImpl(DT, PDT, LI, MSSAU ? MSSAU.get() : nullptr, 866 DT.getNode(RootBB), BlockFilter).run(); 867 } 868 869 void getAnalysisUsage(AnalysisUsage &AU) const override { 870 AU.setPreservesCFG(); 871 getLoopAnalysisUsage(AU); 872 AU.addPreserved<PostDominatorTreeWrapperPass>(); 873 AU.addPreserved<MemorySSAWrapperPass>(); 874 } 875 }; 876 } 877 878 char GuardWideningLegacyPass::ID = 0; 879 char LoopGuardWideningLegacyPass::ID = 0; 880 881 INITIALIZE_PASS_BEGIN(GuardWideningLegacyPass, "guard-widening", "Widen guards", 882 false, false) 883 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 884 INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass) 885 INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) 886 INITIALIZE_PASS_END(GuardWideningLegacyPass, "guard-widening", "Widen guards", 887 false, false) 888 889 INITIALIZE_PASS_BEGIN(LoopGuardWideningLegacyPass, "loop-guard-widening", 890 "Widen guards (within a single loop, as a loop pass)", 891 false, false) 892 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 893 INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass) 894 INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) 895 INITIALIZE_PASS_END(LoopGuardWideningLegacyPass, "loop-guard-widening", 896 "Widen guards (within a single loop, as a loop pass)", 897 false, false) 898 899 FunctionPass *llvm::createGuardWideningPass() { 900 return new GuardWideningLegacyPass(); 901 } 902 903 Pass *llvm::createLoopGuardWideningPass() { 904 return new LoopGuardWideningLegacyPass(); 905 } 906