LLVM 24.0.0git
ConstraintElimination.cpp
Go to the documentation of this file.
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
16#include "llvm/ADT/STLExtras.h"
17#include "llvm/ADT/ScopeExit.h"
19#include "llvm/ADT/Statistic.h"
30#include "llvm/IR/DataLayout.h"
31#include "llvm/IR/DebugInfo.h"
32#include "llvm/IR/Dominators.h"
33#include "llvm/IR/Function.h"
34#include "llvm/IR/IRBuilder.h"
35#include "llvm/IR/InstrTypes.h"
37#include "llvm/IR/Module.h"
39#include "llvm/IR/Verifier.h"
40#include "llvm/Pass.h"
42#include "llvm/Support/Debug.h"
47
48#include <optional>
49#include <string>
50
51using namespace llvm;
52using namespace PatternMatch;
53using namespace SCEVPatternMatch;
54
55#define DEBUG_TYPE "constraint-elimination"
56
57STATISTIC(NumCondsRemoved, "Number of instructions removed");
58DEBUG_COUNTER(EliminatedCounter, "conds-eliminated",
59 "Controls which conditions are eliminated");
60
62 MaxRows("constraint-elimination-max-rows", cl::init(500), cl::Hidden,
63 cl::desc("Maximum number of rows to keep in constraint system"));
64
66 "constraint-elimination-dump-reproducers", cl::init(false), cl::Hidden,
67 cl::desc("Dump IR to reproduce successful transformations."));
68
69static int64_t MaxConstraintValue = std::numeric_limits<int64_t>::max();
70static int64_t MinSignedConstraintValue = std::numeric_limits<int64_t>::min();
71
73 Instruction *UserI = cast<Instruction>(U.getUser());
74 if (auto *Phi = dyn_cast<PHINode>(UserI))
75 UserI = Phi->getIncomingBlock(U)->getTerminator();
76 return UserI;
77}
78
79/// Returns the closest program point dominating all uses of \p I.
81 DominatorTree &DT) {
82 Instruction *CommonDom = nullptr;
83 unsigned NumUses = 0;
84 for (Use &U : I.uses()) {
85 // Conservatively use original instruction, if there are too many uses.
86 if (++NumUses == 16)
87 return &I;
89 CommonDom =
90 CommonDom ? DT.findNearestCommonDominator(CommonDom, UserI) : UserI;
91 }
92 if (!CommonDom)
93 return &I;
94 // Uses in unreachable blocks are not in the dominator tree.
95 return DT.getNode(CommonDom->getParent()) ? CommonDom : &I;
96}
97
98namespace {
99using Entry = ConstraintSystem::Entry;
100using RowTy = ConstraintSystem::RowTy;
101
102/// Struct to express a condition of the form %Op0 Pred %Op1.
103struct ConditionTy {
104 CmpPredicate Pred;
105 Value *Op0 = nullptr;
106 Value *Op1 = nullptr;
107
108 ConditionTy() = default;
109 ConditionTy(CmpPredicate Pred, Value *Op0, Value *Op1)
110 : Pred(Pred), Op0(Op0), Op1(Op1) {}
111};
112
113/// Represents either
114/// * a condition that holds on entry to a block (=condition fact)
115/// * an assume (=assume fact)
116/// * a use of a compare instruction to simplify.
117/// It also tracks the Dominator DFS in and out numbers for each entry.
118struct FactOrCheck {
119 enum class EntryTy {
120 ConditionFact, /// A condition that holds on entry to a block.
121 InstFact, /// A fact that holds after Inst executed (e.g. an assume or
122 /// min/mix intrinsic.
123 InstCheck, /// An instruction to simplify (e.g. an overflow math
124 /// intrinsics) or whose flags may be strengthened.
125 UseCheck /// An use of a compare instruction to simplify.
126 };
127
128 union {
129 Instruction *Inst;
130 Use *U;
132 };
133
134 union {
135 /// A pre-condition that must hold for the current fact to be added to the
136 /// system. Only used by condition facts.
137 ConditionTy DoesHold;
138
139 /// Context instruction for the point where conditions are checked for
140 /// InstCheck simplifications.
141 Instruction *ContextInst;
142 };
143
144 unsigned NumIn;
145 unsigned NumOut;
146 EntryTy Ty;
147
148 FactOrCheck(EntryTy Ty, DomTreeNode *DTN, Instruction *Inst,
149 Instruction *ContextInst = nullptr)
150 : Inst(Inst), ContextInst(ContextInst ? ContextInst : Inst),
151 NumIn(DTN->getDFSNumIn()), NumOut(DTN->getDFSNumOut()), Ty(Ty) {}
152
153 FactOrCheck(DomTreeNode *DTN, Use *U)
154 : U(U), ContextInst(nullptr), NumIn(DTN->getDFSNumIn()),
155 NumOut(DTN->getDFSNumOut()), Ty(EntryTy::UseCheck) {}
156
157 FactOrCheck(DomTreeNode *DTN, CmpPredicate Pred, Value *Op0, Value *Op1,
158 ConditionTy Precond = {})
159 : Cond(Pred, Op0, Op1), DoesHold(Precond), NumIn(DTN->getDFSNumIn()),
160 NumOut(DTN->getDFSNumOut()), Ty(EntryTy::ConditionFact) {}
161
162 static FactOrCheck getConditionFact(DomTreeNode *DTN, CmpPredicate Pred,
163 Value *Op0, Value *Op1,
164 ConditionTy Precond = {}) {
165 return FactOrCheck(DTN, Pred, Op0, Op1, Precond);
166 }
167
168 static FactOrCheck getInstFact(DomTreeNode *DTN, Instruction *Inst) {
169 return FactOrCheck(EntryTy::InstFact, DTN, Inst);
170 }
171
172 static FactOrCheck getCheck(DomTreeNode *DTN, Use *U) {
173 return FactOrCheck(DTN, U);
174 }
175
176 static FactOrCheck getCheck(DomTreeNode *DTN, Instruction *I,
177 Instruction *ContextInst = nullptr) {
178 assert((ContextInst ? ContextInst : I)->getParent() == DTN->getBlock() &&
179 "anchoring instruction must be in DTN's block");
180 return FactOrCheck(EntryTy::InstCheck, DTN, I, ContextInst);
181 }
182
183 bool isCheck() const {
184 return Ty == EntryTy::InstCheck || Ty == EntryTy::UseCheck;
185 }
186
187 Instruction *getContextInst() const {
188 assert(!isConditionFact());
189 if (Ty == EntryTy::UseCheck)
190 return getContextInstForUse(*U);
191 return ContextInst;
192 }
193
194 Instruction *getInstructionToSimplify() const {
195 assert(isCheck());
196 if (Ty == EntryTy::InstCheck)
197 return Inst;
198 // The use may have been simplified to a constant already.
199 return dyn_cast<Instruction>(*U);
200 }
201
202 bool isConditionFact() const { return Ty == EntryTy::ConditionFact; }
203};
204
205/// The senses in which an induction phi is monotonic, together with the
206/// direction it moves in.
207struct MonotonicInfo {
208 /// True if the phi steps by a negative constant.
209 bool Decreasing = false;
210 /// True if the phi is monotonic in the unsigned sense.
211 bool Unsigned = false;
212 /// True if the phi is monotonic in the signed sense.
213 bool Signed = false;
214};
215
216/// Keep state required to build worklist.
217struct State {
218 DominatorTree &DT;
219 LoopInfo &LI;
220 /// Only available for functions with loops.
221 ScalarEvolution *SE;
222 TargetLibraryInfo &TLI;
224
225 State(DominatorTree &DT, LoopInfo &LI, ScalarEvolution *SE,
226 TargetLibraryInfo &TLI)
227 : DT(DT), LI(LI), SE(SE), TLI(TLI) {}
228
229 /// Process block \p BB and add known facts to work-list.
230 void addInfoFor(BasicBlock &BB);
231
232 /// If \p BB is a loop header, bound each induction phi in it by its start
233 /// value.
234 void addBoundsForHeaderInductions(BasicBlock &BB);
235
236 /// Try to add facts for loop inductions (AddRecs) in EQ/NE compares
237 /// controlling the loop header.
238 void addInfoForInductions(BasicBlock &BB);
239
240 /// Returns the direction the induction phi \p PN with backedge value \p Step
241 /// moves in, and the senses in which it is monotonic in that direction.
242 MonotonicInfo getMonotonicityInfo(PHINode &PN, Value *Step);
243
244 /// Returns true if we can add a known condition from BB to its successor
245 /// block Succ.
246 bool canAddSuccessor(BasicBlock &BB, BasicBlock *Succ) const {
247 return DT.dominates(BasicBlockEdge(&BB, Succ), Succ);
248 }
249};
250
251class ConstraintInfo;
252
253struct StackEntry {
254 unsigned NumIn;
255 unsigned NumOut;
256 bool IsSigned = false;
257 /// Variables that can be removed from the system once the stack entry gets
258 /// removed.
259 SmallVector<Value *, 2> ValuesToRelease;
260
261 StackEntry(unsigned NumIn, unsigned NumOut, bool IsSigned,
262 SmallVector<Value *, 2> ValuesToRelease)
263 : NumIn(NumIn), NumOut(NumOut), IsSigned(IsSigned),
264 ValuesToRelease(std::move(ValuesToRelease)) {}
265};
266
267struct ConstraintTy {
268 RowTy Coefficients;
269
270 /// Number of variables the constraint is defined over.
271 unsigned NumVars = 0;
272
273 bool IsSigned = false;
274
275 ConstraintTy() = default;
276
277 ConstraintTy(RowTy Coefficients, unsigned NumVars, bool IsSigned, bool IsEq,
278 bool IsNe)
279 : Coefficients(std::move(Coefficients)), NumVars(NumVars),
280 IsSigned(IsSigned), IsEq(IsEq), IsNe(IsNe) {}
281
282 bool empty() const { return Coefficients.empty(); }
283
284 bool isEq() const { return IsEq; }
285
286 bool isNe() const { return IsNe; }
287
288 /// Check if the current constraint is implied by the given ConstraintSystem.
289 ///
290 /// \return true or false if the constraint is proven to be respectively true,
291 /// or false. When the constraint cannot be proven to be either true or false,
292 /// std::nullopt is returned.
293 std::optional<bool> isImpliedBy(const ConstraintSystem &CS) const;
294
295private:
296 bool IsEq = false;
297 bool IsNe = false;
298};
299
300/// Represents a (Coefficient * Variable) entry after IR decomposition.
301struct DecompEntry {
302 int64_t Coefficient;
303 Value *Variable;
304
305 DecompEntry(int64_t Coefficient, Value *Variable)
306 : Coefficient(Coefficient), Variable(Variable) {}
307};
308
309/// Represents an Offset + Coefficient1 * Variable1 + ... decomposition.
310struct Decomposition {
311 int64_t Offset = 0;
313
314 Decomposition(int64_t Offset) : Offset(Offset) {}
315 Decomposition(Value *V) { Vars.emplace_back(1, V); }
316 Decomposition(int64_t Offset, ArrayRef<DecompEntry> Vars)
317 : Offset(Offset), Vars(Vars) {}
318
319 /// Add \p OtherOffset and return true if the operation overflows, i.e. the
320 /// new decomposition is invalid.
321 [[nodiscard]] bool add(int64_t OtherOffset) {
322 return AddOverflow(Offset, OtherOffset, Offset);
323 }
324
325 /// Add \p Other and return true if the operation overflows, i.e. the new
326 /// decomposition is invalid.
327 [[nodiscard]] bool add(const Decomposition &Other) {
328 if (add(Other.Offset))
329 return true;
330 append_range(Vars, Other.Vars);
331 return false;
332 }
333
334 /// Subtract \p Other and return true if the operation overflows, i.e. the new
335 /// decomposition is invalid.
336 [[nodiscard]] bool sub(const Decomposition &Other) {
337 Decomposition Tmp = Other;
338 if (Tmp.mul(-1))
339 return true;
340 if (add(Tmp.Offset))
341 return true;
342 append_range(Vars, Tmp.Vars);
343 return false;
344 }
345
346 /// Multiply all coefficients by \p Factor and return true if the operation
347 /// overflows, i.e. the new decomposition is invalid.
348 [[nodiscard]] bool mul(int64_t Factor) {
349 if (MulOverflow(Offset, Factor, Offset))
350 return true;
351 for (auto &Var : Vars)
352 if (MulOverflow(Var.Coefficient, Factor, Var.Coefficient))
353 return true;
354 return false;
355 }
356};
357
358/// Wrapper encapsulating separate constraint systems and corresponding value
359/// mappings for both unsigned and signed information. Facts are added to and
360/// conditions are checked against the corresponding system depending on the
361/// signed-ness of their predicates. While the information is kept separate
362/// based on signed-ness, certain conditions can be transferred between the two
363/// systems.
364class ConstraintInfo {
365
366 ConstraintSystem UnsignedCS;
367 ConstraintSystem SignedCS;
368
369 const DataLayout &DL;
370
371 /// Decompositions computed against the current state of the systems. Must be
372 /// cleared when the system changes.
373 DenseMap<PointerIntPair<Value *, 1, bool>, Decomposition> DecomposeCache;
374
375public:
376 DenseMap<PointerIntPair<Value *, 1, bool>, Decomposition> &
377 getDecomposeCache() {
378 return DecomposeCache;
379 }
380
381 ConstraintInfo(const DataLayout &DL, ArrayRef<Value *> FunctionArgs)
382 : UnsignedCS(FunctionArgs), SignedCS(FunctionArgs), DL(DL) {
383 auto &Value2Index = getValue2Index(false);
384 // Add Arg > -1 constraints to unsigned system for all function arguments.
385 for (Value *Arg : FunctionArgs)
386 UnsignedCS.addRow({Entry(0, 0), Entry(-1, Value2Index.at(Arg))},
387 Value2Index.size());
388 }
389
390 DenseMap<Value *, unsigned> &getValue2Index(bool Signed) {
391 return Signed ? SignedCS.getValue2Index() : UnsignedCS.getValue2Index();
392 }
393 const DenseMap<Value *, unsigned> &getValue2Index(bool Signed) const {
394 return Signed ? SignedCS.getValue2Index() : UnsignedCS.getValue2Index();
395 }
396
397 ConstraintSystem &getCS(bool Signed) {
398 return Signed ? SignedCS : UnsignedCS;
399 }
400 const ConstraintSystem &getCS(bool Signed) const {
401 return Signed ? SignedCS : UnsignedCS;
402 }
403
404 void popLastConstraint(bool Signed) {
405 assert(DecomposeCache.empty() && "Cache must be cleared");
406 getCS(Signed).popLastConstraint();
407 }
408 void popLastNVariables(bool Signed, unsigned N) {
409 assert(DecomposeCache.empty() && "Cache must be cleared");
410 getCS(Signed).popLastNVariables(N);
411 }
412
413 bool doesHold(CmpInst::Predicate Pred, Value *A, Value *B);
414
415 /// Returns true if \p V is known to be non-negative, either because the
416 /// signed system implies it or because ValueTracking can prove it.
417 bool isKnownNonNegative(Value *V);
418
419 /// Returns true if \p V is known to be positive, either because the signed
420 /// system implies it or because ValueTracking can prove it.
421 bool isKnownPositive(Value *V);
422
423 void addFact(CmpInst::Predicate Pred, Value *A, Value *B, unsigned NumIn,
424 unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack);
425
426 /// Turn a comparison of the form \p Op0 \p Pred \p Op1 into a vector of
427 /// constraints, using indices from the corresponding constraint system.
428 /// New variables that need to be added to the system are collected in
429 /// \p NewVariables.
430 ConstraintTy getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
431 SmallVectorImpl<Value *> &NewVariables,
432 bool ForceSignedSystem = false);
433
434 /// Turns a comparison of the form \p Op0 \p Pred \p Op1 into a vector of
435 /// constraints using getConstraint. Returns an empty constraint if the result
436 /// cannot be used to query the existing constraint system, e.g. because it
437 /// would require adding new variables. Also tries to convert signed
438 /// predicates to unsigned ones if possible to allow using the unsigned system
439 /// which increases the effectiveness of the signed <-> unsigned transfer
440 /// logic.
441 ConstraintTy getConstraintForSolving(CmpInst::Predicate Pred, Value *Op0,
442 Value *Op1);
443
444 /// Try to add information from \p A \p Pred \p B to the unsigned/signed
445 /// system if \p Pred is signed/unsigned.
446 void transferToOtherSystem(CmpInst::Predicate Pred, Value *A, Value *B,
447 unsigned NumIn, unsigned NumOut,
448 SmallVectorImpl<StackEntry> &DFSInStack);
449
450private:
451 /// Adds facts into constraint system. \p ForceSignedSystem can be set when
452 /// the \p Pred is eq/ne, and signed constraint system is used when it's
453 /// specified.
454 void addFactImpl(CmpInst::Predicate Pred, Value *A, Value *B, unsigned NumIn,
455 unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack,
456 bool ForceSignedSystem);
457
458 /// Try to use the inequality \p A != \p B to tighten a non-strict bound the
459 /// system already implies to the corresponding strict bound.
460 void tightenBoundUsingNe(Value *A, Value *B, unsigned NumIn, unsigned NumOut,
461 SmallVectorImpl<StackEntry> &DFSInStack);
462};
463
464// Variable and constant offsets for a chain of GEPs, with base pointer BasePtr.
465struct OffsetResult {
466 Value *BasePtr;
467 APInt ConstantOffset;
468 SmallMapVector<Value *, APInt, 4> VariableOffsets;
469 GEPNoWrapFlags NW;
470
471 OffsetResult() : BasePtr(nullptr), ConstantOffset(0, uint64_t(0)) {}
472
473 OffsetResult(GEPOperator &GEP, const DataLayout &DL)
474 : BasePtr(GEP.getPointerOperand()), NW(GEP.getNoWrapFlags()) {
475 ConstantOffset = APInt(DL.getIndexTypeSizeInBits(BasePtr->getType()), 0);
476 }
477};
478} // namespace
479
480// Try to collect variable and constant offsets for \p GEP, partly traversing
481// nested GEPs. Returns an OffsetResult with nullptr as BasePtr of collecting
482// the offset fails.
484 OffsetResult Result(GEP, DL);
485 unsigned BitWidth = Result.ConstantOffset.getBitWidth();
486 if (!GEP.collectOffset(DL, BitWidth, Result.VariableOffsets,
487 Result.ConstantOffset))
488 return {};
489
490 // If we have a nested GEP, check if we can combine the constant offset of the
491 // inner GEP with the outer GEP.
492 if (auto *InnerGEP = dyn_cast<GetElementPtrInst>(Result.BasePtr)) {
493 SmallMapVector<Value *, APInt, 4> VariableOffsets2;
494 APInt ConstantOffset2(BitWidth, 0);
495 bool CanCollectInner = InnerGEP->collectOffset(
496 DL, BitWidth, VariableOffsets2, ConstantOffset2);
497 // TODO: Support cases with more than 1 variable offset.
498 if (!CanCollectInner || Result.VariableOffsets.size() > 1 ||
499 VariableOffsets2.size() > 1 ||
500 (Result.VariableOffsets.size() >= 1 && VariableOffsets2.size() >= 1)) {
501 // More than 1 variable index, use outer result.
502 return Result;
503 }
504 Result.BasePtr = InnerGEP->getPointerOperand();
505 Result.ConstantOffset += ConstantOffset2;
506 if (Result.VariableOffsets.size() == 0 && VariableOffsets2.size() == 1)
507 Result.VariableOffsets = std::move(VariableOffsets2);
508 Result.NW &= InnerGEP->getNoWrapFlags();
509 }
510 return Result;
511}
512
513static Decomposition decompose(Value *V, ConstraintInfo &Info, bool IsSigned,
514 const DataLayout &DL);
515
516static bool canUseSExt(ConstantInt *CI) {
517 const APInt &Val = CI->getValue();
519}
520
521/// Returns true if \p Info implies that \p Op is in \p R, interpreting \p R as
522/// a signed range if \p Signed is set and as an unsigned range otherwise.
523static bool doesHoldInRange(ConstraintInfo &Info, Value *Op,
524 const ConstantRange &R, bool Signed) {
525 if (R.isEmptySet() || (Signed ? R.isSignWrappedSet() : R.isWrappedSet()))
526 return false;
527
528 if (R.isFullSet())
529 return true;
530
531 unsigned BitWidth = R.getBitWidth();
532 APInt Min = Signed ? R.getSignedMin() : R.getUnsignedMin();
533 APInt Max = Signed ? R.getSignedMax() : R.getUnsignedMax();
538 // Replace bound too large to be decomposed by the largest usable one.
539 if (!Signed && Max.uge(MaxConstraintValue))
541
542 Type *Ty = Op->getType();
543 if (Min != MinVal &&
544 !Info.doesHold(Signed ? CmpInst::ICMP_SGE : CmpInst::ICMP_UGE, Op,
545 ConstantInt::get(Ty, Min)))
546 return false;
547 if (Max != MaxVal &&
548 !Info.doesHold(Signed ? CmpInst::ICMP_SLE : CmpInst::ICMP_ULE, Op,
549 ConstantInt::get(Ty, Max)))
550 return false;
551 return true;
552}
553
554/// Returns true if \p Opcode applied to \p Op0 and \p Op1 with \p NoWrapFlags
555/// is known to not wrap in signed or unsigned, depending on \p Signed.
556static bool isKnownNoWrap(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1,
557 unsigned NoWrapFlags, ConstraintInfo &Info,
558 bool Signed) {
559 using OBO = OverflowingBinaryOperator;
560
561 if (NoWrapFlags & (Signed ? OBO::NoSignedWrap : OBO::NoUnsignedWrap))
562 return true;
563
564 if (Opcode == Instruction::Sub) {
565 // Op0 - Op1 does not wrap unsigned if Op0 >=u Op1.
566 if (!Signed)
567 return Info.doesHold(CmpInst::ICMP_UGE, Op0, Op1);
568
569 // Op0 - Op1 does not wrap signed if 0 <=s Op1 <=s Op0.
570 if (Info.isKnownNonNegative(Op1) &&
571 Info.doesHold(CmpInst::ICMP_SGE, Op0, Op1))
572 return true;
573 }
574
575 if (!Signed && (NoWrapFlags & OBO::NoSignedWrap) &&
576 (Opcode == Instruction::Shl || Info.isKnownNonNegative(Op1)) &&
577 Info.isKnownNonNegative(Op0))
578 return true;
579
580 // For a constant Op1, the ranges of Op0 for which the operation does not
581 // wrap are known exactly; check if the systems imply one of them.
582 auto *C = dyn_cast<ConstantInt>(Op1);
583 if (!C)
584 return false;
585
586 return doesHoldInRange(Info, Op0,
588 Opcode, C->getValue(),
589 Signed ? OBO::NoSignedWrap : OBO::NoUnsignedWrap),
590 Signed);
591}
592
593/// Returns true if \p V is known to not wrap in signed or unsigned, depending
594/// on \p Signed.
595static bool isKnownNoWrap(Value *V, ConstraintInfo &Info, bool Signed) {
596 if (match(V, m_DisjointOr(m_Value(), m_Value())))
597 return true;
598
599 if (auto *WO = dyn_cast<WithOverflowInst>(V))
600 return isKnownNoWrap(WO->getBinaryOp(), WO->getLHS(), WO->getRHS(),
601 /*NoWrapFlags=*/0, Info, Signed);
602
603 if (auto *Trunc = dyn_cast<TruncInst>(V)) {
604 if (Signed)
605 return Trunc->hasNoSignedWrap();
606
607 // A trunc nsw only truncates without unsigned wrap if its operand is
608 // non-negative.
609 return Trunc->hasNoUnsignedWrap() ||
610 (Trunc->hasNoSignedWrap() &&
611 Info.isKnownNonNegative(Trunc->getOperand(0)));
612 }
613
615 return BO &&
616 isKnownNoWrap(static_cast<Instruction::BinaryOps>(BO->getOpcode()),
617 BO->getOperand(0), BO->getOperand(1),
618 BO->getNoWrapKind(), Info, Signed);
619}
620
621static Decomposition decomposeGEP(GEPOperator &GEP, ConstraintInfo &Info,
622 bool IsSigned, const DataLayout &DL) {
623 // Do not reason about pointers where the index size is larger than 64 bits,
624 // as the coefficients used to encode constraints are 64 bit integers.
625 if (DL.getIndexTypeSizeInBits(GEP.getPointerOperand()->getType()) > 64)
626 return &GEP;
627
628 assert(!IsSigned && "The logic below only supports decomposition for "
629 "unsigned predicates at the moment.");
630 const auto &[BasePtr, ConstantOffset, VariableOffsets, NW] =
632 // We support either plain gep nuw, or gep nusw with non-negative offset,
633 // which implies gep nuw.
634 if (!BasePtr || NW == GEPNoWrapFlags::none())
635 return &GEP;
636
637 // For a nuw-only GEP (nuw without nusw/inbounds), the offset must be
638 // interpreted as unsigned.
639 if (!NW.hasNoUnsignedSignedWrap() && ConstantOffset.isNegative())
640 return &GEP;
641
642 Decomposition Result(ConstantOffset.getSExtValue(), DecompEntry(1, BasePtr));
643 for (auto [Index, Scale] : VariableOffsets) {
644 if (!NW.hasNoUnsignedWrap()) {
645 // Try to prove nuw from nusw and nneg. If the index cannot be proven
646 // non-negative, keep the GEP as-is instead of decomposing it.
647 assert(NW.hasNoUnsignedSignedWrap() && "Must have nusw flag");
648 if (!Info.isKnownNonNegative(Index))
649 return &GEP;
650 }
651
652 auto IdxResult = decompose(Index, Info, IsSigned, DL);
653 if (IdxResult.mul(Scale.getSExtValue()))
654 return &GEP;
655 if (Result.add(IdxResult))
656 return &GEP;
657 }
658 return Result;
659}
660
661// Decomposes \p V into a constant offset + list of pairs { Coefficient,
662// Variable } where Coefficient * Variable. The sum of the constant offset and
663// pairs equals \p V.
664//
665// Looking through certain expressions is only valid if a pre-condition holds.
666// Pre-conditions are checked against \p Info as needed.
667static Decomposition decomposeImpl(Value *V, ConstraintInfo &Info,
668 bool IsSigned, const DataLayout &DL);
669
670/// Returns true if \p V is an operation decomposeImpl can look through.
671static bool mayLookThrough(Value *V) {
672 auto *Op = dyn_cast<Operator>(V);
673 if (!Op)
674 return false;
675 switch (Op->getOpcode()) {
676 case Instruction::GetElementPtr:
677 case Instruction::Add:
678 case Instruction::Sub:
679 case Instruction::Mul:
680 case Instruction::Shl:
681 case Instruction::ZExt:
682 case Instruction::SExt:
683 case Instruction::Trunc:
684 case Instruction::Or:
685 case Instruction::Xor:
686 return true;
687 default:
688 return false;
689 }
690}
691
692static Decomposition decompose(Value *V, ConstraintInfo &Info, bool IsSigned,
693 const DataLayout &DL) {
694 if (!mayLookThrough(V))
695 return decomposeImpl(V, Info, IsSigned, DL);
696
698 auto &Cache = Info.getDecomposeCache();
699 auto It = Cache.find(Key);
700 if (It != Cache.end())
701 return It->second;
702
703 Decomposition Result = decomposeImpl(V, Info, IsSigned, DL);
704 Info.getDecomposeCache().insert({Key, Result});
705 return Result;
706}
707
708static Decomposition decomposeImpl(Value *V, ConstraintInfo &Info,
709 bool IsSigned, const DataLayout &DL) {
710 auto MergeResults = [&Info, IsSigned,
711 &DL](Value *A, Value *B,
712 bool IsSignedB) -> std::optional<Decomposition> {
713 auto ResA = decompose(A, Info, IsSigned, DL);
714 auto ResB = decompose(B, Info, IsSignedB, DL);
715 if (ResA.add(ResB))
716 return std::nullopt;
717 return ResA;
718 };
719
720 Type *Ty = V->getType()->getScalarType();
721 if (Ty->isPointerTy() && !IsSigned) {
722 if (auto *GEP = dyn_cast<GEPOperator>(V))
723 return decomposeGEP(*GEP, Info, IsSigned, DL);
725 return int64_t(0);
726
727 return V;
728 }
729
730 // Don't handle integers > 64 bit. Our coefficients are 64-bit large, so
731 // coefficient add/mul may wrap, while the operation in the full bit width
732 // would not.
733 if (!Ty->isIntegerTy() || Ty->getIntegerBitWidth() > 64)
734 return V;
735
736 if (auto *CI = dyn_cast<ConstantInt>(V)) {
737 if (IsSigned) {
738 if (canUseSExt(CI))
739 return CI->getSExtValue();
740 } else if (!CI->uge(MaxConstraintValue)) {
741 return int64_t(CI->getZExtValue());
742 }
743 return V;
744 }
745
746 Value *Op0;
747 Value *Op1;
748 ConstantInt *CI;
749
750 if (match(V, m_ZExt(m_Value(Op0)))) {
751 // In the signed system, the ZExt must be non-negative.
752 if (IsSigned && !cast<ZExtInst>(V)->hasNonNeg())
753 return V;
754 V = Op0;
755 } else if (match(V, m_SExt(m_Value(Op0)))) {
756 // In the unsigned system, the SExt operand must be non-negative.
757 if (!IsSigned && !Info.isKnownNonNegative(Op0))
758 return V;
759 V = Op0;
760 } else if (auto *Trunc = dyn_cast<TruncInst>(V)) {
761 if (Trunc->getSrcTy()->getScalarSizeInBits() <= 64 &&
762 isKnownNoWrap(Trunc, Info, IsSigned))
763 V = Trunc->getOperand(0);
764 }
765
766 if (match(V, m_AddLike(m_Value(Op0), m_Value(Op1)))) {
767 if (isKnownNoWrap(V, Info, IsSigned)) {
768 if (auto Decomp = MergeResults(Op0, Op1, IsSigned))
769 return *Decomp;
770 return V;
771 }
772 // In the unsigned system, adding a negative constant only wraps if Op0 is
773 // smaller than it.
774 if (!IsSigned && match(Op1, m_ConstantInt(CI)) && CI->isNegative() &&
775 canUseSExt(CI) &&
776 Info.doesHold(CmpInst::ICMP_UGE, Op0,
777 ConstantInt::get(Op0->getType(), -CI->getSExtValue())))
778 if (auto Decomp = MergeResults(Op0, CI, /*IsSignedB=*/true))
779 return *Decomp;
780 return V;
781 }
782
783 // `xor %x, -1` is equivalent to `sub nsw -1, %x`.
784 if (IsSigned && match(V, m_Not(m_Value(Op0)))) {
785 Decomposition Result(-1);
786 if (!Result.sub(decompose(Op0, Info, IsSigned, DL)))
787 return Result;
788 return V;
789 }
790
791 if (match(V, m_Sub(m_Value(Op0), m_Value(Op1)))) {
792 if (isKnownNoWrap(V, Info, IsSigned)) {
793 auto ResA = decompose(Op0, Info, IsSigned, DL);
794 auto ResB = decompose(Op1, Info, IsSigned, DL);
795 if (!ResA.sub(ResB))
796 return ResA;
797 }
798 return V;
799 }
800
801 if (match(V, m_Mul(m_Value(Op0), m_ConstantInt(CI)))) {
802 // A negative constant is only a valid coefficient in the signed system; in
803 // the unsigned system the multiplier is the constant's unsigned value.
804 if (canUseSExt(CI) && (IsSigned || !CI->isNegative()) &&
805 isKnownNoWrap(V, Info, IsSigned)) {
806 auto Result = decompose(Op0, Info, IsSigned, DL);
807 if (!Result.mul(CI->getSExtValue()))
808 return Result;
809 }
810 return V;
811 }
812
813 if (match(V, m_Shl(m_Value(Op0), m_ConstantInt(CI)))) {
814 // (shl x, shift) is (mul x, 1 << shift). The scale must fit in the signed
815 // coefficient, so reject shifts >= 63. Also reject a shift of bw-1, for
816 // which the product is not representable.
817 int64_t MaxShift = IsSigned ? Ty->getIntegerBitWidth() - 1 : 63;
818 if (!CI->isNegative() && CI->getSExtValue() < MaxShift &&
819 isKnownNoWrap(V, Info, IsSigned)) {
820 auto Result = decompose(Op0, Info, IsSigned, DL);
821 if (!Result.mul(int64_t{1} << CI->getSExtValue()))
822 return Result;
823 }
824 return V;
825 }
826
827 return V;
828}
829
830/// Build the row for 'ADec <= BDec', using the indices from \p Value2Index.
831/// Variables not in \p Value2Index are appended to \p NewVariables and get the
832/// indices following the ones in \p Value2Index. Returns an empty row if the
833/// coefficients overflow.
834static RowTy getRowForLessEqual(const Decomposition &ADec,
835 const Decomposition &BDec,
836 const DenseMap<Value *, unsigned> &Value2Index,
837 SmallVectorImpl<Value *> &NewVariables) {
838 // Build the row, by first adding all coefficients from A and then subtracting
839 // all coefficients from B.
840 int64_t OffsetSum;
841 if (SubOverflow(BDec.Offset, ADec.Offset, OffsetSum))
842 return {};
843 RowTy R(1, Entry(OffsetSum, 0));
844 auto GetCoefficient = [&R](unsigned Idx) -> int64_t & {
845 // The entry for Idx, or the place to insert it at, is the first entry with
846 // an index >= Idx.
847 Entry *I =
848 find_if(drop_begin(R), [Idx](const Entry &E) { return E.Id >= Idx; });
849 if (I == R.end() || I->Id != Idx)
850 I = R.insert(I, Entry(0, Idx));
851 return I->Coefficient;
852 };
853 // First try to look up \p V in Value2Index and NewVariables. Otherwise add a
854 // new entry to NewVariables.
855 auto GetOrAddIndex = [&Value2Index, &NewVariables](Value *V) -> unsigned {
856 auto V2I = Value2Index.find(V);
857 if (V2I != Value2Index.end())
858 return V2I->second;
859 unsigned Idx = find(NewVariables, V) - NewVariables.begin();
860 if (Idx == NewVariables.size())
861 NewVariables.push_back(V);
862 return Value2Index.size() + Idx + 1;
863 };
864 for (const DecompEntry &KV : ADec.Vars)
865 GetCoefficient(GetOrAddIndex(KV.Variable)) += KV.Coefficient;
866
867 for (const DecompEntry &KV : BDec.Vars) {
868 auto &Coeff = GetCoefficient(GetOrAddIndex(KV.Variable));
869 if (SubOverflow(Coeff, KV.Coefficient, Coeff))
870 return {};
871 }
872
873 // Drop coefficients that cancelled out.
874 erase_if(R, [](const Entry &E) { return E.Id != 0 && E.Coefficient == 0; });
875 return R;
876}
877
878ConstraintTy
879ConstraintInfo::getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
880 SmallVectorImpl<Value *> &NewVariables,
881 bool ForceSignedSystem) {
882 assert(NewVariables.empty() && "NewVariables must be empty when passed in");
883 assert((!ForceSignedSystem || CmpInst::isEquality(Pred)) &&
884 "signed system can only be forced on eq/ne");
885
886 bool IsEq = false;
887 bool IsNe = false;
888
889 // Try to convert Pred to one of ULE/ULT/SLE/SLT.
890 switch (Pred) {
894 case CmpInst::ICMP_SGE: {
895 Pred = CmpInst::getSwappedPredicate(Pred);
896 std::swap(Op0, Op1);
897 break;
898 }
899 case CmpInst::ICMP_EQ:
900 if (!ForceSignedSystem && match(Op1, m_Zero())) {
901 Pred = CmpInst::ICMP_ULE;
902 } else {
903 IsEq = true;
904 Pred = CmpInst::ICMP_ULE;
905 }
906 break;
907 case CmpInst::ICMP_NE:
908 if (!ForceSignedSystem && match(Op1, m_Zero())) {
910 std::swap(Op0, Op1);
911 } else {
912 IsNe = true;
913 Pred = CmpInst::ICMP_ULE;
914 }
915 break;
916 default:
917 break;
918 }
919
920 if (Pred != CmpInst::ICMP_ULE && Pred != CmpInst::ICMP_ULT &&
921 Pred != CmpInst::ICMP_SLE && Pred != CmpInst::ICMP_SLT)
922 return {};
923
924 bool IsSigned = ForceSignedSystem || CmpInst::isSigned(Pred);
925 auto &Value2Index = getValue2Index(IsSigned);
926 auto ADec = decompose(Op0->stripPointerCastsSameRepresentation(), *this,
927 IsSigned, DL);
928 auto BDec = decompose(Op1->stripPointerCastsSameRepresentation(), *this,
929 IsSigned, DL);
930 RowTy R = getRowForLessEqual(ADec, BDec, Value2Index, NewVariables);
931 if (R.empty())
932 return {};
933
934 if (Pred == CmpInst::ICMP_SLT || Pred == CmpInst::ICMP_ULT)
935 if (AddOverflow(R[0].Coefficient, int64_t(-1), R[0].Coefficient))
936 return {};
937
938 // Remove any new variable without a coefficient in the row.
939 unsigned NumV2I = Value2Index.size();
940 NewVariables.truncate(R.back().Id > NumV2I ? R.back().Id - NumV2I : 0);
941
942 return ConstraintTy(std::move(R), Value2Index.size() + NewVariables.size(),
943 IsSigned, IsEq, IsNe);
944}
945
946ConstraintTy ConstraintInfo::getConstraintForSolving(CmpInst::Predicate Pred,
947 Value *Op0, Value *Op1) {
948 Constant *NullC = Constant::getNullValue(Op0->getType());
949 // Handle trivially true compares directly to avoid adding V UGE 0 constraints
950 // for all variables in the unsigned system.
951 if ((Pred == CmpInst::ICMP_ULE && Op0 == NullC) ||
952 (Pred == CmpInst::ICMP_UGE && Op1 == NullC)) {
953 // Return constraint that's trivially true.
954 return ConstraintTy(RowTy(1, Entry(0, 0)), /*NumVars=*/0,
955 /*IsSigned=*/false, /*IsEq=*/false, /*IsNe=*/false);
956 }
957
958 // If both operands are known to be non-negative, change signed predicates to
959 // unsigned ones. This increases the reasoning effectiveness in combination
960 // with the signed <-> unsigned transfer logic.
961 if (CmpInst::isSigned(Pred) &&
965
966 SmallVector<Value *> NewVariables;
967 ConstraintTy R = getConstraint(Pred, Op0, Op1, NewVariables);
968 if (!NewVariables.empty())
969 return {};
970 return R;
971}
972
973std::optional<bool>
974ConstraintTy::isImpliedBy(const ConstraintSystem &CS) const {
975 const auto &[SubCS, NewCoefficients] = CS.getSubSystem(Coefficients);
976 bool IsConditionImplied = SubCS.isConditionImplied(NewCoefficients);
977
978 if (IsEq || IsNe) {
979 auto NegatedOrEqual = ConstraintSystem::negateOrEqual(NewCoefficients);
980 bool IsNegatedOrEqualImplied =
981 !NegatedOrEqual.empty() && SubCS.isConditionImplied(NegatedOrEqual);
982
983 // In order to check that `%a == %b` is true (equality), both conditions `%a
984 // >= %b` and `%a <= %b` must hold true. When checking for equality (`IsEq`
985 // is true), we return true if they both hold, false in the other cases.
986 if (IsConditionImplied && IsNegatedOrEqualImplied)
987 return IsEq;
988
989 auto Negated = ConstraintSystem::negate(NewCoefficients);
990 bool IsNegatedImplied =
991 !Negated.empty() && SubCS.isConditionImplied(Negated);
992
993 auto StrictLessThan = ConstraintSystem::toStrictLessThan(NewCoefficients);
994 bool IsStrictLessThanImplied =
995 !StrictLessThan.empty() && SubCS.isConditionImplied(StrictLessThan);
996
997 // In order to check that `%a != %b` is true (non-equality), either
998 // condition `%a > %b` or `%a < %b` must hold true. When checking for
999 // non-equality (`IsNe` is true), we return true if one of the two holds,
1000 // false in the other cases.
1001 if (IsNegatedImplied || IsStrictLessThanImplied)
1002 return IsNe;
1003
1004 return std::nullopt;
1005 }
1006
1007 if (IsConditionImplied)
1008 return true;
1009
1010 auto Negated = ConstraintSystem::negate(NewCoefficients);
1011 auto IsNegatedImplied = !Negated.empty() && SubCS.isConditionImplied(Negated);
1012 if (IsNegatedImplied)
1013 return false;
1014
1015 // Neither the condition nor its negated holds, did not prove anything.
1016 return std::nullopt;
1017}
1018
1019bool ConstraintInfo::doesHold(CmpInst::Predicate Pred, Value *A, Value *B) {
1020 auto R = getConstraintForSolving(Pred, A, B);
1021 return !R.empty() &&
1022 getCS(R.IsSigned).isConditionImpliedInSubSystem(R.Coefficients);
1023}
1024
1025bool ConstraintInfo::isKnownNonNegative(Value *V) {
1026 if (auto *CI = dyn_cast<ConstantInt>(V))
1027 return !CI->isNegative();
1028 return ::isKnownNonNegative(V, DL) ||
1029 doesHold(CmpInst::ICMP_SGE, V, ConstantInt::get(V->getType(), 0));
1030}
1031
1032bool ConstraintInfo::isKnownPositive(Value *V) {
1033 if (auto *CI = dyn_cast<ConstantInt>(V))
1034 return CI->getValue().isStrictlyPositive();
1035 return ::isKnownPositive(V, DL) ||
1036 doesHold(CmpInst::ICMP_SGT, V, ConstantInt::get(V->getType(), 0));
1037}
1038
1039void ConstraintInfo::transferToOtherSystem(
1040 CmpInst::Predicate Pred, Value *A, Value *B, unsigned NumIn,
1041 unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack) {
1042 // Check if we can combine facts from the signed and unsigned systems to
1043 // derive additional facts.
1044 if (!A->getType()->isIntegerTy())
1045 return;
1046 // FIXME: This currently depends on the order we add facts. Ideally we
1047 // would first add all known facts and only then try to add additional
1048 // facts.
1049 switch (Pred) {
1050 default:
1051 break;
1052 case CmpInst::ICMP_ULT:
1053 case CmpInst::ICMP_ULE:
1054 // If B is a signed positive constant, then A >=s 0 and A <s (or <=s) B.
1055 if (isKnownNonNegative(B)) {
1056 addFact(CmpInst::ICMP_SGE, A, ConstantInt::get(B->getType(), 0), NumIn,
1057 NumOut, DFSInStack);
1058 addFact(ICmpInst::getSignedPredicate(Pred), A, B, NumIn, NumOut,
1059 DFSInStack);
1060 }
1061 break;
1062 case CmpInst::ICMP_UGE:
1063 case CmpInst::ICMP_UGT:
1064 // If A is a signed positive constant, then B >=s 0 and A >s (or >=s) B.
1065 if (isKnownNonNegative(A)) {
1066 addFact(CmpInst::ICMP_SGE, B, ConstantInt::get(B->getType(), 0), NumIn,
1067 NumOut, DFSInStack);
1068 addFact(ICmpInst::getSignedPredicate(Pred), A, B, NumIn, NumOut,
1069 DFSInStack);
1070 }
1071 break;
1072 case CmpInst::ICMP_SLT:
1073 case CmpInst::ICMP_SLE:
1074 if (isKnownNonNegative(A))
1075 addFact(ICmpInst::getUnsignedPredicate(Pred), A, B, NumIn, NumOut,
1076 DFSInStack);
1077 break;
1078 case CmpInst::ICMP_SGT: {
1079 if (doesHold(CmpInst::ICMP_SGE, B, Constant::getAllOnesValue(B->getType())))
1080 addFact(CmpInst::ICMP_UGE, A, ConstantInt::get(B->getType(), 0), NumIn,
1081 NumOut, DFSInStack);
1082 if (isKnownNonNegative(B))
1083 addFact(CmpInst::ICMP_UGT, A, B, NumIn, NumOut, DFSInStack);
1084
1085 break;
1086 }
1087 case CmpInst::ICMP_SGE:
1088 if (isKnownNonNegative(B))
1089 addFact(CmpInst::ICMP_UGE, A, B, NumIn, NumOut, DFSInStack);
1090 break;
1091 }
1092}
1093
1094#ifndef NDEBUG
1095
1097 const DenseMap<Value *, unsigned> &Value2Index) {
1098 ConstraintSystem CS(Value2Index);
1099 CS.addRow(C, Value2Index.size());
1100 CS.dump();
1101}
1102#endif
1103
1104/// Splits the induction phi \p PN into the start value, coming from the loop
1105/// predecessor \p LoopPred, and the backedge value, coming from inside the
1106/// loop. Returns {nullptr, nullptr} if \p PN has other incoming values.
1107static std::pair<Value *, Value *>
1108getStartAndBackedgeValue(const PHINode &PN, const BasicBlock *LoopPred) {
1109 assert(PN.getBasicBlockIndex(LoopPred) >= 0 &&
1110 "LoopPred must be a predecessor of the phi's block");
1111 if (PN.getNumIncomingValues() != 2)
1112 return {nullptr, nullptr};
1113 unsigned StartIdx = PN.getIncomingBlock(0) == LoopPred ? 0 : 1;
1114 return {PN.getIncomingValue(StartIdx), PN.getIncomingValue(1 - StartIdx)};
1115}
1116
1117/// Matches an increment of \p PhiM by a constant offset, captured in \p Off.
1118/// The increment must be a plain IR add or [u|s]add.with.overflow.
1119template <typename PhiMatchTy>
1120static auto m_IncrementOf(const PhiMatchTy &PhiM, const APInt *&Off) {
1121 return m_CombineOr(
1122 m_c_Add(PhiM, m_APInt(Off)),
1126}
1127
1128MonotonicInfo State::getMonotonicityInfo(PHINode &PN, Value *Step) {
1129 MonotonicInfo Info;
1130 const APInt *StepOffset = nullptr;
1131 if (match(Step, m_IncrementOf(m_Specific(&PN), StepOffset))) {
1132 Info.Decreasing = StepOffset->isNegative();
1133 if (const auto *Add = dyn_cast<OverflowingBinaryOperator>(Step)) {
1134 Info.Unsigned = !Info.Decreasing && Add->hasNoUnsignedWrap();
1135 Info.Signed = Add->hasNoSignedWrap();
1136 }
1137 } else if (const auto *GEP = dyn_cast<GEPOperator>(Step)) {
1138 // TODO: Handle the non-increasing direction, which needs a nusw GEP with a
1139 // negative constant offset.
1140 const DataLayout &DL = PN.getDataLayout();
1141 APInt GEPOffset(DL.getIndexTypeSizeInBits(GEP->getType()), 0);
1142 Info.Unsigned = GEP->getPointerOperand() == &PN &&
1143 (GEP->hasNoUnsignedWrap() ||
1144 ((GEP->hasNoUnsignedSignedWrap() &&
1145 GEP->accumulateConstantOffset(DL, GEPOffset) &&
1146 !GEPOffset.isNegative())));
1147 }
1148
1149 // Forming the SCEV of a phi is expensive, so only consult it for a PN + C
1150 // step whose no-wrap flags prove nothing.
1151 if (Info.Unsigned || Info.Signed || !StepOffset)
1152 return Info;
1153
1154 const auto *AR = dyn_cast<SCEVAddRecExpr>(SE->getSCEV(&PN));
1155 if (!AR)
1156 return Info;
1160 auto IsMonotonic = [&](CmpInst::Predicate Pred) {
1161 return SE->getMonotonicPredicateType(AR, Pred) == Expected;
1162 };
1163 Info.Signed = IsMonotonic(CmpInst::ICMP_SGT);
1164 Info.Unsigned = !Info.Decreasing && IsMonotonic(CmpInst::ICMP_UGT);
1165 return Info;
1166}
1167
1168void State::addBoundsForHeaderInductions(BasicBlock &BB) {
1169 Loop *L = LI.getLoopFor(&BB);
1170 if (!L || L->getHeader() != &BB)
1171 return;
1172 BasicBlock *LoopPred = L->getLoopPredecessor();
1173 if (!LoopPred)
1174 return;
1175
1176 DomTreeNode *DTN = DT.getNode(&BB);
1177 for (PHINode &PN : BB.phis()) {
1178 if (!PN.getType()->isIntegerTy() && !PN.getType()->isPointerTy())
1179 continue;
1180
1181 auto [Start, Step] = getStartAndBackedgeValue(PN, LoopPred);
1182 if (!Start)
1183 continue;
1184
1185 MonotonicInfo Info = getMonotonicityInfo(PN, Step);
1186 // Every variable in the unsigned system already has a `V >= 0` row, so a
1187 // zero start value would just duplicate it.
1188 if (match(Start, m_Zero()))
1189 Info.Unsigned = false;
1190 if (!Info.Unsigned && !Info.Signed)
1191 continue;
1192
1193 // A non-decreasing induction cannot step below its start value, and a
1194 // non-increasing one cannot step above it.
1195 Value *LHS = &PN, *RHS = Start;
1196 if (Info.Decreasing)
1197 std::swap(LHS, RHS);
1198 CmpPredicate Pred(Info.Unsigned ? CmpInst::ICMP_UGE : CmpInst::ICMP_SGE,
1199 /*HasSameSign=*/Info.Unsigned && Info.Signed);
1200 WorkList.push_back(FactOrCheck::getConditionFact(DTN, Pred, LHS, RHS));
1201 }
1202}
1203
1204void State::addInfoForInductions(BasicBlock &BB) {
1205 auto *L = LI.getLoopFor(&BB);
1206 if (!L)
1207 return;
1208
1209 BasicBlock *Header = L->getHeader();
1210 BasicBlock *Latch = L->getLoopLatch();
1211 if (Header != &BB && Latch != &BB)
1212 return;
1213
1214 // A is either a phi or a post-increment PN + C with constant step. For the
1215 // latter, extract the constant IncStep.
1216 Value *A;
1217 Value *B;
1218 PHINode *PN = nullptr;
1219 const APInt *IncStep = nullptr;
1220 CmpPredicate Pred;
1221 auto IndValue =
1222 m_Value(A, m_CombineOr(m_Phi(PN), m_IncrementOf(m_Phi(PN), IncStep)));
1223
1224 auto *Br = dyn_cast<CondBrInst>(BB.getTerminator());
1225 if (!Br)
1226 return;
1227
1228 auto CountingCmp = m_c_ICmp(Pred, IndValue, m_Value(B));
1229 std::optional<bool> PeeledOnEdge;
1230 if (!match(Br->getCondition(), CountingCmp)) {
1231 // Look through AND/OR, and remember which edge requires all operands to be
1232 // true.
1233 if (match(Br->getCondition(), m_c_LogicalAnd(CountingCmp, m_Value())))
1234 PeeledOnEdge = true;
1235 else if (match(Br->getCondition(), m_c_LogicalOr(CountingCmp, m_Value())))
1236 PeeledOnEdge = false;
1237 else
1238 return;
1239 }
1240
1241 if (PN->getParent() != Header || PN->getNumIncomingValues() != 2 ||
1242 !SE->isSCEVable(PN->getType()))
1243 return;
1244
1245 // For latch conditions, we need to inject the condition that holds for the
1246 // next iteration into the header. We limit to post-inc conditions, for which
1247 // an original PN + Step != B condition results in a PN < B constraint in the
1248 // header, which also holds for the next loop iteration. This would no longer
1249 // be correct if the post-inc handling would inject a more precise PN + Step <
1250 // B constraint instead.
1251 if (&BB == Latch && !IncStep)
1252 return;
1253
1254 bool ContinueOnTrue =
1255 Pred == CmpInst::ICMP_NE || ICmpInst::isLT(Pred) || ICmpInst::isLE(Pred);
1256 CmpInst::Predicate ContinuePred =
1257 ContinueOnTrue ? Pred.dropSameSign() : CmpInst::getInversePredicate(Pred);
1258 BasicBlock *InLoopSucc = Br->getSuccessor(ContinueOnTrue ? 0 : 1);
1259
1260 // The peeled condition only implies the compare on the edge where the
1261 // combined condition forces its operands, which must be the in-loop edge.
1262 if (PeeledOnEdge && *PeeledOnEdge != ContinueOnTrue)
1263 return;
1264
1265 if (!L->contains(InLoopSucc) || !L->isLoopExiting(&BB))
1266 return;
1267
1268 BasicBlock *LoopPred = L->getLoopPredecessor();
1269 if (!LoopPred || !L->isLoopInvariant(B))
1270 return;
1271
1272 auto [StartValue, Backedge] = getStartAndBackedgeValue(*PN, LoopPred);
1273 DomTreeNode *DTN = DT.getNode(InLoopSucc);
1274
1275 if (ICmpInst::isRelational(ContinuePred)) {
1276 if (A != Backedge)
1277 return;
1278
1279 // The latch condition ensures ContinuePred holds in the header on each
1280 // iteration other than the first. Together with a precondition on the start
1281 // value (StartValue ContinuePred B), we can add B as bound of PN.
1282 WorkList.push_back(FactOrCheck::getConditionFact(
1283 DTN, ContinuePred, PN, B, ConditionTy(ContinuePred, StartValue, B)));
1284
1285 // A signed bound can be translated to the unsigned system if PN is signed
1286 // non-decreasing (StartValue s<= PN s< B) and StartValue u< B holds.
1287 // Then StartValue, PN and B must all have the same sign.
1288 if (ICmpInst::isSigned(ContinuePred)) {
1289 assert((ContinuePred == CmpInst::ICMP_SLT ||
1290 ContinuePred == CmpInst::ICMP_SLE) &&
1291 "Expected a signed less-than continuation predicate");
1292 MonotonicInfo Info = getMonotonicityInfo(*PN, Backedge);
1293 if (Info.Signed && !Info.Decreasing) {
1295 WorkList.push_back(FactOrCheck::getConditionFact(
1296 DTN, UPred, PN, B, ConditionTy(UPred, StartValue, B)));
1297 }
1298 }
1299
1300 // A relational latch steps past B rather than landing on it, so none of the
1301 // reasoning below applies.
1302 return;
1303 }
1304
1305 const APInt *StepOffset = nullptr;
1306 const SCEV *StartSCEV = nullptr;
1307 if (match(Backedge, m_c_Add(m_Specific(PN), m_APInt(StepOffset)))) {
1308 if (StepOffset->isZero())
1309 return;
1310 } else {
1311 const SCEV *Expr = SE->getSCEV(PN);
1312 if (!match(Expr,
1313 m_scev_AffineAddRec(m_SCEV(StartSCEV), m_scev_APInt(StepOffset),
1314 m_SpecificLoop(L))))
1315 return;
1316 }
1317
1318 // If we looked through `PN + C`, only derive facts when that add is
1319 // really the induction's post-increment or post-decrement.
1320 if (IncStep && *IncStep != *StepOffset)
1321 return;
1322
1323 MonotonicInfo Info = getMonotonicityInfo(*PN, Backedge);
1324
1325 // Handle negative steps.
1326 if (StepOffset->isNegative()) {
1327 // TODO: Extend to allow steps > -1.
1328 if (!(-*StepOffset).isOne())
1329 return;
1330
1331 // AR may wrap.
1332 // The loop exits once the compared value reaches B, that is at PN == B when
1333 // comparing the phi, and at PN == B + 1 for a post-decrement. Use
1334 // non-strict predicate for the former, and a strict one for the latter to
1335 // ensure the loop exits before wrapping.
1336 CmpInst::Predicate UPrecond =
1338 ConditionTy BBeforeStartUnsigned = {UPrecond, B, StartValue};
1339 ConditionTy BBeforeStartSigned = {ICmpInst::getSignedPredicate(UPrecond), B,
1340 StartValue};
1341
1342 // AR may wrap, so both facts are conditional on B being below StartValue.
1343 // Add StartValue >= PN, which holds as the loop exits before wrapping.
1344 WorkList.push_back(FactOrCheck::getConditionFact(
1345 DTN, CmpInst::ICMP_UGE, StartValue, PN, BBeforeStartUnsigned));
1346 if (!(Info.Decreasing && Info.Signed))
1347 WorkList.push_back(FactOrCheck::getConditionFact(
1348 DTN, CmpInst::ICMP_SGE, StartValue, PN, BBeforeStartSigned));
1349 // Add PN > B, which holds as the loop exits when reaching B.
1350 WorkList.push_back(FactOrCheck::getConditionFact(DTN, CmpInst::ICMP_UGT, PN,
1351 B, BBeforeStartUnsigned));
1352 WorkList.push_back(FactOrCheck::getConditionFact(DTN, CmpInst::ICMP_SGT, PN,
1353 B, BBeforeStartSigned));
1354 return;
1355 }
1356
1357 // Make sure AR either steps by 1 or that the value we compare against is a
1358 // GEP based on the same start value and all offsets are a multiple of the
1359 // step size, to guarantee that the induction will reach the value.
1360 if (StepOffset->isZero() || StepOffset->isNegative())
1361 return;
1362
1363 if (!StepOffset->isOne()) {
1364 // Check whether B-Start is known to be a multiple of StepOffset.
1365 if (!StartSCEV)
1366 StartSCEV = SE->getSCEV(StartValue);
1367 const SCEV *BMinusStart = SE->getMinusSCEV(SE->getSCEV(B), StartSCEV);
1368 if (isa<SCEVCouldNotCompute>(BMinusStart) ||
1369 !SE->getConstantMultiple(BMinusStart).urem(*StepOffset).isZero())
1370 return;
1371 }
1372
1373 // We already established that B - Start is a multiple of Step above. The loop
1374 // exits once the compared value reaches B, that is at PN == B when comparing
1375 // the phi, and at PN + Step == B for a post-increment. Together with the
1376 // added precondition StartValue <= B for the former and the strict
1377 // StartValue < B for the latter (which implies StartValue + Step <= B),
1378 // neither PN nor the increment can wrap.
1380 ConditionTy StartBeforeBoundUnsigned = {UPrecond, StartValue, B};
1381 ConditionTy StartBeforeBoundSigned = {ICmpInst::getSignedPredicate(UPrecond),
1382 StartValue, B};
1383
1384 // Add PN >= StartValue, as the loop exits before wrapping.
1385 if (!Info.Unsigned)
1386 WorkList.push_back(FactOrCheck::getConditionFact(
1387 DTN, CmpInst::ICMP_UGE, PN, StartValue, StartBeforeBoundUnsigned));
1388 if (!Info.Signed)
1389 WorkList.push_back(FactOrCheck::getConditionFact(
1390 DTN, CmpInst::ICMP_SGE, PN, StartValue, StartBeforeBoundSigned));
1391 // Add PN < B, as the loop exits once the compared value reaches B.
1392 WorkList.push_back(FactOrCheck::getConditionFact(DTN, CmpInst::ICMP_SLT, PN,
1393 B, StartBeforeBoundSigned));
1394 WorkList.push_back(FactOrCheck::getConditionFact(
1395 DTN, CmpInst::ICMP_ULT, PN, B, StartBeforeBoundUnsigned));
1396
1397 // Try to add condition from the header or latch to the dedicated exit
1398 // blocks. When exiting either with EQ or NE, we know that the induction value
1399 // must be u<= B, as other exits may only exit earlier.
1400 assert(!StepOffset->isNegative() && "induction must be increasing");
1401 assert(ContinuePred == CmpInst::ICMP_NE && "unsupported predicate");
1403 L->getExitBlocks(ExitBBs);
1404 for (BasicBlock *EB : ExitBBs) {
1405 // Bail out on non-dedicated exits.
1406 if (DT.dominates(&BB, EB)) {
1407 WorkList.emplace_back(FactOrCheck::getConditionFact(
1408 DT.getNode(EB), CmpInst::ICMP_ULE, A, B, StartBeforeBoundUnsigned));
1409 }
1410 }
1411}
1412
1414 uint64_t AccessSize,
1415 CmpPredicate &Pred, Value *&A,
1416 Value *&B, const DataLayout &DL,
1417 const TargetLibraryInfo &TLI) {
1418 if (!GEP.hasNoUnsignedWrap())
1419 return false;
1420
1421 Value *Base = GEP.getPointerOperand();
1422 if (auto *InnerGEP = dyn_cast<GetElementPtrInst>(Base))
1423 Base = InnerGEP->getPointerOperand();
1424
1425 ObjectSizeOpts Opts;
1426 // Workaround for gep inbounds, ptr null, idx.
1427 Opts.NullIsUnknownSize = true;
1428 // Be conservative since we are not clear on whether an out of bounds access
1429 // to the padding is UB or not.
1430 Opts.RoundToAlign = true;
1431 std::optional<TypeSize> Size = getBaseObjectSize(Base, DL, &TLI, Opts);
1432 if (!Size || Size->isScalable())
1433 return false;
1434
1436 if (Offset.BasePtr != Base || !Offset.NW.hasNoUnsignedWrap())
1437 return false;
1438
1439 if (Offset.VariableOffsets.size() != 1)
1440 return false;
1441
1442 uint64_t BitWidth = Offset.ConstantOffset.getBitWidth();
1443 auto &[Index, Scale] = Offset.VariableOffsets.front();
1444 // Bail out on non-canonical GEPs.
1445 if (Index->getType()->getScalarSizeInBits() != BitWidth)
1446 return false;
1447
1448 // Index * Scale + ConstOffset + AccessSize <= AllocSize
1449 // With nuw flag, we know that the index addition doesn't have unsigned wrap.
1450 // If (AllocSize - (ConstOffset + AccessSize)) wraps around, there is no valid
1451 // value for Index.
1452 APInt MaxIndex = (APInt(BitWidth, Size->getFixedValue() - AccessSize,
1453 /*isSigned=*/false, /*implicitTrunc=*/true) -
1454 Offset.ConstantOffset)
1455 .udiv(Scale);
1456 Pred = ICmpInst::ICMP_ULE;
1457 A = Index;
1458 B = ConstantInt::get(Index->getType(), MaxIndex);
1459 return true;
1460}
1461
1462/// Returns true if \p I is a candidate whose poison-generating flags may be
1463/// strengthened using the constraint systems.
1465 if (auto *Trunc = dyn_cast<TruncInst>(I))
1466 return Trunc->getType()->isIntegerTy() && Trunc->hasNoSignedWrap() &&
1467 !Trunc->hasNoUnsignedWrap();
1468
1469 auto *BO = dyn_cast<BinaryOperator>(I);
1470 if (!BO || !BO->getType()->isIntegerTy())
1471 return false;
1472
1473 switch (BO->getOpcode()) {
1474 case Instruction::Sub:
1475 if (BO->hasNoUnsignedWrap() && BO->hasNoSignedWrap())
1476 return false;
1477 // A - B does not wrap unsigned if A >=u B, and does not wrap signed if
1478 // 0 <=s B <=s A. With a constant B, bounds on A can refine both flags.
1479 return true;
1480 case Instruction::Add:
1481 case Instruction::Mul:
1482 case Instruction::Shl:
1483 if (BO->hasNoUnsignedWrap() && BO->hasNoSignedWrap())
1484 return false;
1485 // With a constant second operand, we can use bounds on the first operand to
1486 // refine no-wrap flags. Independently, nuw can be added for nsw if the
1487 // operands are non-negative.
1488 return isa<ConstantInt>(BO->getOperand(1)) || BO->hasNoSignedWrap();
1489 default:
1490 return false;
1491 }
1492}
1493
1494/// Try to strengthen \p I's poison generating flags using \p Info. Returns
1495/// true if \p I was modified.
1496static bool tryToStrengthenFlags(Instruction *I, ConstraintInfo &Info) {
1497 assert(canStrengthenFlags(I) && "not a candidate for flag strengthening");
1498
1499 bool Changed = false;
1500 if (!I->hasNoSignedWrap() && isKnownNoWrap(I, Info, /*Signed=*/true)) {
1501 LLVM_DEBUG(dbgs() << "Adding nsw to " << *I << "\n");
1502 I->setHasNoSignedWrap();
1503 Changed = true;
1504 }
1505 if (!I->hasNoUnsignedWrap() && isKnownNoWrap(I, Info, /*Signed=*/false)) {
1506 LLVM_DEBUG(dbgs() << "Adding nuw to " << *I << "\n");
1507 I->setHasNoUnsignedWrap();
1508 Changed = true;
1509 }
1510 return Changed;
1511}
1512
1513void State::addInfoFor(BasicBlock &BB) {
1514 addBoundsForHeaderInductions(BB);
1515 addInfoForInductions(BB);
1516 auto &DL = BB.getDataLayout();
1517
1518 Value *A, *B;
1519 CmpPredicate Pred;
1520 // True as long as the current instruction is guaranteed to execute.
1521 bool GuaranteedToExecute = true;
1522 // Queue conditions and assumes.
1523 for (Instruction &I : BB) {
1524 if (match(&I, m_ICmpLike(Pred, m_Value(), m_Value()))) {
1525 for (Use &U : I.uses()) {
1526 auto *UserI = getContextInstForUse(U);
1527 auto *DTN = DT.getNode(UserI->getParent());
1528 if (!DTN)
1529 continue;
1530 WorkList.push_back(FactOrCheck::getCheck(DTN, &U));
1531 }
1532 continue;
1533 }
1534
1535 auto AddFactFromMemoryAccess = [&](Value *Ptr, Type *AccessType) {
1536 auto *GEP = dyn_cast<GetElementPtrInst>(Ptr);
1537 if (!GEP)
1538 return;
1539 TypeSize AccessSize = DL.getTypeStoreSize(AccessType);
1540 if (!AccessSize.isFixed())
1541 return;
1542 if (GuaranteedToExecute) {
1544 Pred, A, B, DL, TLI)) {
1545 // The memory access is guaranteed to execute when BB is entered,
1546 // hence the constraint holds on entry to BB.
1547 WorkList.emplace_back(FactOrCheck::getConditionFact(
1548 DT.getNode(I.getParent()), Pred, A, B));
1549 }
1550 } else {
1551 WorkList.emplace_back(
1552 FactOrCheck::getInstFact(DT.getNode(I.getParent()), &I));
1553 }
1554 };
1555
1556 if (auto *LI = dyn_cast<LoadInst>(&I)) {
1557 if (!LI->isVolatile())
1558 AddFactFromMemoryAccess(LI->getPointerOperand(), LI->getAccessType());
1559 }
1560 if (auto *SI = dyn_cast<StoreInst>(&I)) {
1561 if (!SI->isVolatile())
1562 AddFactFromMemoryAccess(SI->getPointerOperand(), SI->getAccessType());
1563 }
1564
1565 auto *II = dyn_cast<IntrinsicInst>(&I);
1566 Intrinsic::ID ID = II ? II->getIntrinsicID() : Intrinsic::not_intrinsic;
1567 switch (ID) {
1568 case Intrinsic::assume: {
1569 if (!match(I.getOperand(0), m_ICmpLike(Pred, m_Value(A), m_Value(B))))
1570 break;
1571 if (GuaranteedToExecute) {
1572 // The assume is guaranteed to execute when BB is entered, hence Cond
1573 // holds on entry to BB.
1574 WorkList.emplace_back(FactOrCheck::getConditionFact(
1575 DT.getNode(I.getParent()), Pred, A, B));
1576 } else {
1577 WorkList.emplace_back(
1578 FactOrCheck::getInstFact(DT.getNode(I.getParent()), &I));
1579 }
1580 break;
1581 }
1582 // Enqueue intrinsics for simplification.
1583 case Intrinsic::uadd_with_overflow:
1584 case Intrinsic::sadd_with_overflow:
1585 case Intrinsic::usub_with_overflow:
1586 case Intrinsic::ssub_with_overflow:
1587 case Intrinsic::umul_with_overflow:
1588 case Intrinsic::smul_with_overflow:
1589 case Intrinsic::ucmp:
1590 case Intrinsic::scmp:
1591 WorkList.push_back(
1592 FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
1593 break;
1594 // Enqueue the intrinsics to add extra info.
1595 case Intrinsic::umin:
1596 case Intrinsic::umax:
1597 case Intrinsic::smin:
1598 case Intrinsic::smax:
1599 case Intrinsic::usub_sat:
1600 // TODO: handle llvm.abs as well
1601 WorkList.push_back(
1602 FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
1603 [[fallthrough]];
1604 case Intrinsic::uadd_sat:
1605 // TODO: Check if it is possible to instead only added the min/max facts
1606 // when simplifying uses of the min/max intrinsics.
1608 break;
1609 [[fallthrough]];
1610 case Intrinsic::abs:
1611 WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I));
1612 break;
1613 }
1614
1615 // Add facts from unsigned division, remainder and logical shift right, and
1616 // from signed division and remainder.
1617 // urem x, n: result < n and result <= x
1618 // udiv x, n: result <= x
1619 // lshr x, n: result <= x
1620 // srem x, n: result >= 0 and result <= x, if x >= 0
1621 // result < n, if n > 0
1622 // sdiv x, n: result >= 0 and result <= x, if x >= 0 and n > 0
1623 // result >= 0 and result < x, if x > 0 and n > 1
1624 if (auto *BO = dyn_cast<BinaryOperator>(&I)) {
1625 if ((BO->getOpcode() == Instruction::URem ||
1626 BO->getOpcode() == Instruction::UDiv ||
1627 BO->getOpcode() == Instruction::LShr ||
1628 BO->getOpcode() == Instruction::SRem ||
1629 BO->getOpcode() == Instruction::SDiv) &&
1631 WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), BO));
1632 }
1633
1634 // Queue instructions whose flags may be strengthened, checked at the
1635 // closest point dominating all uses.
1636 if (canStrengthenFlags(&I)) {
1637 Instruction *CommonDom = findCommonDominatorOfUses(I, DT);
1638 WorkList.push_back(FactOrCheck::getCheck(
1639 DT.getNode(CommonDom->getParent()), &I, CommonDom));
1640 }
1641
1642 GuaranteedToExecute &= isGuaranteedToTransferExecutionToSuccessor(&I);
1643 }
1644
1645 if (auto *Switch = dyn_cast<SwitchInst>(BB.getTerminator())) {
1646 for (auto &Case : Switch->cases()) {
1647 BasicBlock *Succ = Case.getCaseSuccessor();
1648 Value *V = Case.getCaseValue();
1649 if (!canAddSuccessor(BB, Succ))
1650 continue;
1651 WorkList.emplace_back(FactOrCheck::getConditionFact(
1652 DT.getNode(Succ), CmpInst::ICMP_EQ, Switch->getCondition(), V));
1653 }
1654 return;
1655 }
1656
1657 auto *Br = dyn_cast<CondBrInst>(BB.getTerminator());
1658 if (!Br)
1659 return;
1660
1661 Value *Cond = Br->getCondition();
1662
1663 // If the condition is a chain of ORs/AND and the successor only has the
1664 // current block as predecessor, queue conditions for the successor.
1665 Value *Op0, *Op1;
1666 if (match(Cond, m_LogicalOr(m_Value(Op0), m_Value(Op1))) ||
1667 match(Cond, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) {
1668 bool IsOr = match(Cond, m_LogicalOr());
1669 bool IsAnd = match(Cond, m_LogicalAnd());
1670 // If there's a select that matches both AND and OR, we need to commit to
1671 // one of the options. Arbitrarily pick OR.
1672 if (IsOr && IsAnd)
1673 IsAnd = false;
1674
1675 BasicBlock *Successor = Br->getSuccessor(IsOr ? 1 : 0);
1676 if (canAddSuccessor(BB, Successor)) {
1677 SmallVector<Value *> CondWorkList;
1678 SmallPtrSet<Value *, 8> SeenCond;
1679 auto QueueValue = [&CondWorkList, &SeenCond](Value *V) {
1680 if (SeenCond.insert(V).second)
1681 CondWorkList.push_back(V);
1682 };
1683 QueueValue(Op1);
1684 QueueValue(Op0);
1685 while (!CondWorkList.empty()) {
1686 Value *Cur = CondWorkList.pop_back_val();
1687 if (match(Cur, m_ICmpLike(Pred, m_Value(A), m_Value(B)))) {
1688 WorkList.emplace_back(FactOrCheck::getConditionFact(
1689 DT.getNode(Successor),
1690 IsOr ? CmpPredicate::getInverse(Pred) : Pred, A, B));
1691 continue;
1692 }
1693 if (IsOr && match(Cur, m_LogicalOr(m_Value(Op0), m_Value(Op1)))) {
1694 QueueValue(Op1);
1695 QueueValue(Op0);
1696 continue;
1697 }
1698 if (IsAnd && match(Cur, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) {
1699 QueueValue(Op1);
1700 QueueValue(Op0);
1701 continue;
1702 }
1703 }
1704 }
1705 return;
1706 }
1707
1708 if (!match(Br->getCondition(), m_ICmpLike(Pred, m_Value(A), m_Value(B))))
1709 return;
1710 if (canAddSuccessor(BB, Br->getSuccessor(0)))
1711 WorkList.emplace_back(FactOrCheck::getConditionFact(
1712 DT.getNode(Br->getSuccessor(0)), Pred, A, B));
1713 if (canAddSuccessor(BB, Br->getSuccessor(1)))
1714 WorkList.emplace_back(FactOrCheck::getConditionFact(
1715 DT.getNode(Br->getSuccessor(1)), CmpPredicate::getInverse(Pred), A, B));
1716}
1717
1718#ifndef NDEBUG
1720 Value *LHS, Value *RHS) {
1721 OS << "icmp " << Pred << ' ';
1722 LHS->printAsOperand(OS, /*PrintType=*/true);
1723 OS << ", ";
1724 RHS->printAsOperand(OS, /*PrintType=*/false);
1725}
1726#endif
1727
1728namespace {
1729/// Helper to keep track of a condition and if it should be treated as negated
1730/// for reproducer construction.
1731/// Pred == Predicate::BAD_ICMP_PREDICATE indicates that this entry is a
1732/// placeholder to keep the ReproducerCondStack in sync with DFSInStack.
1733struct ReproducerEntry {
1734 ICmpInst::Predicate Pred;
1735 Value *LHS;
1736 Value *RHS;
1737
1738 ReproducerEntry(ICmpInst::Predicate Pred, Value *LHS, Value *RHS)
1739 : Pred(Pred), LHS(LHS), RHS(RHS) {}
1740};
1741} // namespace
1742
1743/// Helper function to generate a reproducer function for simplifying \p Cond.
1744/// The reproducer function contains a series of @llvm.assume calls, one for
1745/// each condition in \p Stack. For each condition, the operand instruction are
1746/// cloned until we reach operands that have an entry in \p Value2Index. Those
1747/// will then be added as function arguments. \p DT is used to order cloned
1748/// instructions. The reproducer function will get added to \p M, if it is
1749/// non-null. Otherwise no reproducer function is generated.
1750static void generateReproducer(Instruction *Cond, bool IsSigned, Module *M,
1752 ConstraintInfo &Info, DominatorTree &DT) {
1753 if (!M)
1754 return;
1755
1756 LLVMContext &Ctx = Cond->getContext();
1757
1758 LLVM_DEBUG(dbgs() << "Creating reproducer for " << *Cond << "\n");
1759
1760 ValueToValueMapTy Old2New;
1763 // Traverse Cond and its operands recursively until we reach a value that's in
1764 // Value2Index or not an instruction, or not a operation that
1765 // ConstraintElimination can decompose. Such values will be considered as
1766 // external inputs to the reproducer, they are collected and added as function
1767 // arguments later.
1768 auto CollectArguments = [&](ArrayRef<Value *> Ops, bool IsSigned) {
1769 auto &Value2Index = Info.getValue2Index(IsSigned);
1770 SmallVector<Value *, 4> WorkList(Ops);
1771 while (!WorkList.empty()) {
1772 Value *V = WorkList.pop_back_val();
1773 if (!Seen.insert(V).second)
1774 continue;
1775 if (Old2New.find(V) != Old2New.end())
1776 continue;
1777 if (isa<Constant>(V))
1778 continue;
1779
1780 auto *I = dyn_cast<Instruction>(V);
1781 if (Value2Index.contains(V) || !I ||
1783 Old2New[V] = V;
1784 Args.push_back(V);
1785 LLVM_DEBUG(dbgs() << " found external input " << *V << "\n");
1786 } else {
1787 append_range(WorkList, I->operands());
1788 }
1789 }
1790 };
1791
1792 for (auto &Entry : Stack)
1793 if (Entry.Pred != ICmpInst::BAD_ICMP_PREDICATE)
1794 CollectArguments({Entry.LHS, Entry.RHS}, ICmpInst::isSigned(Entry.Pred));
1795 CollectArguments(Cond, IsSigned);
1796
1797 SmallVector<Type *> ParamTys;
1798 for (auto *P : Args)
1799 ParamTys.push_back(P->getType());
1800
1801 FunctionType *FTy = FunctionType::get(Cond->getType(), ParamTys,
1802 /*isVarArg=*/false);
1804 Cond->getModule()->getName() +
1805 Cond->getFunction()->getName() + "repro",
1806 M);
1807 // Add arguments to the reproducer function for each external value collected.
1808 for (unsigned I = 0; I < Args.size(); ++I) {
1809 F->getArg(I)->setName(Args[I]->getName());
1810 Old2New[Args[I]] = F->getArg(I);
1811 }
1812
1813 BasicBlock *Entry = BasicBlock::Create(Ctx, "entry", F);
1814 IRBuilder<> Builder(Entry);
1815 Builder.CreateRet(Builder.getTrue());
1816 Builder.SetInsertPoint(Entry->getTerminator());
1817
1818 // Clone instructions in \p Ops and their operands recursively until reaching
1819 // an value in Value2Index (external input to the reproducer). Update Old2New
1820 // mapping for the original and cloned instructions. Sort instructions to
1821 // clone by dominance, then insert the cloned instructions in the function.
1822 auto CloneInstructions = [&](ArrayRef<Value *> Ops, bool IsSigned) {
1823 SmallVector<Value *, 4> WorkList(Ops);
1825 auto &Value2Index = Info.getValue2Index(IsSigned);
1826 while (!WorkList.empty()) {
1827 Value *V = WorkList.pop_back_val();
1828 if (Old2New.find(V) != Old2New.end())
1829 continue;
1830
1831 auto *I = dyn_cast<Instruction>(V);
1832 if (!Value2Index.contains(V) && I) {
1833 Old2New[V] = nullptr;
1834 ToClone.push_back(I);
1835 append_range(WorkList, I->operands());
1836 }
1837 }
1838
1839 sort(ToClone,
1840 [&DT](Instruction *A, Instruction *B) { return DT.dominates(A, B); });
1841 for (Instruction *I : ToClone) {
1842 Instruction *Cloned = I->clone();
1843 Old2New[I] = Cloned;
1844 Old2New[I]->setName(I->getName());
1845 Cloned->insertBefore(Builder.GetInsertPoint());
1847 Cloned->setDebugLoc({});
1848 }
1849 };
1850
1851 // Materialize the assumptions for the reproducer using the entries in Stack.
1852 // That is, first clone the operands of the condition recursively until we
1853 // reach an external input to the reproducer and add them to the reproducer
1854 // function. Then add an ICmp for the condition (with the inverse predicate if
1855 // the entry is negated) and an assert using the ICmp.
1856 for (auto &Entry : Stack) {
1857 if (Entry.Pred == ICmpInst::BAD_ICMP_PREDICATE)
1858 continue;
1859
1860 LLVM_DEBUG(dbgs() << " Materializing assumption ";
1861 dumpUnpackedICmp(dbgs(), Entry.Pred, Entry.LHS, Entry.RHS);
1862 dbgs() << "\n");
1863 CloneInstructions({Entry.LHS, Entry.RHS}, CmpInst::isSigned(Entry.Pred));
1864
1865 auto *Cmp = Builder.CreateICmp(Entry.Pred, Entry.LHS, Entry.RHS);
1866 Builder.CreateAssumption(Cmp);
1867 }
1868
1869 // Finally, clone the condition to reproduce and remap instruction operands in
1870 // the reproducer using Old2New.
1871 CloneInstructions(Cond, IsSigned);
1872 Entry->getTerminator()->setOperand(0, Cond);
1873 remapInstructionsInBlocks({Entry}, Old2New);
1874
1875 assert(!verifyFunction(*F, &dbgs()));
1876}
1877
1878/// If \p V is a variable in the system and constraint \p C does not contain \p
1879/// V, we managed to decompose \p V at this point, but likely not earlier when
1880/// the fact involving \p V was added. In that case, return a new row for
1881/// V <= decompose(V) to link the variable with the decomposition result.
1882static RowTy getDecompositionLinkRow(Value *V, const ConstraintTy &C,
1883 ConstraintInfo &Info,
1884 const DataLayout &DL) {
1885 const auto &Value2Index = Info.getValue2Index(C.IsSigned);
1886 auto It = Value2Index.find(V);
1887 if (It == Value2Index.end() ||
1888 any_of(C.Coefficients,
1889 [Id = It->second](const Entry &E) { return E.Id == Id; }))
1890 return {};
1891
1892 SmallVector<Value *> NewVariables;
1893 RowTy Row =
1894 getRowForLessEqual(Decomposition(V), decompose(V, Info, C.IsSigned, DL),
1895 Value2Index, NewVariables);
1896 return NewVariables.empty() ? Row : RowTy();
1897}
1898
1899static std::optional<bool> checkCondition(CmpInst::Predicate Pred, Value *A,
1900 Value *B, Instruction *CheckInst,
1901 ConstraintInfo &Info) {
1902 LLVM_DEBUG(dbgs() << "Checking " << *CheckInst << "\n");
1903
1904 auto TryWithConstraint = [&](const ConstraintTy &R) -> std::optional<bool> {
1905 if (R.empty()) {
1906 LLVM_DEBUG(dbgs() << " failed to decompose condition\n");
1907 return std::nullopt;
1908 }
1909
1910 auto &CSToUse = Info.getCS(R.IsSigned);
1911 if (auto ImpliedCondition = R.isImpliedBy(CSToUse)) {
1912 if (!DebugCounter::shouldExecute(EliminatedCounter))
1913 return std::nullopt;
1914 LLVM_DEBUG({
1915 dbgs() << "Condition ";
1917 *ImpliedCondition ? Pred
1919 A, B);
1920 dbgs() << " implied by dominating constraints\n";
1921 CSToUse.dump();
1922 });
1923 return ImpliedCondition;
1924 }
1925 return std::nullopt;
1926 };
1927
1928 // Retry the query after adding additional facts for A == decompose(A) and B
1929 // == decompose(B), if needed.
1930 auto TryWithLinkedDecomposition =
1931 [&](const ConstraintTy &C) -> std::optional<bool> {
1932 if (C.empty())
1933 return std::nullopt;
1934
1935 auto &CS = Info.getCS(C.IsSigned);
1936 unsigned NumVars = Info.getValue2Index(C.IsSigned).size();
1937 unsigned NumPushed = 0;
1938 for (Value *V : {A, B}) {
1939 RowTy Row =
1940 getDecompositionLinkRow(V, C, Info, CheckInst->getDataLayout());
1941 RowTy Negated = ConstraintSystem::negateOrEqual(Row);
1942 if (Row.empty() || Negated.empty())
1943 continue;
1944 NumPushed += CS.addRow(Row, NumVars);
1945 NumPushed += CS.addRow(Negated, NumVars);
1946 }
1947 if (NumPushed == 0)
1948 return std::nullopt;
1949
1950 std::optional<bool> Res = TryWithConstraint(C);
1951 while (NumPushed--)
1952 CS.popLastConstraint();
1953 return Res;
1954 };
1955
1956 auto R = Info.getConstraintForSolving(Pred, A, B);
1957 if (auto ImpliedCondition = TryWithConstraint(R))
1958 return ImpliedCondition;
1959 if (auto ImpliedCondition = TryWithLinkedDecomposition(R))
1960 return ImpliedCondition;
1961
1962 // For non-negative operands unsigned queries can also be checked against the
1963 // signed system.
1964 if (CmpInst::isUnsigned(Pred) && A->getType()->isIntegerTy()) {
1965 SmallVector<Value *> NewVariables;
1966 auto SR = Info.getConstraint(ICmpInst::getSignedPredicate(Pred), A, B,
1967 NewVariables);
1968 if (NewVariables.empty() && !SR.empty() && Info.isKnownNonNegative(A) &&
1969 Info.isKnownNonNegative(B))
1970 if (auto ImpliedCondition = TryWithConstraint(SR))
1971 return ImpliedCondition;
1972 }
1973
1974 // Additionally, query the signed system for eq/ne predicates if we know about
1975 // A or B.
1976 if (CmpInst::isEquality(Pred)) {
1977 const auto &Value2Index = Info.getValue2Index(/*Signed=*/true);
1978 if (!Value2Index.contains(A) && !Value2Index.contains(B))
1979 return std::nullopt;
1980
1981 SmallVector<Value *> NewVariables;
1982 auto SR = Info.getConstraint(Pred, A, B, NewVariables,
1983 /*ForceSignedSystem=*/true);
1984 if (NewVariables.empty()) {
1985 if (auto ImpliedCondition = TryWithConstraint(SR))
1986 return ImpliedCondition;
1987 if (auto ImpliedCondition = TryWithLinkedDecomposition(SR))
1988 return ImpliedCondition;
1989 }
1990 }
1991 return std::nullopt;
1992}
1993
1995 CmpPredicate Pred, Value *A, Value *B, Instruction *CheckInst,
1996 ConstraintInfo &Info, unsigned NumIn, unsigned NumOut,
1997 Instruction *ContextInst, Module *ReproducerModule,
1998 ArrayRef<ReproducerEntry> ReproducerCondStack, DominatorTree &DT,
2000 auto ReplaceCmpWithConstant = [&](Instruction *CheckInst, bool IsTrue) {
2001 generateReproducer(CheckInst, ICmpInst::isSigned(Pred), ReproducerModule,
2002 ReproducerCondStack, Info, DT);
2003 Constant *ConstantC = ConstantInt::getBool(
2004 CmpInst::makeCmpResultType(CheckInst->getType()), IsTrue);
2005 bool Changed = CheckInst->replaceUsesWithIf(ConstantC, [&](Use &U) {
2006 auto *UserI = getContextInstForUse(U);
2007 auto *DTN = DT.getNode(UserI->getParent());
2008 if (!DTN || DTN->getDFSNumIn() < NumIn || DTN->getDFSNumOut() > NumOut)
2009 return false;
2010 if (UserI->getParent() == ContextInst->getParent() &&
2011 UserI->comesBefore(ContextInst))
2012 return false;
2013
2014 // Conditions in an assume trivially simplify to true. Skip uses
2015 // in assume calls to not destroy the available information.
2016 auto *II = dyn_cast<IntrinsicInst>(U.getUser());
2017 return !II || II->getIntrinsicID() != Intrinsic::assume;
2018 });
2019 NumCondsRemoved++;
2020
2021 // Update the debug value records that satisfy the same condition used
2022 // in replaceUsesWithIf.
2024 findDbgUsers(CheckInst, DVRUsers);
2025
2026 for (auto *DVR : DVRUsers) {
2027 auto *DTN = DT.getNode(DVR->getParent());
2028 if (!DTN || DTN->getDFSNumIn() < NumIn || DTN->getDFSNumOut() > NumOut)
2029 continue;
2030
2031 auto *MarkedI = DVR->getInstruction();
2032 if (MarkedI->getParent() == ContextInst->getParent() &&
2033 MarkedI->comesBefore(ContextInst))
2034 continue;
2035
2036 DVR->replaceVariableLocationOp(CheckInst, ConstantC);
2037 }
2038
2039 if (CheckInst->use_empty())
2040 ToRemove.push_back(CheckInst);
2041
2042 return Changed;
2043 };
2044
2045 if (auto ImpliedCondition = checkCondition(Pred, A, B, CheckInst, Info))
2046 return ReplaceCmpWithConstant(CheckInst, *ImpliedCondition);
2047
2048 // When the predicate is samesign and unsigned, we can also make use of the
2049 // signed predicate information.
2050 if (Pred.hasSameSign() && ICmpInst::isUnsigned(Pred))
2051 if (auto ImpliedCondition = checkCondition(
2052 ICmpInst::getSignedPredicate(Pred), A, B, CheckInst, Info))
2053 return ReplaceCmpWithConstant(CheckInst, *ImpliedCondition);
2054
2055 return false;
2056}
2057
2058static bool checkAndReplaceMinMax(MinMaxIntrinsic *MinMax, ConstraintInfo &Info,
2060 auto ReplaceMinMaxWithOperand = [&](MinMaxIntrinsic *MinMax, bool UseLHS) {
2061 // TODO: generate reproducer for min/max.
2062 MinMax->replaceAllUsesWith(MinMax->getOperand(UseLHS ? 0 : 1));
2063 ToRemove.push_back(MinMax);
2064 return true;
2065 };
2066
2067 ICmpInst::Predicate Pred =
2068 ICmpInst::getNonStrictPredicate(MinMax->getPredicate());
2069 if (auto ImpliedCondition = checkCondition(
2070 Pred, MinMax->getOperand(0), MinMax->getOperand(1), MinMax, Info))
2071 return ReplaceMinMaxWithOperand(MinMax, *ImpliedCondition);
2072 if (auto ImpliedCondition = checkCondition(
2073 Pred, MinMax->getOperand(1), MinMax->getOperand(0), MinMax, Info))
2074 return ReplaceMinMaxWithOperand(MinMax, !*ImpliedCondition);
2075 return false;
2076}
2077
2078static bool checkAndReplaceCmp(CmpIntrinsic *I, ConstraintInfo &Info,
2080 Value *LHS = I->getOperand(0);
2081 Value *RHS = I->getOperand(1);
2082 if (checkCondition(I->getGTPredicate(), LHS, RHS, I, Info).value_or(false)) {
2083 I->replaceAllUsesWith(ConstantInt::get(I->getType(), 1));
2084 ToRemove.push_back(I);
2085 return true;
2086 }
2087 if (checkCondition(I->getLTPredicate(), LHS, RHS, I, Info).value_or(false)) {
2088 I->replaceAllUsesWith(ConstantInt::getSigned(I->getType(), -1));
2089 ToRemove.push_back(I);
2090 return true;
2091 }
2092 if (checkCondition(ICmpInst::ICMP_EQ, LHS, RHS, I, Info).value_or(false)) {
2093 I->replaceAllUsesWith(ConstantInt::get(I->getType(), 0));
2094 ToRemove.push_back(I);
2095 return true;
2096 }
2097 return false;
2098}
2099
2100/// Try to replace \p USub by a plain subtract, if \p Info proves it cannot
2101/// saturate. Returns true if \p USub was replaced.
2102static bool checkAndReplaceUSubSat(SaturatingInst *USub, ConstraintInfo &Info,
2104 // usub.sat(A, B) is A - B exactly when A >=u B.
2105 Value *A = USub->getLHS();
2106 Value *B = USub->getRHS();
2107 if (!checkCondition(CmpInst::ICMP_UGE, A, B, USub, Info).value_or(false))
2108 return false;
2109
2110 IRBuilder<> Builder(USub);
2111 Value *Sub = Builder.CreateSub(A, B, "", /*HasNUW=*/true,
2112 /*HasNSW=*/Info.isKnownNonNegative(A));
2113 USub->replaceAllUsesWith(Sub);
2114 Sub->takeName(USub);
2115 ToRemove.push_back(USub);
2116 return true;
2117}
2118
2119static void
2120removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info,
2121 Module *ReproducerModule,
2122 SmallVectorImpl<ReproducerEntry> &ReproducerCondStack,
2123 SmallVectorImpl<StackEntry> &DFSInStack) {
2124 Info.getDecomposeCache().clear();
2125 Info.popLastConstraint(E.IsSigned);
2126 // Remove variables in the system that went out of scope.
2127 auto &Mapping = Info.getValue2Index(E.IsSigned);
2128 for (Value *V : E.ValuesToRelease)
2129 Mapping.erase(V);
2130 Info.popLastNVariables(E.IsSigned, E.ValuesToRelease.size());
2131 DFSInStack.pop_back();
2132 if (ReproducerModule)
2133 ReproducerCondStack.pop_back();
2134}
2135
2136/// Check if either the first condition of an AND or OR is implied by the
2137/// (negated in case of OR) second condition or vice versa.
2139 FactOrCheck &CB, ConstraintInfo &Info, Module *ReproducerModule,
2140 SmallVectorImpl<ReproducerEntry> &ReproducerCondStack,
2141 SmallVectorImpl<StackEntry> &DFSInStack,
2143 Instruction *JoinOp = CB.getContextInst();
2144 if (JoinOp->use_empty())
2145 return false;
2146
2147 Instruction *CmpToCheck = cast<Instruction>(CB.getInstructionToSimplify());
2148 unsigned OtherOpIdx = JoinOp->getOperand(0) == CmpToCheck ? 1 : 0;
2149
2150 // Don't try to simplify the first condition of a select by the second, as
2151 // this may make the select more poisonous than the original one.
2152 // TODO: check if the first operand may be poison.
2153 if (OtherOpIdx != 0 && isa<SelectInst>(JoinOp))
2154 return false;
2155
2156 unsigned OldSize = DFSInStack.size();
2157 llvm::scope_exit InfoRestorer([&]() {
2158 // Remove entries again.
2159 while (OldSize < DFSInStack.size()) {
2160 StackEntry E = DFSInStack.back();
2161 removeEntryFromStack(E, Info, ReproducerModule, ReproducerCondStack,
2162 DFSInStack);
2163 }
2164 });
2165 bool IsOr = match(JoinOp, m_LogicalOr());
2166 SmallVector<Value *, 4> Worklist({JoinOp->getOperand(OtherOpIdx)});
2167 // Do a traversal of the AND/OR tree to add facts from leaf compares.
2168 while (!Worklist.empty()) {
2169 Value *Val = Worklist.pop_back_val();
2170 Value *LHS, *RHS;
2171 CmpPredicate Pred;
2172 if (match(Val, m_ICmpLike(Pred, m_Value(LHS), m_Value(RHS)))) {
2173 // For OR, check if the negated condition implies CmpToCheck.
2174 if (IsOr)
2175 Pred = CmpInst::getInversePredicate(Pred);
2176 // Optimistically add fact from the other compares in the AND/OR.
2177 Info.addFact(Pred, LHS, RHS, CB.NumIn, CB.NumOut, DFSInStack);
2178 continue;
2179 }
2180 if (IsOr ? match(Val, m_LogicalOr(m_Value(LHS), m_Value(RHS)))
2181 : match(Val, m_LogicalAnd(m_Value(LHS), m_Value(RHS)))) {
2182 Worklist.push_back(LHS);
2183 Worklist.push_back(RHS);
2184 }
2185 }
2186 if (OldSize == DFSInStack.size())
2187 return false;
2188
2189 Value *A, *B;
2190 CmpPredicate Pred;
2191 [[maybe_unused]] bool Matched =
2192 match(CmpToCheck, m_ICmpLike(Pred, m_Value(A), m_Value(B)));
2193 assert(Matched && "expected icmp-like match");
2194 // Check if the second condition can be simplified now.
2195 if (auto ImpliedCondition = checkCondition(Pred, A, B, CmpToCheck, Info)) {
2196 if (IsOr == *ImpliedCondition)
2197 JoinOp->replaceAllUsesWith(
2198 ConstantInt::getBool(JoinOp->getType(), *ImpliedCondition));
2199 else
2200 JoinOp->replaceAllUsesWith(JoinOp->getOperand(OtherOpIdx));
2201 ToRemove.push_back(JoinOp);
2202 return true;
2203 }
2204
2205 return false;
2206}
2207
2208void ConstraintInfo::addFact(CmpInst::Predicate Pred, Value *A, Value *B,
2209 unsigned NumIn, unsigned NumOut,
2210 SmallVectorImpl<StackEntry> &DFSInStack) {
2211 addFactImpl(Pred, A, B, NumIn, NumOut, DFSInStack, false);
2212 // If the Pred is eq/ne, also add the fact to signed system.
2213 if (CmpInst::isEquality(Pred))
2214 addFactImpl(Pred, A, B, NumIn, NumOut, DFSInStack, true);
2215 if (Pred == CmpInst::ICMP_NE)
2216 tightenBoundUsingNe(A, B, NumIn, NumOut, DFSInStack);
2217}
2218
2219void ConstraintInfo::tightenBoundUsingNe(
2220 Value *A, Value *B, unsigned NumIn, unsigned NumOut,
2221 SmallVectorImpl<StackEntry> &DFSInStack) {
2222 if (!A->getType()->isIntOrPtrTy())
2223 return;
2224
2225 for (bool IsSigned : {false, true}) {
2226 // In the unsigned system `A u>= 0` holds for every A, so getConstraint
2227 // already turned `A != 0` into `A u> 0`.
2228 if (!IsSigned && match(B, m_Zero()))
2229 continue;
2230
2231 // Skip if there are any unknown variables.
2232 const auto &Value2Index = getValue2Index(IsSigned);
2233 if (any_of(decompose(A, *this, IsSigned, DL).Vars,
2234 [&Value2Index](const DecompEntry &E) {
2235 return !Value2Index.contains(E.Variable);
2236 }))
2237 continue;
2238
2239 // If the system implies `A >= B` then together with `A != B` we get the
2240 // strict `A > B`; symmetrically `A <= B` becomes `A < B`.
2241 CmpInst::Predicate GEPred =
2243 CmpInst::Predicate LEPred =
2245 for (CmpInst::Predicate NonStrict : {GEPred, LEPred}) {
2246 if (!doesHold(NonStrict, A, B))
2247 continue;
2249 LLVM_DEBUG(dbgs() << "Tightening '";
2250 dumpUnpackedICmp(dbgs(), NonStrict, A, B); dbgs() << "' to '";
2252 dbgs() << "' using inequality\n");
2253 addFactImpl(Strict, A, B, NumIn, NumOut, DFSInStack,
2254 /*ForceSignedSystem=*/false);
2255 break;
2256 }
2257 }
2258}
2259
2260void ConstraintInfo::addFactImpl(CmpInst::Predicate Pred, Value *A, Value *B,
2261 unsigned NumIn, unsigned NumOut,
2262 SmallVectorImpl<StackEntry> &DFSInStack,
2263 bool ForceSignedSystem) {
2264 SmallVector<Value *> NewVariables;
2265 auto R = getConstraint(Pred, A, B, NewVariables, ForceSignedSystem);
2266
2267 // TODO: Support non-equality for facts as well.
2268 if (R.empty() || R.isNe())
2269 return;
2270
2271 auto &CSToUse = getCS(R.IsSigned);
2272 // A row implied by a single existing row adds no information. Rows in the
2273 // system are removed in reverse order, so the existing row outlives R.
2274 if (!R.isEq() && NewVariables.empty() &&
2275 CSToUse.isImpliedBySingleRow(R.Coefficients))
2276 return;
2277 LLVM_DEBUG(dbgs() << "Adding '"; dumpUnpackedICmp(dbgs(), Pred, A, B);
2278 dbgs() << "'\n");
2279 bool Added = CSToUse.addRow(R.Coefficients, R.NumVars);
2280 if (!Added)
2281 return;
2282
2283 DecomposeCache.clear();
2284
2285 // If R has been added to the system, add the new variables and queue it for
2286 // removal once it goes out-of-scope.
2287 SmallVector<Value *, 2> ValuesToRelease;
2288 auto &Value2Index = getValue2Index(R.IsSigned);
2289 for (Value *V : NewVariables) {
2290 Value2Index.try_emplace(V, Value2Index.size() + 1);
2291 ValuesToRelease.push_back(V);
2292 }
2293
2294 LLVM_DEBUG({
2295 dbgs() << " constraint: ";
2296 dumpConstraint(R.Coefficients, getValue2Index(R.IsSigned));
2297 dbgs() << "\n";
2298 });
2299
2300 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
2301 std::move(ValuesToRelease));
2302
2303 if (!R.IsSigned) {
2304 for (Value *V : NewVariables) {
2305 // Add V > -1 constraints for all new variables.
2306 CSToUse.addRow({Entry(0, 0), Entry(-1, Value2Index.at(V))},
2307 Value2Index.size());
2308 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
2309 SmallVector<Value *, 2>());
2310 }
2311 }
2312
2313 if (R.isEq()) {
2314 // Also add the inverted constraint for equality constraints.
2315 for (Entry &E : R.Coefficients)
2316 if (MulOverflow(E.Coefficient, int64_t(-1), E.Coefficient))
2317 return;
2318 CSToUse.addRow(R.Coefficients, R.NumVars);
2319
2320 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
2321 SmallVector<Value *, 2>());
2322 }
2323}
2324
2325/// Replace the uses of \p II, which is known not to overflow, by the
2326/// corresponding plain binary operation and a false overflow flag.
2329 bool Changed = false;
2330 IRBuilder<> Builder(II->getParent(), II->getIterator());
2331 Value *Res = nullptr;
2332 for (User *U : make_early_inc_range(II->users())) {
2333 if (match(U, m_ExtractValue<0>(m_Value()))) {
2334 if (!Res)
2335 Res = Builder.CreateNoWrapBinOp(II->getBinaryOp(), II->getLHS(),
2336 II->getRHS(),
2337 /*IsNUW=*/!II->isSigned(),
2338 /*IsNSW=*/II->isSigned());
2339 U->replaceAllUsesWith(Res);
2340 Changed = true;
2341 } else if (match(U, m_ExtractValue<1>(m_Value()))) {
2342 U->replaceAllUsesWith(Builder.getFalse());
2343 Changed = true;
2344 } else
2345 continue;
2346
2347 if (U->use_empty()) {
2348 auto *I = cast<Instruction>(U);
2349 ToRemove.push_back(I);
2350 I->setOperand(0, PoisonValue::get(II->getType()));
2351 Changed = true;
2352 }
2353 }
2354
2355 if (II->use_empty()) {
2356 // Do not erase II here: the worklist may still hold Uses of II's operands.
2357 for (Use &Arg : II->args())
2358 Arg.set(PoisonValue::get(Arg->getType()));
2359 ToRemove.push_back(II);
2360 Changed = true;
2361 }
2362 return Changed;
2363}
2364
2365static bool
2368 if (!isKnownNoWrap(II, Info, II->isSigned()))
2369 return false;
2371}
2372
2374 ScalarEvolution *SE,
2376 TargetLibraryInfo &TLI) {
2377 bool Changed = false;
2378 DT.updateDFSNumbers();
2379 SmallVector<Value *> FunctionArgs(llvm::make_pointer_range(F.args()));
2380 ConstraintInfo Info(F.getDataLayout(), FunctionArgs);
2381 State S(DT, LI, SE, TLI);
2382 std::unique_ptr<Module> ReproducerModule(
2383 DumpReproducers ? new Module(F.getName(), F.getContext()) : nullptr);
2384
2385 // First, collect conditions implied by branches and blocks with their
2386 // Dominator DFS in and out numbers.
2387 for (BasicBlock &BB : F) {
2388 if (!DT.getNode(&BB))
2389 continue;
2390 S.addInfoFor(BB);
2391 }
2392
2393 // Next, sort worklist by dominance, so that dominating conditions to check
2394 // and facts come before conditions and facts dominated by them. If a
2395 // condition to check and a fact have the same numbers, conditional facts come
2396 // first. Assume facts and checks are ordered according to their relative
2397 // order in the containing basic block. Also make sure conditions with
2398 // constant operands come before conditions without constant operands. This
2399 // increases the effectiveness of the current signed <-> unsigned fact
2400 // transfer logic.
2401 stable_sort(S.WorkList, [](const FactOrCheck &A, const FactOrCheck &B) {
2402 auto HasNoConstOp = [](const FactOrCheck &B) {
2403 Value *V0 = B.isConditionFact() ? B.Cond.Op0 : B.Inst->getOperand(0);
2404 Value *V1 = B.isConditionFact() ? B.Cond.Op1 : B.Inst->getOperand(1);
2405 return !isa<ConstantInt>(V0) && !isa<ConstantInt>(V1);
2406 };
2407 // If both entries have the same In numbers, conditional facts come first.
2408 // Otherwise use the relative order in the basic block.
2409 if (A.NumIn == B.NumIn) {
2410 if (A.isConditionFact() && B.isConditionFact()) {
2411 bool NoConstOpA = HasNoConstOp(A);
2412 bool NoConstOpB = HasNoConstOp(B);
2413 return NoConstOpA < NoConstOpB;
2414 }
2415 if (A.isConditionFact())
2416 return true;
2417 if (B.isConditionFact())
2418 return false;
2419 auto *InstA = A.getContextInst();
2420 auto *InstB = B.getContextInst();
2421 return InstA->comesBefore(InstB);
2422 }
2423 return A.NumIn < B.NumIn;
2424 });
2425
2426 SmallVector<Instruction *> ToRemove;
2427
2428 // Finally, process ordered worklist and eliminate implied conditions.
2429 SmallVector<StackEntry, 16> DFSInStack;
2430 SmallVector<ReproducerEntry> ReproducerCondStack;
2431 for (FactOrCheck &CB : S.WorkList) {
2432 // First, pop entries from the stack that are out-of-scope for CB. Remove
2433 // the corresponding entry from the constraint system.
2434 while (!DFSInStack.empty()) {
2435 auto &E = DFSInStack.back();
2436 LLVM_DEBUG(dbgs() << "Top of stack : " << E.NumIn << " " << E.NumOut
2437 << "\n");
2438 LLVM_DEBUG(dbgs() << "CB: " << CB.NumIn << " " << CB.NumOut << "\n");
2439 assert(E.NumIn <= CB.NumIn);
2440 if (CB.NumOut <= E.NumOut)
2441 break;
2442 LLVM_DEBUG({
2443 dbgs() << "Removing ";
2444 dumpConstraint(Info.getCS(E.IsSigned).getLastConstraint(),
2445 Info.getValue2Index(E.IsSigned));
2446 dbgs() << "\n";
2447 });
2448 removeEntryFromStack(E, Info, ReproducerModule.get(), ReproducerCondStack,
2449 DFSInStack);
2450 }
2451
2452 CmpPredicate Pred;
2453 Value *A, *B;
2454 // For a block, check if any CmpInsts become known based on the current set
2455 // of constraints.
2456 if (CB.isCheck()) {
2457 Instruction *Inst = CB.getInstructionToSimplify();
2458 if (!Inst)
2459 continue;
2460 if (canStrengthenFlags(Inst)) {
2461 Changed |= tryToStrengthenFlags(Inst, Info);
2462 continue;
2463 }
2464 LLVM_DEBUG(dbgs() << "Processing condition to simplify: " << *Inst
2465 << "\n");
2466 if (auto *II = dyn_cast<WithOverflowInst>(Inst)) {
2468 } else if (match(Inst, m_ICmpLike(Pred, m_Value(A), m_Value(B)))) {
2470 Pred, A, B, Inst, Info, CB.NumIn, CB.NumOut, CB.getContextInst(),
2471 ReproducerModule.get(), ReproducerCondStack, S.DT, ToRemove);
2472 if (!Simplified &&
2473 match(CB.getContextInst(), m_LogicalOp(m_Value(), m_Value()))) {
2475 CB, Info, ReproducerModule.get(), ReproducerCondStack, DFSInStack,
2476 ToRemove);
2477 }
2479 } else if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(Inst)) {
2480 Changed |= checkAndReplaceMinMax(MinMax, Info, ToRemove);
2481 } else if (auto *CmpIntr = dyn_cast<CmpIntrinsic>(Inst)) {
2482 Changed |= checkAndReplaceCmp(CmpIntr, Info, ToRemove);
2483 } else if (match(Inst, m_Intrinsic<Intrinsic::usub_sat>())) {
2484 Changed |=
2486 }
2487 continue;
2488 }
2489
2490 auto AddFact = [&](CmpPredicate Pred, Value *A, Value *B) {
2491 LLVM_DEBUG(dbgs() << "Processing fact to add to the system: ";
2492 dumpUnpackedICmp(dbgs(), Pred, A, B); dbgs() << "\n");
2493 if (Info.getCS(CmpInst::isSigned(Pred)).size() > MaxRows) {
2494 LLVM_DEBUG(
2495 dbgs()
2496 << "Skip adding constraint because system has too many rows.\n");
2497 return;
2498 }
2499
2500 Info.addFact(Pred, A, B, CB.NumIn, CB.NumOut, DFSInStack);
2501 if (ReproducerModule && DFSInStack.size() > ReproducerCondStack.size())
2502 ReproducerCondStack.emplace_back(Pred, A, B);
2503
2504 if (ICmpInst::isRelational(Pred)) {
2505 // If samesign is present on the ICmp, simply flip the sign of the
2506 // predicate, transferring the information from the signed system to the
2507 // unsigned system, and viceversa.
2508 if (Pred.hasSameSign())
2510 CB.NumIn, CB.NumOut, DFSInStack);
2511 else
2512 Info.transferToOtherSystem(Pred, A, B, CB.NumIn, CB.NumOut,
2513 DFSInStack);
2514 }
2515
2516 // (X | Y) >s -1 implies X >s -1 and Y >s -1, because the sign bit of an
2517 // OR is the OR of the operand sign bits. Similarly, (X & Y) <s 0 implies
2518 // X <s 0 and Y <s 0. Look through these canonical forms produced by
2519 // InstCombine so the sign facts on the operands are available to the
2520 // solver.
2521 if ((Pred == CmpInst::ICMP_SGT && match(B, m_AllOnes())) ||
2522 (Pred == CmpInst::ICMP_SLT && match(B, m_Zero()))) {
2523 unsigned Opc =
2524 Pred == CmpInst::ICMP_SGT ? Instruction::Or : Instruction::And;
2525 SmallVector<Value *> Worklist = {A};
2526 SmallPtrSet<Value *, 4> Seen;
2527 while (!Worklist.empty()) {
2528 Value *Cur = Worklist.pop_back_val();
2529 auto *BO = dyn_cast<BinaryOperator>(Cur);
2530 if (!BO || BO->getOpcode() != Opc)
2531 continue;
2532 for (Value *Op : {BO->getOperand(0), BO->getOperand(1)}) {
2533 if (!Seen.insert(Op).second)
2534 continue;
2535 Worklist.push_back(Op);
2536 Info.addFact(Pred, Op, B, CB.NumIn, CB.NumOut, DFSInStack);
2537 }
2538 }
2539 }
2540
2541 if (ReproducerModule && DFSInStack.size() > ReproducerCondStack.size()) {
2542 // Add dummy entries to ReproducerCondStack to keep it in sync with
2543 // DFSInStack.
2544 for (unsigned I = 0,
2545 E = (DFSInStack.size() - ReproducerCondStack.size());
2546 I < E; ++I) {
2547 ReproducerCondStack.emplace_back(ICmpInst::BAD_ICMP_PREDICATE,
2548 nullptr, nullptr);
2549 }
2550 }
2551 };
2552
2553 if (!CB.isConditionFact()) {
2554 Value *X;
2555 if (match(CB.Inst, m_Intrinsic<Intrinsic::abs>(m_Value(X)))) {
2556 // If is_int_min_poison is true then we may assume llvm.abs >= 0.
2557 if (cast<ConstantInt>(CB.Inst->getOperand(1))->isOne())
2558 AddFact(CmpInst::ICMP_SGE, CB.Inst,
2559 ConstantInt::get(CB.Inst->getType(), 0));
2560 AddFact(CmpInst::ICMP_SGE, CB.Inst, X);
2561 continue;
2562 }
2563
2564 if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(CB.Inst)) {
2565 Pred = ICmpInst::getNonStrictPredicate(MinMax->getPredicate());
2566 AddFact(Pred, MinMax, MinMax->getLHS());
2567 AddFact(Pred, MinMax, MinMax->getRHS());
2568 continue;
2569 }
2570 if (auto *USatI = dyn_cast<SaturatingInst>(CB.Inst)) {
2571 switch (USatI->getIntrinsicID()) {
2572 default:
2573 llvm_unreachable("Unexpected intrinsic.");
2574 case Intrinsic::uadd_sat:
2575 AddFact(ICmpInst::ICMP_UGE, USatI, USatI->getLHS());
2576 AddFact(ICmpInst::ICMP_UGE, USatI, USatI->getRHS());
2577 break;
2578 case Intrinsic::usub_sat:
2579 AddFact(ICmpInst::ICMP_ULE, USatI, USatI->getLHS());
2580 break;
2581 }
2582 continue;
2583 }
2584
2585 if (auto *BO = dyn_cast<BinaryOperator>(CB.Inst)) {
2586 if (BO->getOpcode() == Instruction::URem) {
2587 // urem x, n: result < n (remainder is always less than divisor)
2588 AddFact(CmpInst::ICMP_ULT, BO, BO->getOperand(1));
2589 // urem x, n: result <= x (remainder is at most the dividend)
2590 AddFact(CmpInst::ICMP_ULE, BO, BO->getOperand(0));
2591 continue;
2592 }
2593 if (BO->getOpcode() == Instruction::UDiv) {
2594 // udiv x, n: result <= x (quotient is at most the dividend)
2595 AddFact(CmpInst::ICMP_ULE, BO, BO->getOperand(0));
2596 continue;
2597 }
2598 if (BO->getOpcode() == Instruction::LShr) {
2599 // lshr x, n: result <= x (right shift cannot increase the value)
2600 AddFact(CmpInst::ICMP_ULE, BO, BO->getOperand(0));
2601 continue;
2602 }
2603 if (BO->getOpcode() == Instruction::SRem) {
2604 Value *X = BO->getOperand(0);
2605 Value *N = BO->getOperand(1);
2606 Constant *Zero = Constant::getNullValue(BO->getType());
2607 if (Info.doesHold(CmpInst::ICMP_SGE, X, Zero) ||
2608 isKnownNonNegative(X, F.getDataLayout())) {
2609 // srem x, n: result >= 0, if x >= 0 (result has the sign of x)
2610 AddFact(CmpInst::ICMP_SGE, BO, Zero);
2611 // srem x, n: result <= x, if x >= 0 (|result| <= |x| and both are
2612 // non-negative)
2613 AddFact(CmpInst::ICMP_SLE, BO, X);
2614 }
2615 if (Info.doesHold(CmpInst::ICMP_SGE, N, Zero) ||
2616 isKnownPositive(N, F.getDataLayout())) {
2617 // srem x, n: result <= n, if n >= 0 (|result| < n, so result <= n -
2618 // 1
2619 AddFact(CmpInst::ICMP_SLT, BO, N);
2620 }
2621 continue;
2622 }
2623 if (BO->getOpcode() == Instruction::SDiv) {
2624 Value *X = BO->getOperand(0);
2625 Value *N = BO->getOperand(1);
2626 if (!Info.isKnownNonNegative(X) || !Info.isKnownPositive(N))
2627 continue;
2628
2629 bool IsStrict = Info.isKnownPositive(X) &&
2630 Info.doesHold(CmpInst::ICMP_SGT, N,
2631 ConstantInt::get(N->getType(), 1));
2632 AddFact(CmpInst::ICMP_SGE, BO, Constant::getNullValue(BO->getType()));
2633 AddFact(IsStrict ? CmpInst::ICMP_SLT : CmpInst::ICMP_SLE, BO, X);
2634 continue;
2635 }
2636 }
2637
2638 auto &DL = F.getDataLayout();
2639 auto AddFactsAboutIndices = [&](Value *Ptr, Type *AccessType) {
2640 CmpPredicate Pred;
2641 Value *A, *B;
2644 DL.getTypeStoreSize(AccessType).getFixedValue(), Pred, A, B, DL,
2645 TLI))
2646 AddFact(Pred, A, B);
2647 };
2648
2649 if (auto *LI = dyn_cast<LoadInst>(CB.Inst)) {
2650 AddFactsAboutIndices(LI->getPointerOperand(), LI->getAccessType());
2651 continue;
2652 }
2653 if (auto *SI = dyn_cast<StoreInst>(CB.Inst)) {
2654 AddFactsAboutIndices(SI->getPointerOperand(), SI->getAccessType());
2655 continue;
2656 }
2657 }
2658
2659 if (CB.isConditionFact()) {
2660 Pred = CB.Cond.Pred;
2661 A = CB.Cond.Op0;
2662 B = CB.Cond.Op1;
2663 if (CB.DoesHold.Pred != CmpInst::BAD_ICMP_PREDICATE &&
2664 !Info.doesHold(CB.DoesHold.Pred, CB.DoesHold.Op0, CB.DoesHold.Op1)) {
2665 LLVM_DEBUG({
2666 dbgs() << "Not adding fact ";
2667 dumpUnpackedICmp(dbgs(), Pred, A, B);
2668 dbgs() << " because precondition ";
2669 dumpUnpackedICmp(dbgs(), CB.DoesHold.Pred, CB.DoesHold.Op0,
2670 CB.DoesHold.Op1);
2671 dbgs() << " does not hold.\n";
2672 });
2673 continue;
2674 }
2675 } else {
2676 [[maybe_unused]] bool Matched =
2678 m_ICmpLike(Pred, m_Value(A), m_Value(B))));
2679 assert(Matched &&
2680 "Must have an assume intrinsic with a icmp like operand");
2681 }
2682 AddFact(Pred, A, B);
2683 }
2684
2685 if (ReproducerModule && !ReproducerModule->functions().empty()) {
2686 std::string S;
2687 raw_string_ostream StringS(S);
2688 ReproducerModule->print(StringS, nullptr);
2689 OptimizationRemark Rem(DEBUG_TYPE, "Reproducer", &F);
2690 Rem << ore::NV("module") << S;
2691 ORE.emit(Rem);
2692 }
2693
2694#ifndef NDEBUG
2695 unsigned SignedEntries =
2696 count_if(DFSInStack, [](const StackEntry &E) { return E.IsSigned; });
2697 assert(Info.getCS(false).size() - FunctionArgs.size() ==
2698 DFSInStack.size() - SignedEntries &&
2699 "updates to CS and DFSInStack are out of sync");
2700 assert(Info.getCS(true).size() == SignedEntries &&
2701 "updates to CS and DFSInStack are out of sync");
2702#endif
2703
2704 for (Instruction *I : ToRemove)
2705 I->eraseFromParent();
2706 return Changed;
2707}
2708
2711 auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
2712 auto &LI = AM.getResult<LoopAnalysis>(F);
2713 // SCEV is only used for loops, only construct it if there are some.
2714 auto *SE = LI.empty() ? nullptr : &AM.getResult<ScalarEvolutionAnalysis>(F);
2716 auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
2717 if (!eliminateConstraints(F, DT, LI, SE, ORE, TLI))
2718 return PreservedAnalyses::all();
2719
2723 return PA;
2724}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
ReachingDefInfo InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static const Function * getParent(const Value *V)
#define X(NUM, ENUM, NAME)
Definition ELF.h:857
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
std::pair< ICmpInst *, unsigned > ConditionTy
static int64_t MaxConstraintValue
static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI, ScalarEvolution *SE, OptimizationRemarkEmitter &ORE, TargetLibraryInfo &TLI)
static bool canStrengthenFlags(Instruction *I)
Returns true if I is a candidate whose poison-generating flags may be strengthened using the constrai...
static bool doesHoldInRange(ConstraintInfo &Info, Value *Op, const ConstantRange &R, bool Signed)
Returns true if Info implies that Op is in R, interpreting R as a signed range if Signed is set and a...
static RowTy getDecompositionLinkRow(Value *V, const ConstraintTy &C, ConstraintInfo &Info, const DataLayout &DL)
If V is a variable in the system and constraint C does not contain V, we managed to decompose V at th...
static int64_t MinSignedConstraintValue
static bool tryToSimplifyOverflowMath(WithOverflowInst *II, ConstraintInfo &Info, SmallVectorImpl< Instruction * > &ToRemove)
static auto m_IncrementOf(const PhiMatchTy &PhiM, const APInt *&Off)
Matches an increment of PhiM by a constant offset, captured in Off.
static Instruction * getContextInstForUse(Use &U)
static bool isKnownNoWrap(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1, unsigned NoWrapFlags, ConstraintInfo &Info, bool Signed)
Returns true if Opcode applied to Op0 and Op1 with NoWrapFlags is known to not wrap in signed or unsi...
static bool mayLookThrough(Value *V)
Returns true if V is an operation decomposeImpl can look through.
static bool canUseSExt(ConstantInt *CI)
static void removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info, Module *ReproducerModule, SmallVectorImpl< ReproducerEntry > &ReproducerCondStack, SmallVectorImpl< StackEntry > &DFSInStack)
static std::optional< bool > checkCondition(CmpInst::Predicate Pred, Value *A, Value *B, Instruction *CheckInst, ConstraintInfo &Info)
static cl::opt< unsigned > MaxRows("constraint-elimination-max-rows", cl::init(500), cl::Hidden, cl::desc("Maximum number of rows to keep in constraint system"))
static cl::opt< bool > DumpReproducers("constraint-elimination-dump-reproducers", cl::init(false), cl::Hidden, cl::desc("Dump IR to reproduce successful transformations."))
static Decomposition decompose(Value *V, ConstraintInfo &Info, bool IsSigned, const DataLayout &DL)
static bool checkOrAndOpImpliedByOther(FactOrCheck &CB, ConstraintInfo &Info, Module *ReproducerModule, SmallVectorImpl< ReproducerEntry > &ReproducerCondStack, SmallVectorImpl< StackEntry > &DFSInStack, SmallVectorImpl< Instruction * > &ToRemove)
Check if either the first condition of an AND or OR is implied by the (negated in case of OR) second ...
static OffsetResult collectOffsets(GEPOperator &GEP, const DataLayout &DL)
static bool checkAndReplaceMinMax(MinMaxIntrinsic *MinMax, ConstraintInfo &Info, SmallVectorImpl< Instruction * > &ToRemove)
static bool tryToStrengthenFlags(Instruction *I, ConstraintInfo &Info)
Try to strengthen I's poison generating flags using Info.
static RowTy getRowForLessEqual(const Decomposition &ADec, const Decomposition &BDec, const DenseMap< Value *, unsigned > &Value2Index, SmallVectorImpl< Value * > &NewVariables)
Build the row for 'ADec <= BDec', using the indices from Value2Index.
static void dumpConstraint(ArrayRef< Entry > C, const DenseMap< Value *, unsigned > &Value2Index)
static bool replaceOverflowUses(WithOverflowInst *II, SmallVectorImpl< Instruction * > &ToRemove)
Replace the uses of II, which is known not to overflow, by the corresponding plain binary operation a...
static bool getConstraintFromMemoryAccess(GetElementPtrInst &GEP, uint64_t AccessSize, CmpPredicate &Pred, Value *&A, Value *&B, const DataLayout &DL, const TargetLibraryInfo &TLI)
static void dumpUnpackedICmp(raw_ostream &OS, ICmpInst::Predicate Pred, Value *LHS, Value *RHS)
static void generateReproducer(Instruction *Cond, bool IsSigned, Module *M, ArrayRef< ReproducerEntry > Stack, ConstraintInfo &Info, DominatorTree &DT)
Helper function to generate a reproducer function for simplifying Cond.
static bool checkAndReplaceUSubSat(SaturatingInst *USub, ConstraintInfo &Info, SmallVectorImpl< Instruction * > &ToRemove)
Try to replace USub by a plain subtract, if Info proves it cannot saturate.
static bool checkAndReplaceCondition(CmpPredicate Pred, Value *A, Value *B, Instruction *CheckInst, ConstraintInfo &Info, unsigned NumIn, unsigned NumOut, Instruction *ContextInst, Module *ReproducerModule, ArrayRef< ReproducerEntry > ReproducerCondStack, DominatorTree &DT, SmallVectorImpl< Instruction * > &ToRemove)
static Instruction * findCommonDominatorOfUses(Instruction &I, DominatorTree &DT)
Returns the closest program point dominating all uses of I.
static Decomposition decomposeImpl(Value *V, ConstraintInfo &Info, bool IsSigned, const DataLayout &DL)
static bool checkAndReplaceCmp(CmpIntrinsic *I, ConstraintInfo &Info, SmallVectorImpl< Instruction * > &ToRemove)
static std::pair< Value *, Value * > getStartAndBackedgeValue(const PHINode &PN, const BasicBlock *LoopPred)
Splits the induction phi PN into the start value, coming from the loop predecessor LoopPred,...
static Decomposition decomposeGEP(GEPOperator &GEP, ConstraintInfo &Info, bool IsSigned, const DataLayout &DL)
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
#define DEBUG_TYPE
This is the interface for a simple mod/ref and alias analysis over globals.
Hexagon Common GEP
Module.h This file contains the declarations for the Module class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Machine Check Debug Module
uint64_t IntrinsicInst * II
#define P(N)
if(PassOpts->AAPipeline)
This file defines the PointerIntPair class.
static StringRef getName(Value *V)
const SmallVectorImpl< MachineOperand > & Cond
This file contains some templates that are useful if you are working with the STL at all.
This file defines the scope_exit class, which executes user-defined cleanup logic at scope exit.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
Value * RHS
Value * LHS
Class for arbitrary precision integers.
Definition APInt.h:78
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
Definition APInt.h:202
bool sgt(const APInt &RHS) const
Signed greater than comparison.
Definition APInt.h:1205
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
Definition APInt.h:376
LLVM_ABI APInt urem(const APInt &RHS) const
Unsigned remainder operation.
Definition APInt.cpp:1695
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
Definition APInt.h:205
static APInt getMinValue(unsigned numBits)
Gets minimum unsigned value of APInt for a specific bit width.
Definition APInt.h:212
bool isNegative() const
Determine sign of this APInt.
Definition APInt.h:325
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
Definition APInt.h:215
bool slt(const APInt &RHS) const
Signed less than comparison.
Definition APInt.h:1134
bool isOne() const
Determine if this is a value of 1.
Definition APInt.h:385
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
LLVM Basic Block Representation.
Definition BasicBlock.h:62
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
Definition BasicBlock.h:515
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this basic block belongs to.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Predicate getStrictPredicate() const
For example, SGE -> SGT, SLE -> SLT, ULE -> ULT, UGE -> UGT.
Definition InstrTypes.h:921
bool isEquality() const
Determine if this is an equals/not equals predicate.
Definition InstrTypes.h:978
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ ICMP_SLT
signed less than
Definition InstrTypes.h:769
@ ICMP_SLE
signed less or equal
Definition InstrTypes.h:770
@ ICMP_UGE
unsigned greater or equal
Definition InstrTypes.h:764
@ ICMP_UGT
unsigned greater than
Definition InstrTypes.h:763
@ ICMP_SGT
signed greater than
Definition InstrTypes.h:767
@ ICMP_ULT
unsigned less than
Definition InstrTypes.h:765
@ ICMP_NE
not equal
Definition InstrTypes.h:762
@ ICMP_SGE
signed greater or equal
Definition InstrTypes.h:768
@ ICMP_ULE
unsigned less or equal
Definition InstrTypes.h:766
bool isSigned() const
Definition InstrTypes.h:993
static LLVM_ABI bool isEquality(Predicate pred)
Determine if this is an equals/not equals predicate.
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Definition InstrTypes.h:890
Predicate getNonStrictPredicate() const
For example, SGT -> SGE, SLT -> SLE, ULT -> ULE, UGT -> UGE.
Definition InstrTypes.h:934
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Definition InstrTypes.h:852
bool isUnsigned() const
Definition InstrTypes.h:999
This class represents a ucmp/scmp intrinsic.
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
static LLVM_ABI CmpPredicate getInverse(CmpPredicate P)
Get the inverse predicate of a CmpPredicate.
CmpInst::Predicate dropSameSign() const
Drops samesign information.
bool hasSameSign() const
Query samesign information, for optimizations.
This is the shared class of boolean and integer constants.
Definition Constants.h:87
bool isNegative() const
Definition Constants.h:214
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
Definition Constants.h:135
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
Definition Constants.h:174
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition Constants.h:159
static LLVM_ABI ConstantInt * getBool(LLVMContext &Context, bool V)
This class represents a range of values.
static LLVM_ABI ConstantRange makeExactNoWrapRegion(Instruction::BinaryOps BinOp, const APInt &Other, unsigned NoWrapKind)
Produce the range that contains X if and only if "X BinOp Other" does not wrap.
This is an important base class in LLVM.
Definition Constant.h:43
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &)
bool addRow(ArrayRef< Entry > R, size_t NumVars)
static RowTy negate(RowTy R)
LLVM_ABI std::pair< ConstraintSystem, RowTy > getSubSystem(ArrayRef< Entry > R) const
Build and return a sub-system of constraints connected (transitively) to query R, with variables comp...
static RowTy toStrictLessThan(RowTy R)
Converts the given row to form a strict less than inequality.
SmallVector< Entry, 8 > RowTy
A single constraint of the form 'c >= v1 * c1 + ... + vn * cn'.
static RowTy negateOrEqual(RowTy R)
Multiplies each coefficient in the given row by -1.
LLVM_ABI void dump() const
Print the constraints in the system.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
static bool shouldExecute(CounterInfo &Counter)
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:782
iterator end()
Definition DenseMap.h:702
unsigned size() const
Definition DenseMap.h:733
unsigned getDFSNumIn() const
getDFSNumIn/getDFSNumOut - These return the DFS visitation order for nodes in the dominator tree.
NodeT * getBlock() const
unsigned getDFSNumOut() const
Analysis pass which computes a DominatorTree.
Definition Dominators.h:241
void updateDFSNumbers() const
updateDFSNumbers - Assign In and Out numbers to the nodes while walking dominator tree in dfs order.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
LLVM_ABI Instruction * findNearestCommonDominator(Instruction *I1, Instruction *I2) const
Find the nearest instruction I that dominates both I1 and I2, in the sense that a result produced bef...
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition Function.h:169
static GEPNoWrapFlags none()
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
@ ExternalLinkage
Externally visible function.
Definition GlobalValue.h:53
static bool isLT(Predicate P)
Return true if the predicate is SLT or ULT.
Predicate getFlippedSignednessPredicate() const
For example, SLT->ULT, ULT->SLT, SLE->ULE, ULE->SLE, EQ->EQ.
Predicate getSignedPredicate() const
For example, EQ->EQ, SLE->SLE, UGT->SGT, etc.
bool isRelational() const
Return true if the predicate is relational (not EQ or NE).
Predicate getUnsignedPredicate() const
For example, EQ->EQ, SLE->ULE, UGT->UGT, etc.
static bool isLE(Predicate P)
Return true if the predicate is SLE or ULE.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2901
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
LLVM_ABI void dropUnknownNonDebugMetadata(ArrayRef< unsigned > KnownIDs={})
Drop all unknown metadata except for debug locations.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
Analysis pass that exposes the LoopInfo for a function.
Definition LoopInfo.h:594
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
size_type size() const
Definition MapVector.h:58
This class represents min/max intrinsics.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
The optimization diagnostic interface.
Utility class for integer operators which may exhibit overflow - Add, Sub, Mul, and Shl.
Definition Operator.h:78
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
int getBasicBlockIndex(const BasicBlock *BB) const
Return the first index of the specified basic block in the value list for this PHI.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
PointerIntPair - This class implements a pair of a pointer and small integer.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Definition Analysis.h:132
Represents a saturating add/sub intrinsic.
Analysis pass that exposes the ScalarEvolution for a function.
The main scalar evolution driver.
LLVM_ABI const SCEV * getMinusSCEV(SCEVUse LHS, SCEVUse RHS, SCEVFlags Flags=SCEV::FlagNone, unsigned Depth=0)
Return LHS-RHS.
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI bool isSCEVable(Type *Ty) const
Test if values of the given type are analyzable within the SCEV framework.
MonotonicPredicateType
A predicate is said to be monotonically increasing if may go from being false to being true as the lo...
LLVM_ABI APInt getConstantMultiple(const SCEV *S, const Instruction *CtxI=nullptr)
Returns the max constant multiple of S.
LLVM_ABI std::optional< MonotonicPredicateType > getMonotonicPredicateType(const SCEVAddRecExpr *LHS, ICmpInst::Predicate Pred)
If, for all loop invariant X, the predicate "LHS `Pred` X" is monotonically increasing or decreasing,...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void truncate(size_type N)
Like resize, but requires that N is less than size().
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:277
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
Value * getOperand(unsigned i) const
Definition User.h:207
iterator find(const KeyT &Val)
Definition ValueMap.h:160
iterator end()
Definition ValueMap.h:139
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:553
LLVM_ABI const Value * stripPointerCastsSameRepresentation() const
Strip off pointer casts, all-zero GEPs and address space casts but ensures the representation of the ...
Definition Value.cpp:720
bool use_empty() const
Definition Value.h:348
LLVM_ABI bool replaceUsesWithIf(Value *New, llvm::function_ref< bool(Use &U)> ShouldReplace)
Go through the uses list for this definition and make each use point to "V" if the callback ShouldRep...
Definition Value.cpp:561
Represents an op.with.overflow intrinsic.
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
constexpr bool isFixed() const
Returns true if the quantity is not scaled by vscale.
Definition TypeSize.h:171
const ParentTy * getParent() const
Definition ilist_node.h:34
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ Entry
Definition COFF.h:862
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:83
AllOnesConstantMatch m_AllOnes()
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
match_bind< PHINode > m_Phi(PHINode *&PN)
Match a PHI node, capturing it if we match.
auto m_LogicalOp()
Matches either L && R or L || R where L and R are arbitrary values.
CommutativeBinaryIntrinsic_match< IntrID, T0, T1 > m_c_Intrinsic(const T0 &Op0, const T1 &Op1)
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
DisjointOr_match< LHS, RHS > m_DisjointOr(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst, true > m_c_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
Matches an ICmp with a predicate over LHS and RHS in either order.
ExtractValue_match< Ind, Val_t > m_ExtractValue(const Val_t &V)
Match a single index ExtractValue instruction.
ICmpLike_match< LHS, RHS > m_ICmpLike(CmpPredicate &Pred, const LHS &L, const RHS &R)
auto m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
match_combine_or< BinaryOp_match< LHS, RHS, Instruction::Add >, DisjointOr_match< LHS, RHS > > m_AddLike(const LHS &L, const RHS &R)
Match either "add" or "or disjoint".
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
LogicalOp_match< LHS, RHS, Instruction::And, true > m_c_LogicalAnd(const LHS &L, const RHS &R)
Matches L && R with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
LogicalOp_match< LHS, RHS, Instruction::Or, true > m_c_LogicalOr(const LHS &L, const RHS &R)
Matches L || R with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
bind_cst_ty m_scev_APInt(const APInt *&C)
Match an SCEV constant and bind it to an APInt.
specificloop_ty m_SpecificLoop(const Loop *L)
bool match(const SCEV *S, const Pattern &P)
SCEVAffineAddRec_match< Op0_t, Op1_t, match_isa< const Loop > > m_scev_AffineAddRec(const Op0_t &Op0, const Op1_t &Op1)
initializer< Ty > init(const Ty &Val)
@ Switch
The "resume-switch" lowering, where there are separate resume and destroy functions that are shared b...
Definition CoroShape.h:32
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
bool empty() const
Definition BasicBlock.h:101
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:316
@ Offset
Definition DWP.cpp:577
void stable_sort(R &&Range)
Definition STLExtras.h:2132
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1781
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI bool verifyFunction(const Function &F, raw_ostream *OS=nullptr)
Check a function for errors, useful for use when debugging a pass.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2224
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:649
constexpr std::enable_if_t< std::is_signed_v< T >, std::pair< T, bool > > AddOverflow(T X, T Y)
Add two signed integers, computing the two's complement truncated result, returning a pair {result,...
Definition MathExtras.h:698
LLVM_ABI std::optional< TypeSize > getBaseObjectSize(const Value *Ptr, const DataLayout &DL, const TargetLibraryInfo *TLI, ObjectSizeOpts Opts={})
Like getObjectSize(), but only returns the size of base objects (like allocas, global variables and a...
const Value * getPointerOperand(const Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
DomTreeNodeBase< BasicBlock > DomTreeNode
Definition Dominators.h:65
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
constexpr std::enable_if_t< std::is_signed_v< T >, std::pair< T, bool > > SubOverflow(T X, T Y)
Subtract two signed integers, computing the two's complement truncated result, returning a pair {resu...
Definition MathExtras.h:735
constexpr unsigned MaxAnalysisRecursionDepth
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1652
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
@ Other
Any other memory.
Definition ModRef.h:68
@ Sub
Subtraction of integers.
@ Add
Sum of integers.
DWARFExpression::Operation Op
LLVM_ABI void remapInstructionsInBlocks(ArrayRef< BasicBlock * > Blocks, ValueToValueMapTy &VMap)
Remaps instructions in Blocks using the mapping in VMap.
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1933
LLVM_ABI bool isGuaranteedToTransferExecutionToSuccessor(const Instruction *I)
Return true if this function can prove that the instruction I will always transfer execution to one o...
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
Definition STLExtras.h:2035
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1788
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition STLExtras.h:2208
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition iterator.h:368
constexpr std::enable_if_t< std::is_signed_v< T >, std::pair< T, bool > > MulOverflow(T X, T Y)
Multiply two signed integers, computing the two's complement truncated result, returning a pair {resu...
Definition MathExtras.h:772
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be poison, but may be undef.
LLVM_ABI bool isKnownPositive(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the given value is known be positive (i.e.
LLVM_ABI bool isKnownNonNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the give value is known to be non-negative.
LLVM_ABI void findDbgUsers(Value *V, SmallVectorImpl< DbgVariableRecord * > &DbgVariableRecords)
Finds the debug info records describing a value.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
Various options to control the behavior of getObjectSize.
bool NullIsUnknownSize
If this is true, null pointers in address space 0 will be treated as though they can't be evaluated.
bool RoundToAlign
Whether to round the result up to the alignment of allocas, byval arguments, and global variables.
A MapVector that performs no allocations if smaller than a certain size.
Definition MapVector.h:342