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
15#include "ScalarOptions.h"
17#include "llvm/ADT/STLExtras.h"
18#include "llvm/ADT/ScopeExit.h"
20#include "llvm/ADT/Statistic.h"
31#include "llvm/IR/DataLayout.h"
32#include "llvm/IR/DebugInfo.h"
33#include "llvm/IR/Dominators.h"
34#include "llvm/IR/Function.h"
35#include "llvm/IR/IRBuilder.h"
36#include "llvm/IR/InstrTypes.h"
38#include "llvm/IR/Module.h"
40#include "llvm/IR/Verifier.h"
41#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
61static int64_t MaxConstraintValue = std::numeric_limits<int64_t>::max();
62static int64_t MinSignedConstraintValue = std::numeric_limits<int64_t>::min();
63
65 Instruction *UserI = cast<Instruction>(U.getUser());
66 if (auto *Phi = dyn_cast<PHINode>(UserI))
67 UserI = Phi->getIncomingBlock(U)->getTerminator();
68 return UserI;
69}
70
71/// Returns the closest program point dominating all uses of \p I.
73 DominatorTree &DT) {
74 Instruction *CommonDom = nullptr;
75 unsigned NumUses = 0;
76 for (Use &U : I.uses()) {
77 // Conservatively use original instruction, if there are too many uses.
78 if (++NumUses == 16)
79 return &I;
81 CommonDom =
82 CommonDom ? DT.findNearestCommonDominator(CommonDom, UserI) : UserI;
83 }
84 if (!CommonDom)
85 return &I;
86 // Uses in unreachable blocks are not in the dominator tree.
87 return DT.getNode(CommonDom->getParent()) ? CommonDom : &I;
88}
89
90namespace {
91using Entry = ConstraintSystem::Entry;
92using RowTy = ConstraintSystem::RowTy;
93
94/// Struct to express a condition of the form %Op0 Pred %Op1.
95struct ConditionTy {
96 CmpPredicate Pred;
97 Value *Op0 = nullptr;
98 Value *Op1 = nullptr;
99
100 ConditionTy() = default;
101 ConditionTy(CmpPredicate Pred, Value *Op0, Value *Op1)
102 : Pred(Pred), Op0(Op0), Op1(Op1) {}
103};
104
105/// Represents either
106/// * a condition that holds on entry to a block (=condition fact)
107/// * an assume (=assume fact)
108/// * a use of a compare instruction to simplify.
109/// It also tracks the Dominator DFS in and out numbers for each entry.
110struct FactOrCheck {
111 enum class EntryTy {
112 ConditionFact, /// A condition that holds on entry to a block.
113 InstFact, /// A fact that holds after Inst executed (e.g. an assume or
114 /// min/mix intrinsic.
115 InstCheck, /// An instruction to simplify (e.g. an overflow math
116 /// intrinsics) or whose flags may be strengthened.
117 UseCheck /// An use of a compare instruction to simplify.
118 };
119
120 union {
121 Instruction *Inst;
122 Use *U;
124 };
125
126 union {
127 /// A pre-condition that must hold for the current fact to be added to the
128 /// system. Only used by condition facts.
129 ConditionTy DoesHold;
130
131 /// Context instruction for the point where conditions are checked for
132 /// InstCheck simplifications.
133 Instruction *ContextInst;
134 };
135
136 unsigned NumIn;
137 unsigned NumOut;
138 EntryTy Ty;
139
140 FactOrCheck(EntryTy Ty, DomTreeNode *DTN, Instruction *Inst,
141 Instruction *ContextInst = nullptr)
142 : Inst(Inst), ContextInst(ContextInst ? ContextInst : Inst),
143 NumIn(DTN->getDFSNumIn()), NumOut(DTN->getDFSNumOut()), Ty(Ty) {}
144
145 FactOrCheck(DomTreeNode *DTN, Use *U)
146 : U(U), ContextInst(nullptr), NumIn(DTN->getDFSNumIn()),
147 NumOut(DTN->getDFSNumOut()), Ty(EntryTy::UseCheck) {}
148
149 FactOrCheck(DomTreeNode *DTN, CmpPredicate Pred, Value *Op0, Value *Op1,
150 ConditionTy Precond = {})
151 : Cond(Pred, Op0, Op1), DoesHold(Precond), NumIn(DTN->getDFSNumIn()),
152 NumOut(DTN->getDFSNumOut()), Ty(EntryTy::ConditionFact) {}
153
154 static FactOrCheck getConditionFact(DomTreeNode *DTN, CmpPredicate Pred,
155 Value *Op0, Value *Op1,
156 ConditionTy Precond = {}) {
157 return FactOrCheck(DTN, Pred, Op0, Op1, Precond);
158 }
159
160 static FactOrCheck getInstFact(DomTreeNode *DTN, Instruction *Inst) {
161 return FactOrCheck(EntryTy::InstFact, DTN, Inst);
162 }
163
164 static FactOrCheck getCheck(DomTreeNode *DTN, Use *U) {
165 return FactOrCheck(DTN, U);
166 }
167
168 static FactOrCheck getCheck(DomTreeNode *DTN, Instruction *I,
169 Instruction *ContextInst = nullptr) {
170 assert((ContextInst ? ContextInst : I)->getParent() == DTN->getBlock() &&
171 "anchoring instruction must be in DTN's block");
172 return FactOrCheck(EntryTy::InstCheck, DTN, I, ContextInst);
173 }
174
175 bool isCheck() const {
176 return Ty == EntryTy::InstCheck || Ty == EntryTy::UseCheck;
177 }
178
179 Instruction *getContextInst() const {
180 assert(!isConditionFact());
181 if (Ty == EntryTy::UseCheck)
182 return getContextInstForUse(*U);
183 return ContextInst;
184 }
185
186 Instruction *getInstructionToSimplify() const {
187 assert(isCheck());
188 if (Ty == EntryTy::InstCheck)
189 return Inst;
190 // The use may have been simplified to a constant already.
191 return dyn_cast<Instruction>(*U);
192 }
193
194 bool isConditionFact() const { return Ty == EntryTy::ConditionFact; }
195};
196
197/// The senses in which an induction phi is monotonic, together with the
198/// direction it moves in.
199struct MonotonicInfo {
200 /// True if the phi steps by a negative constant.
201 bool Decreasing = false;
202 /// True if the phi is monotonic in the unsigned sense.
203 bool Unsigned = false;
204 /// True if the phi is monotonic in the signed sense.
205 bool Signed = false;
206};
207
208/// Keep state required to build worklist.
209struct State {
210 DominatorTree &DT;
211 LoopInfo &LI;
212 /// Only available for functions with loops.
213 ScalarEvolution *SE;
214 TargetLibraryInfo &TLI;
216
217 State(DominatorTree &DT, LoopInfo &LI, ScalarEvolution *SE,
218 TargetLibraryInfo &TLI)
219 : DT(DT), LI(LI), SE(SE), TLI(TLI) {}
220
221 /// Process block \p BB and add known facts to work-list.
222 void addInfoFor(BasicBlock &BB);
223
224 /// If \p BB is a loop header, bound each induction phi in it by its start
225 /// value.
226 void addBoundsForHeaderInductions(BasicBlock &BB);
227
228 /// Try to add facts for loop inductions (AddRecs) in EQ/NE compares
229 /// controlling the loop header.
230 void addInfoForInductions(BasicBlock &BB);
231
232 /// Returns the direction the induction phi \p PN with backedge value \p Step
233 /// moves in, and the senses in which it is monotonic in that direction.
234 MonotonicInfo getMonotonicityInfo(PHINode &PN, Value *Step);
235
236 /// Returns true if we can add a known condition from BB to its successor
237 /// block Succ.
238 bool canAddSuccessor(BasicBlock &BB, BasicBlock *Succ) const {
239 return DT.dominates(BasicBlockEdge(&BB, Succ), Succ);
240 }
241};
242
243class ConstraintInfo;
244
245struct StackEntry {
246 unsigned NumIn;
247 unsigned NumOut;
248 bool IsSigned = false;
249 /// Variables that can be removed from the system once the stack entry gets
250 /// removed.
251 SmallVector<Value *, 2> ValuesToRelease;
252
253 StackEntry(unsigned NumIn, unsigned NumOut, bool IsSigned,
254 SmallVector<Value *, 2> ValuesToRelease)
255 : NumIn(NumIn), NumOut(NumOut), IsSigned(IsSigned),
256 ValuesToRelease(std::move(ValuesToRelease)) {}
257};
258
259struct ConstraintTy {
260 RowTy Coefficients;
261
262 /// Number of variables the constraint is defined over.
263 unsigned NumVars = 0;
264
265 bool IsSigned = false;
266
267 ConstraintTy() = default;
268
269 ConstraintTy(RowTy Coefficients, unsigned NumVars, bool IsSigned, bool IsEq,
270 bool IsNe)
271 : Coefficients(std::move(Coefficients)), NumVars(NumVars),
272 IsSigned(IsSigned), IsEq(IsEq), IsNe(IsNe) {}
273
274 bool empty() const { return Coefficients.empty(); }
275
276 bool isEq() const { return IsEq; }
277
278 bool isNe() const { return IsNe; }
279
280 /// Check if the current constraint is implied by the given ConstraintSystem.
281 ///
282 /// \return true or false if the constraint is proven to be respectively true,
283 /// or false. When the constraint cannot be proven to be either true or false,
284 /// std::nullopt is returned.
285 std::optional<bool> isImpliedBy(const ConstraintSystem &CS) const;
286
287private:
288 bool IsEq = false;
289 bool IsNe = false;
290};
291
292/// Represents a (Coefficient * Variable) entry after IR decomposition.
293struct DecompEntry {
294 int64_t Coefficient;
295 Value *Variable;
296
297 DecompEntry(int64_t Coefficient, Value *Variable)
298 : Coefficient(Coefficient), Variable(Variable) {}
299};
300
301/// Represents an Offset + Coefficient1 * Variable1 + ... decomposition.
302struct Decomposition {
303 int64_t Offset = 0;
305
306 Decomposition(int64_t Offset) : Offset(Offset) {}
307 Decomposition(Value *V) { Vars.emplace_back(1, V); }
308 Decomposition(int64_t Offset, ArrayRef<DecompEntry> Vars)
309 : Offset(Offset), Vars(Vars) {}
310
311 /// Add \p OtherOffset and return true if the operation overflows, i.e. the
312 /// new decomposition is invalid.
313 [[nodiscard]] bool add(int64_t OtherOffset) {
314 return AddOverflow(Offset, OtherOffset, Offset);
315 }
316
317 /// Add \p Other and return true if the operation overflows, i.e. the new
318 /// decomposition is invalid.
319 [[nodiscard]] bool add(const Decomposition &Other) {
320 if (add(Other.Offset))
321 return true;
322 append_range(Vars, Other.Vars);
323 return false;
324 }
325
326 /// Subtract \p Other and return true if the operation overflows, i.e. the new
327 /// decomposition is invalid.
328 [[nodiscard]] bool sub(const Decomposition &Other) {
329 Decomposition Tmp = Other;
330 if (Tmp.mul(-1))
331 return true;
332 if (add(Tmp.Offset))
333 return true;
334 append_range(Vars, Tmp.Vars);
335 return false;
336 }
337
338 /// Multiply all coefficients by \p Factor and return true if the operation
339 /// overflows, i.e. the new decomposition is invalid.
340 [[nodiscard]] bool mul(int64_t Factor) {
341 if (MulOverflow(Offset, Factor, Offset))
342 return true;
343 for (auto &Var : Vars)
344 if (MulOverflow(Var.Coefficient, Factor, Var.Coefficient))
345 return true;
346 return false;
347 }
348};
349
350/// Wrapper encapsulating separate constraint systems and corresponding value
351/// mappings for both unsigned and signed information. Facts are added to and
352/// conditions are checked against the corresponding system depending on the
353/// signed-ness of their predicates. While the information is kept separate
354/// based on signed-ness, certain conditions can be transferred between the two
355/// systems.
356class ConstraintInfo {
357
358 ConstraintSystem UnsignedCS;
359 ConstraintSystem SignedCS;
360
361 const DataLayout &DL;
362
363 /// Decompositions computed against the current state of the systems. Must be
364 /// cleared when the system changes.
365 DenseMap<PointerIntPair<Value *, 1, bool>, Decomposition> DecomposeCache;
366
367public:
368 DenseMap<PointerIntPair<Value *, 1, bool>, Decomposition> &
369 getDecomposeCache() {
370 return DecomposeCache;
371 }
372
373 ConstraintInfo(const DataLayout &DL, ArrayRef<Value *> FunctionArgs)
374 : UnsignedCS(FunctionArgs), SignedCS(FunctionArgs), DL(DL) {
375 auto &Value2Index = getValue2Index(false);
376 // Add Arg > -1 constraints to unsigned system for all function arguments.
377 for (Value *Arg : FunctionArgs)
378 UnsignedCS.addRow({Entry(0, 0), Entry(-1, Value2Index.at(Arg))},
379 Value2Index.size());
380 }
381
382 DenseMap<Value *, unsigned> &getValue2Index(bool Signed) {
383 return Signed ? SignedCS.getValue2Index() : UnsignedCS.getValue2Index();
384 }
385 const DenseMap<Value *, unsigned> &getValue2Index(bool Signed) const {
386 return Signed ? SignedCS.getValue2Index() : UnsignedCS.getValue2Index();
387 }
388
389 ConstraintSystem &getCS(bool Signed) {
390 return Signed ? SignedCS : UnsignedCS;
391 }
392 const ConstraintSystem &getCS(bool Signed) const {
393 return Signed ? SignedCS : UnsignedCS;
394 }
395
396 void popLastConstraint(bool Signed) {
397 assert(DecomposeCache.empty() && "Cache must be cleared");
398 getCS(Signed).popLastConstraint();
399 }
400 void popLastNVariables(bool Signed, unsigned N) {
401 assert(DecomposeCache.empty() && "Cache must be cleared");
402 getCS(Signed).popLastNVariables(N);
403 }
404
405 bool doesHold(CmpInst::Predicate Pred, Value *A, Value *B);
406
407 /// Returns true if \p V is known to be non-negative, either because the
408 /// signed system implies it or because ValueTracking can prove it.
409 bool isKnownNonNegative(Value *V);
410
411 /// Returns true if \p V is known to be positive, either because the signed
412 /// system implies it or because ValueTracking can prove it.
413 bool isKnownPositive(Value *V);
414
415 void addFact(CmpInst::Predicate Pred, Value *A, Value *B, unsigned NumIn,
416 unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack);
417
418 /// Turn a comparison of the form \p Op0 \p Pred \p Op1 into a vector of
419 /// constraints, using indices from the corresponding constraint system.
420 /// New variables that need to be added to the system are collected in
421 /// \p NewVariables.
422 ConstraintTy getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
423 SmallVectorImpl<Value *> &NewVariables,
424 bool ForceSignedSystem = false);
425
426 /// Turns a comparison of the form \p Op0 \p Pred \p Op1 into a vector of
427 /// constraints using getConstraint. Returns an empty constraint if the result
428 /// cannot be used to query the existing constraint system, e.g. because it
429 /// would require adding new variables. Also tries to convert signed
430 /// predicates to unsigned ones if possible to allow using the unsigned system
431 /// which increases the effectiveness of the signed <-> unsigned transfer
432 /// logic.
433 ConstraintTy getConstraintForSolving(CmpInst::Predicate Pred, Value *Op0,
434 Value *Op1);
435
436 /// Try to add information from \p A \p Pred \p B to the unsigned/signed
437 /// system if \p Pred is signed/unsigned.
438 void transferToOtherSystem(CmpInst::Predicate Pred, Value *A, Value *B,
439 unsigned NumIn, unsigned NumOut,
440 SmallVectorImpl<StackEntry> &DFSInStack);
441
442private:
443 /// Adds facts into constraint system. \p ForceSignedSystem can be set when
444 /// the \p Pred is eq/ne, and signed constraint system is used when it's
445 /// specified.
446 void addFactImpl(CmpInst::Predicate Pred, Value *A, Value *B, unsigned NumIn,
447 unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack,
448 bool ForceSignedSystem);
449
450 /// Try to use the inequality \p A != \p B to tighten a non-strict bound the
451 /// system already implies to the corresponding strict bound.
452 void tightenBoundUsingNe(Value *A, Value *B, unsigned NumIn, unsigned NumOut,
453 SmallVectorImpl<StackEntry> &DFSInStack);
454};
455
456// Variable and constant offsets for a chain of GEPs, with base pointer BasePtr.
457struct OffsetResult {
458 Value *BasePtr;
459 APInt ConstantOffset;
460 SmallMapVector<Value *, APInt, 4> VariableOffsets;
461 GEPNoWrapFlags NW;
462
463 OffsetResult() : BasePtr(nullptr), ConstantOffset(0, uint64_t(0)) {}
464
465 OffsetResult(GEPOperator &GEP, const DataLayout &DL)
466 : BasePtr(GEP.getPointerOperand()), NW(GEP.getNoWrapFlags()) {
467 ConstantOffset = APInt(DL.getIndexTypeSizeInBits(BasePtr->getType()), 0);
468 }
469};
470} // namespace
471
472// Try to collect variable and constant offsets for \p GEP, partly traversing
473// nested GEPs. Returns an OffsetResult with nullptr as BasePtr of collecting
474// the offset fails.
476 OffsetResult Result(GEP, DL);
477 unsigned BitWidth = Result.ConstantOffset.getBitWidth();
478 if (!GEP.collectOffset(DL, BitWidth, Result.VariableOffsets,
479 Result.ConstantOffset))
480 return {};
481
482 // If we have a nested GEP, check if we can combine the constant offset of the
483 // inner GEP with the outer GEP.
484 if (auto *InnerGEP = dyn_cast<GetElementPtrInst>(Result.BasePtr)) {
485 SmallMapVector<Value *, APInt, 4> VariableOffsets2;
486 APInt ConstantOffset2(BitWidth, 0);
487 bool CanCollectInner = InnerGEP->collectOffset(
488 DL, BitWidth, VariableOffsets2, ConstantOffset2);
489 // TODO: Support cases with more than 1 variable offset.
490 if (!CanCollectInner || Result.VariableOffsets.size() > 1 ||
491 VariableOffsets2.size() > 1 ||
492 (Result.VariableOffsets.size() >= 1 && VariableOffsets2.size() >= 1)) {
493 // More than 1 variable index, use outer result.
494 return Result;
495 }
496 // The GEPs' wrap flags do not prevent the sum of the offsets from
497 // sign-wrapping.
498 bool Overflow = false;
499 APInt CombinedOffset =
500 Result.ConstantOffset.sadd_ov(ConstantOffset2, Overflow);
501 if (Overflow)
502 return Result;
503
504 Result.BasePtr = InnerGEP->getPointerOperand();
505 Result.ConstantOffset = CombinedOffset;
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 // Indices narrower or wider than the index type are implicitly
645 // sign-extended or truncated. Don't reason about them.
646 if (Index->getType()->getScalarSizeInBits() != Scale.getBitWidth())
647 return &GEP;
648 if (!NW.hasNoUnsignedWrap()) {
649 // Try to prove nuw from nusw and nneg. If the index cannot be proven
650 // non-negative, keep the GEP as-is instead of decomposing it.
651 assert(NW.hasNoUnsignedSignedWrap() && "Must have nusw flag");
652 if (!Info.isKnownNonNegative(Index))
653 return &GEP;
654 } else if (!NW.hasNoUnsignedSignedWrap()) {
655 // For a nuw-only GEP, the scale is unsigned and must fit in the signed
656 // coefficient.
657 if (Scale.isNegative())
658 return &GEP;
659 }
660
661 auto IdxResult = decompose(Index, Info, IsSigned, DL);
662 if (IdxResult.mul(Scale.getSExtValue()))
663 return &GEP;
664 if (Result.add(IdxResult))
665 return &GEP;
666 }
667 return Result;
668}
669
670// Decomposes \p V into a constant offset + list of pairs { Coefficient,
671// Variable } where Coefficient * Variable. The sum of the constant offset and
672// pairs equals \p V.
673//
674// Looking through certain expressions is only valid if a pre-condition holds.
675// Pre-conditions are checked against \p Info as needed.
676static Decomposition decomposeImpl(Value *V, ConstraintInfo &Info,
677 bool IsSigned, const DataLayout &DL);
678
679/// Returns true if \p V is an operation decomposeImpl can look through.
680static bool mayLookThrough(Value *V) {
681 auto *Op = dyn_cast<Operator>(V);
682 if (!Op)
683 return false;
684 switch (Op->getOpcode()) {
685 case Instruction::GetElementPtr:
686 case Instruction::Add:
687 case Instruction::Sub:
688 case Instruction::Mul:
689 case Instruction::Shl:
690 case Instruction::LShr:
691 case Instruction::AShr:
692 case Instruction::ZExt:
693 case Instruction::SExt:
694 case Instruction::Trunc:
695 case Instruction::Or:
696 case Instruction::Xor:
697 return true;
698 default:
699 return false;
700 }
701}
702
703static Decomposition decompose(Value *V, ConstraintInfo &Info, bool IsSigned,
704 const DataLayout &DL) {
705 if (!mayLookThrough(V))
706 return decomposeImpl(V, Info, IsSigned, DL);
707
709 auto &Cache = Info.getDecomposeCache();
710 auto It = Cache.find(Key);
711 if (It != Cache.end())
712 return It->second;
713
714 Decomposition Result = decomposeImpl(V, Info, IsSigned, DL);
715 Info.getDecomposeCache().insert({Key, Result});
716 return Result;
717}
718
719static Decomposition decomposeImpl(Value *V, ConstraintInfo &Info,
720 bool IsSigned, const DataLayout &DL) {
721 auto MergeResults = [&Info, IsSigned,
722 &DL](Value *A, Value *B,
723 bool IsSignedB) -> std::optional<Decomposition> {
724 auto ResA = decompose(A, Info, IsSigned, DL);
725 auto ResB = decompose(B, Info, IsSignedB, DL);
726 if (ResA.add(ResB))
727 return std::nullopt;
728 return ResA;
729 };
730
731 Type *Ty = V->getType()->getScalarType();
732 if (Ty->isPointerTy() && !IsSigned) {
733 if (auto *GEP = dyn_cast<GEPOperator>(V))
734 return decomposeGEP(*GEP, Info, IsSigned, DL);
736 return int64_t(0);
737
738 return V;
739 }
740
741 // Don't handle integers > 64 bit. Our coefficients are 64-bit large, so
742 // coefficient add/mul may wrap, while the operation in the full bit width
743 // would not.
744 if (!Ty->isIntegerTy() || Ty->getIntegerBitWidth() > 64)
745 return V;
746
747 if (auto *CI = dyn_cast<ConstantInt>(V)) {
748 if (IsSigned) {
749 if (canUseSExt(CI))
750 return CI->getSExtValue();
751 } else if (!CI->uge(MaxConstraintValue)) {
752 return int64_t(CI->getZExtValue());
753 }
754 return V;
755 }
756
757 Value *Op0;
758 Value *Op1;
759 ConstantInt *CI;
760
761 if (match(V, m_ZExt(m_Value(Op0)))) {
762 // In the signed system, the ZExt must be non-negative.
763 if (IsSigned && !cast<ZExtInst>(V)->hasNonNeg())
764 return V;
765 V = Op0;
766 } else if (match(V, m_SExt(m_Value(Op0)))) {
767 // In the unsigned system, the SExt operand must be non-negative.
768 if (!IsSigned && !Info.isKnownNonNegative(Op0))
769 return V;
770 V = Op0;
771 } else if (auto *Trunc = dyn_cast<TruncInst>(V)) {
772 if (Trunc->getSrcTy()->getScalarSizeInBits() <= 64 &&
773 isKnownNoWrap(Trunc, Info, IsSigned))
774 V = Trunc->getOperand(0);
775 }
776
777 if (match(V, m_AddLike(m_Value(Op0), m_Value(Op1)))) {
778 if (isKnownNoWrap(V, Info, IsSigned)) {
779 if (auto Decomp = MergeResults(Op0, Op1, IsSigned))
780 return *Decomp;
781 return V;
782 }
783 // In the unsigned system, adding a negative constant only wraps if Op0 is
784 // smaller than it.
785 if (!IsSigned && match(Op1, m_ConstantInt(CI)) && CI->isNegative() &&
786 canUseSExt(CI) &&
787 Info.doesHold(CmpInst::ICMP_UGE, Op0,
788 ConstantInt::get(Op0->getType(), -CI->getSExtValue())))
789 if (auto Decomp = MergeResults(Op0, CI, /*IsSignedB=*/true))
790 return *Decomp;
791 return V;
792 }
793
794 // `xor %x, -1` is equivalent to `sub nsw -1, %x`.
795 if (IsSigned && match(V, m_Not(m_Value(Op0)))) {
796 Decomposition Result(-1);
797 if (!Result.sub(decompose(Op0, Info, IsSigned, DL)))
798 return Result;
799 return V;
800 }
801
802 if (match(V, m_Sub(m_Value(Op0), m_Value(Op1)))) {
803 if (isKnownNoWrap(V, Info, IsSigned)) {
804 auto ResA = decompose(Op0, Info, IsSigned, DL);
805 auto ResB = decompose(Op1, Info, IsSigned, DL);
806 if (!ResA.sub(ResB))
807 return ResA;
808 }
809 return V;
810 }
811
812 if (match(V, m_Mul(m_Value(Op0), m_ConstantInt(CI)))) {
813 // A negative constant is only a valid coefficient in the signed system; in
814 // the unsigned system the multiplier is the constant's unsigned value.
815 if (canUseSExt(CI) && (IsSigned || !CI->isNegative()) &&
816 isKnownNoWrap(V, Info, IsSigned)) {
817 auto Result = decompose(Op0, Info, IsSigned, DL);
818 if (!Result.mul(CI->getSExtValue()))
819 return Result;
820 }
821 return V;
822 }
823
824 if (match(V, m_Exact(m_Shr(m_Value(Op0), m_ConstantInt(CI))))) {
825 bool IsAShr = cast<Operator>(V)->getOpcode() == Instruction::AShr;
826 if (CI->getValue().ult(std::min(63u, CI->getBitWidth())) &&
827 (IsSigned == IsAShr || Info.isKnownNonNegative(Op0))) {
828 int64_t Factor = int64_t(1) << CI->getZExtValue();
829 auto Result = decompose(Op0, Info, IsSigned, DL);
830 if (Result.Offset % Factor == 0 &&
831 all_of(Result.Vars, [Factor](const DecompEntry &E) {
832 return E.Coefficient % Factor == 0;
833 })) {
834 Result.Offset /= Factor;
835 for (auto &E : Result.Vars)
836 E.Coefficient /= Factor;
837 return Result;
838 }
839 }
840 return V;
841 }
842
843 if (match(V, m_Shl(m_Value(Op0), m_ConstantInt(CI)))) {
844 // (shl x, shift) is (mul x, 1 << shift). The scale must fit in the signed
845 // coefficient, so reject shifts >= 63. Also reject a shift of bw-1, for
846 // which the product is not representable.
847 int64_t MaxShift = IsSigned ? Ty->getIntegerBitWidth() - 1 : 63;
848 if (!CI->isNegative() && CI->getSExtValue() < MaxShift &&
849 isKnownNoWrap(V, Info, IsSigned)) {
850 auto Result = decompose(Op0, Info, IsSigned, DL);
851 if (!Result.mul(int64_t{1} << CI->getSExtValue()))
852 return Result;
853 }
854 return V;
855 }
856
857 return V;
858}
859
860/// Build the row for 'ADec <= BDec', using the indices from \p Value2Index.
861/// Variables not in \p Value2Index are appended to \p NewVariables and get the
862/// indices following the ones in \p Value2Index. Returns an empty row if the
863/// coefficients overflow.
864static RowTy getRowForLessEqual(const Decomposition &ADec,
865 const Decomposition &BDec,
866 const DenseMap<Value *, unsigned> &Value2Index,
867 SmallVectorImpl<Value *> &NewVariables) {
868 // Build the row, by first adding all coefficients from A and then subtracting
869 // all coefficients from B.
870 int64_t OffsetSum;
871 if (SubOverflow(BDec.Offset, ADec.Offset, OffsetSum))
872 return {};
873 RowTy R(1, Entry(OffsetSum, 0));
874 auto GetCoefficient = [&R](unsigned Idx) -> int64_t & {
875 // The entry for Idx, or the place to insert it at, is the first entry with
876 // an index >= Idx.
877 Entry *I =
878 find_if(drop_begin(R), [Idx](const Entry &E) { return E.Id >= Idx; });
879 if (I == R.end() || I->Id != Idx)
880 I = R.insert(I, Entry(0, Idx));
881 return I->Coefficient;
882 };
883 // First try to look up \p V in Value2Index and NewVariables. Otherwise add a
884 // new entry to NewVariables.
885 auto GetOrAddIndex = [&Value2Index, &NewVariables](Value *V) -> unsigned {
886 auto V2I = Value2Index.find(V);
887 if (V2I != Value2Index.end())
888 return V2I->second;
889 unsigned Idx = find(NewVariables, V) - NewVariables.begin();
890 if (Idx == NewVariables.size())
891 NewVariables.push_back(V);
892 return Value2Index.size() + Idx + 1;
893 };
894 for (const DecompEntry &KV : ADec.Vars)
895 GetCoefficient(GetOrAddIndex(KV.Variable)) += KV.Coefficient;
896
897 for (const DecompEntry &KV : BDec.Vars) {
898 auto &Coeff = GetCoefficient(GetOrAddIndex(KV.Variable));
899 if (SubOverflow(Coeff, KV.Coefficient, Coeff))
900 return {};
901 }
902
903 // Drop coefficients that cancelled out.
904 erase_if(R, [](const Entry &E) { return E.Id != 0 && E.Coefficient == 0; });
905 return R;
906}
907
908ConstraintTy
909ConstraintInfo::getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
910 SmallVectorImpl<Value *> &NewVariables,
911 bool ForceSignedSystem) {
912 assert(NewVariables.empty() && "NewVariables must be empty when passed in");
913 assert((!ForceSignedSystem || CmpInst::isEquality(Pred)) &&
914 "signed system can only be forced on eq/ne");
915
916 bool IsEq = false;
917 bool IsNe = false;
918
919 // Try to convert Pred to one of ULE/ULT/SLE/SLT.
920 switch (Pred) {
924 case CmpInst::ICMP_SGE: {
925 Pred = CmpInst::getSwappedPredicate(Pred);
926 std::swap(Op0, Op1);
927 break;
928 }
929 case CmpInst::ICMP_EQ:
930 if (!ForceSignedSystem && match(Op1, m_Zero())) {
931 Pred = CmpInst::ICMP_ULE;
932 } else {
933 IsEq = true;
934 Pred = CmpInst::ICMP_ULE;
935 }
936 break;
937 case CmpInst::ICMP_NE:
938 if (!ForceSignedSystem && match(Op1, m_Zero())) {
940 std::swap(Op0, Op1);
941 } else {
942 IsNe = true;
943 Pred = CmpInst::ICMP_ULE;
944 }
945 break;
946 default:
947 break;
948 }
949
950 if (Pred != CmpInst::ICMP_ULE && Pred != CmpInst::ICMP_ULT &&
951 Pred != CmpInst::ICMP_SLE && Pred != CmpInst::ICMP_SLT)
952 return {};
953
954 bool IsSigned = ForceSignedSystem || CmpInst::isSigned(Pred);
955 auto &Value2Index = getValue2Index(IsSigned);
956 auto ADec = decompose(Op0->stripPointerCastsSameRepresentation(), *this,
957 IsSigned, DL);
958 auto BDec = decompose(Op1->stripPointerCastsSameRepresentation(), *this,
959 IsSigned, DL);
960 RowTy R = getRowForLessEqual(ADec, BDec, Value2Index, NewVariables);
961 if (R.empty())
962 return {};
963
964 if (Pred == CmpInst::ICMP_SLT || Pred == CmpInst::ICMP_ULT)
965 if (AddOverflow(R[0].Coefficient, int64_t(-1), R[0].Coefficient))
966 return {};
967
968 // Remove any new variable without a coefficient in the row.
969 unsigned NumV2I = Value2Index.size();
970 NewVariables.truncate(R.back().Id > NumV2I ? R.back().Id - NumV2I : 0);
971
972 return ConstraintTy(std::move(R), Value2Index.size() + NewVariables.size(),
973 IsSigned, IsEq, IsNe);
974}
975
976ConstraintTy ConstraintInfo::getConstraintForSolving(CmpInst::Predicate Pred,
977 Value *Op0, Value *Op1) {
978 Constant *NullC = Constant::getNullValue(Op0->getType());
979 // Handle trivially true compares directly to avoid adding V UGE 0 constraints
980 // for all variables in the unsigned system.
981 if ((Pred == CmpInst::ICMP_ULE && Op0 == NullC) ||
982 (Pred == CmpInst::ICMP_UGE && Op1 == NullC)) {
983 // Return constraint that's trivially true.
984 return ConstraintTy(RowTy(1, Entry(0, 0)), /*NumVars=*/0,
985 /*IsSigned=*/false, /*IsEq=*/false, /*IsNe=*/false);
986 }
987
988 // If both operands are known to be non-negative, change signed predicates to
989 // unsigned ones. This increases the reasoning effectiveness in combination
990 // with the signed <-> unsigned transfer logic.
991 if (CmpInst::isSigned(Pred) &&
995
996 SmallVector<Value *> NewVariables;
997 ConstraintTy R = getConstraint(Pred, Op0, Op1, NewVariables);
998 if (!NewVariables.empty())
999 return {};
1000 return R;
1001}
1002
1003std::optional<bool>
1004ConstraintTy::isImpliedBy(const ConstraintSystem &CS) const {
1005 const auto &[SubCS, NewCoefficients] = CS.getSubSystem(Coefficients);
1006 bool IsConditionImplied = SubCS.isConditionImplied(NewCoefficients);
1007
1008 if (IsEq || IsNe) {
1009 auto NegatedOrEqual = ConstraintSystem::negateOrEqual(NewCoefficients);
1010 bool IsNegatedOrEqualImplied =
1011 !NegatedOrEqual.empty() && SubCS.isConditionImplied(NegatedOrEqual);
1012
1013 // In order to check that `%a == %b` is true (equality), both conditions `%a
1014 // >= %b` and `%a <= %b` must hold true. When checking for equality (`IsEq`
1015 // is true), we return true if they both hold, false in the other cases.
1016 if (IsConditionImplied && IsNegatedOrEqualImplied)
1017 return IsEq;
1018
1019 auto Negated = ConstraintSystem::negate(NewCoefficients);
1020 bool IsNegatedImplied =
1021 !Negated.empty() && SubCS.isConditionImplied(Negated);
1022
1023 auto StrictLessThan = ConstraintSystem::toStrictLessThan(NewCoefficients);
1024 bool IsStrictLessThanImplied =
1025 !StrictLessThan.empty() && SubCS.isConditionImplied(StrictLessThan);
1026
1027 // In order to check that `%a != %b` is true (non-equality), either
1028 // condition `%a > %b` or `%a < %b` must hold true. When checking for
1029 // non-equality (`IsNe` is true), we return true if one of the two holds,
1030 // false in the other cases.
1031 if (IsNegatedImplied || IsStrictLessThanImplied)
1032 return IsNe;
1033
1034 return std::nullopt;
1035 }
1036
1037 if (IsConditionImplied)
1038 return true;
1039
1040 auto Negated = ConstraintSystem::negate(NewCoefficients);
1041 auto IsNegatedImplied = !Negated.empty() && SubCS.isConditionImplied(Negated);
1042 if (IsNegatedImplied)
1043 return false;
1044
1045 // Neither the condition nor its negated holds, did not prove anything.
1046 return std::nullopt;
1047}
1048
1049bool ConstraintInfo::doesHold(CmpInst::Predicate Pred, Value *A, Value *B) {
1050 auto R = getConstraintForSolving(Pred, A, B);
1051 return !R.empty() &&
1052 getCS(R.IsSigned).isConditionImpliedInSubSystem(R.Coefficients);
1053}
1054
1055bool ConstraintInfo::isKnownNonNegative(Value *V) {
1056 if (auto *CI = dyn_cast<ConstantInt>(V))
1057 return !CI->isNegative();
1058 return ::isKnownNonNegative(V, DL) ||
1059 doesHold(CmpInst::ICMP_SGE, V, ConstantInt::get(V->getType(), 0));
1060}
1061
1062bool ConstraintInfo::isKnownPositive(Value *V) {
1063 if (auto *CI = dyn_cast<ConstantInt>(V))
1064 return CI->getValue().isStrictlyPositive();
1065 return ::isKnownPositive(V, DL) ||
1066 doesHold(CmpInst::ICMP_SGT, V, ConstantInt::get(V->getType(), 0));
1067}
1068
1069void ConstraintInfo::transferToOtherSystem(
1070 CmpInst::Predicate Pred, Value *A, Value *B, unsigned NumIn,
1071 unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack) {
1072 // Check if we can combine facts from the signed and unsigned systems to
1073 // derive additional facts.
1074 if (!A->getType()->isIntegerTy())
1075 return;
1076 // FIXME: This currently depends on the order we add facts. Ideally we
1077 // would first add all known facts and only then try to add additional
1078 // facts.
1079 switch (Pred) {
1080 default:
1081 break;
1082 case CmpInst::ICMP_ULT:
1083 case CmpInst::ICMP_ULE:
1084 // If B is a signed positive constant, then A >=s 0 and A <s (or <=s) B.
1085 if (isKnownNonNegative(B)) {
1086 addFact(CmpInst::ICMP_SGE, A, ConstantInt::get(B->getType(), 0), NumIn,
1087 NumOut, DFSInStack);
1088 addFact(ICmpInst::getSignedPredicate(Pred), A, B, NumIn, NumOut,
1089 DFSInStack);
1090 }
1091 break;
1092 case CmpInst::ICMP_UGE:
1093 case CmpInst::ICMP_UGT:
1094 // If A is a signed positive constant, then B >=s 0 and A >s (or >=s) B.
1095 if (isKnownNonNegative(A)) {
1096 addFact(CmpInst::ICMP_SGE, B, ConstantInt::get(B->getType(), 0), NumIn,
1097 NumOut, DFSInStack);
1098 addFact(ICmpInst::getSignedPredicate(Pred), A, B, NumIn, NumOut,
1099 DFSInStack);
1100 }
1101 break;
1102 case CmpInst::ICMP_SLT:
1103 case CmpInst::ICMP_SLE:
1104 if (isKnownNonNegative(A))
1105 addFact(ICmpInst::getUnsignedPredicate(Pred), A, B, NumIn, NumOut,
1106 DFSInStack);
1107 break;
1108 case CmpInst::ICMP_SGT: {
1109 if (doesHold(CmpInst::ICMP_SGE, B, Constant::getAllOnesValue(B->getType())))
1110 addFact(CmpInst::ICMP_UGE, A, ConstantInt::get(B->getType(), 0), NumIn,
1111 NumOut, DFSInStack);
1112 if (isKnownNonNegative(B))
1113 addFact(CmpInst::ICMP_UGT, A, B, NumIn, NumOut, DFSInStack);
1114
1115 break;
1116 }
1117 case CmpInst::ICMP_SGE:
1118 if (isKnownNonNegative(B))
1119 addFact(CmpInst::ICMP_UGE, A, B, NumIn, NumOut, DFSInStack);
1120 break;
1121 }
1122}
1123
1124#ifndef NDEBUG
1125
1127 const DenseMap<Value *, unsigned> &Value2Index) {
1128 ConstraintSystem CS(Value2Index);
1129 CS.addRow(C, Value2Index.size());
1130 CS.dump();
1131}
1132#endif
1133
1134/// Splits the induction phi \p PN into the start value, coming from the loop
1135/// predecessor \p LoopPred, and the backedge value, coming from inside the
1136/// loop. Returns {nullptr, nullptr} if \p PN has other incoming values.
1137static std::pair<Value *, Value *>
1138getStartAndBackedgeValue(const PHINode &PN, const BasicBlock *LoopPred) {
1139 assert(PN.getBasicBlockIndex(LoopPred) >= 0 &&
1140 "LoopPred must be a predecessor of the phi's block");
1141 if (PN.getNumIncomingValues() != 2)
1142 return {nullptr, nullptr};
1143 unsigned StartIdx = PN.getIncomingBlock(0) == LoopPred ? 0 : 1;
1144 return {PN.getIncomingValue(StartIdx), PN.getIncomingValue(1 - StartIdx)};
1145}
1146
1147/// Matches an increment of \p PhiM by a constant offset, captured in \p Off.
1148/// The increment must be a plain IR add or [u|s]add.with.overflow.
1149template <typename PhiMatchTy>
1150static auto m_IncrementOf(const PhiMatchTy &PhiM, const APInt *&Off) {
1151 return m_CombineOr(
1152 m_c_Add(PhiM, m_APInt(Off)),
1156}
1157
1158MonotonicInfo State::getMonotonicityInfo(PHINode &PN, Value *Step) {
1159 MonotonicInfo Info;
1160 const APInt *StepOffset = nullptr;
1161 if (match(Step, m_IncrementOf(m_Specific(&PN), StepOffset))) {
1162 Info.Decreasing = StepOffset->isNegative();
1163 if (const auto *Add = dyn_cast<OverflowingBinaryOperator>(Step)) {
1164 Info.Unsigned = !Info.Decreasing && Add->hasNoUnsignedWrap();
1165 Info.Signed = Add->hasNoSignedWrap();
1166 }
1167 } else if (const auto *GEP = dyn_cast<GEPOperator>(Step)) {
1168 // TODO: Handle the non-increasing direction, which needs a nusw GEP with a
1169 // negative constant offset.
1170 const DataLayout &DL = PN.getDataLayout();
1171 APInt GEPOffset(DL.getIndexTypeSizeInBits(GEP->getType()), 0);
1172 Info.Unsigned = GEP->getPointerOperand() == &PN &&
1173 (GEP->hasNoUnsignedWrap() ||
1174 ((GEP->hasNoUnsignedSignedWrap() &&
1175 GEP->accumulateConstantOffset(DL, GEPOffset) &&
1176 !GEPOffset.isNegative())));
1177 }
1178
1179 // Forming the SCEV of a phi is expensive, so only consult it for a PN + C
1180 // step whose no-wrap flags prove nothing.
1181 if (Info.Unsigned || Info.Signed || !StepOffset)
1182 return Info;
1183
1184 const auto *AR = dyn_cast<SCEVAddRecExpr>(SE->getSCEV(&PN));
1185 if (!AR)
1186 return Info;
1190 auto IsMonotonic = [&](CmpInst::Predicate Pred) {
1191 return SE->getMonotonicPredicateType(AR, Pred) == Expected;
1192 };
1193 Info.Signed = IsMonotonic(CmpInst::ICMP_SGT);
1194 Info.Unsigned = !Info.Decreasing && IsMonotonic(CmpInst::ICMP_UGT);
1195 return Info;
1196}
1197
1198void State::addBoundsForHeaderInductions(BasicBlock &BB) {
1199 Loop *L = LI.getLoopFor(&BB);
1200 if (!L || L->getHeader() != &BB)
1201 return;
1202 BasicBlock *LoopPred = L->getLoopPredecessor();
1203 if (!LoopPred)
1204 return;
1205
1206 DomTreeNode *DTN = DT.getNode(&BB);
1207 for (PHINode &PN : BB.phis()) {
1208 if (!PN.getType()->isIntegerTy() && !PN.getType()->isPointerTy())
1209 continue;
1210
1211 auto [Start, Step] = getStartAndBackedgeValue(PN, LoopPred);
1212 if (!Start)
1213 continue;
1214
1215 MonotonicInfo Info = getMonotonicityInfo(PN, Step);
1216 // Every variable in the unsigned system already has a `V >= 0` row, so a
1217 // zero start value would just duplicate it.
1218 if (match(Start, m_Zero()))
1219 Info.Unsigned = false;
1220 if (!Info.Unsigned && !Info.Signed)
1221 continue;
1222
1223 // A non-decreasing induction cannot step below its start value, and a
1224 // non-increasing one cannot step above it.
1225 Value *LHS = &PN, *RHS = Start;
1226 if (Info.Decreasing)
1227 std::swap(LHS, RHS);
1228 CmpPredicate Pred(Info.Unsigned ? CmpInst::ICMP_UGE : CmpInst::ICMP_SGE,
1229 /*HasSameSign=*/Info.Unsigned && Info.Signed);
1230 WorkList.push_back(FactOrCheck::getConditionFact(DTN, Pred, LHS, RHS));
1231 }
1232}
1233
1234void State::addInfoForInductions(BasicBlock &BB) {
1235 auto *L = LI.getLoopFor(&BB);
1236 if (!L)
1237 return;
1238
1239 BasicBlock *Header = L->getHeader();
1240 BasicBlock *Latch = L->getLoopLatch();
1241 if (Header != &BB && Latch != &BB)
1242 return;
1243
1244 // A is either a phi or a post-increment PN + C with constant step. For the
1245 // latter, extract the constant IncStep.
1246 Value *A;
1247 Value *B;
1248 PHINode *PN = nullptr;
1249 const APInt *IncStep = nullptr;
1250 CmpPredicate Pred;
1251 auto IndValue =
1252 m_Value(A, m_CombineOr(m_Phi(PN), m_IncrementOf(m_Phi(PN), IncStep)));
1253
1254 auto *Br = dyn_cast<CondBrInst>(BB.getTerminator());
1255 if (!Br)
1256 return;
1257
1258 auto CountingCmp = m_c_ICmp(Pred, IndValue, m_Value(B));
1259 std::optional<bool> PeeledOnEdge;
1260 if (!match(Br->getCondition(), CountingCmp)) {
1261 // Look through AND/OR, and remember which edge requires all operands to be
1262 // true.
1263 if (match(Br->getCondition(), m_c_LogicalAnd(CountingCmp, m_Value())))
1264 PeeledOnEdge = true;
1265 else if (match(Br->getCondition(), m_c_LogicalOr(CountingCmp, m_Value())))
1266 PeeledOnEdge = false;
1267 else
1268 return;
1269 }
1270
1271 if (PN->getParent() != Header || PN->getNumIncomingValues() != 2 ||
1272 !SE->isSCEVable(PN->getType()))
1273 return;
1274
1275 bool ContinueOnTrue =
1276 Pred == CmpInst::ICMP_NE || ICmpInst::isLT(Pred) || ICmpInst::isLE(Pred);
1277 CmpInst::Predicate ContinuePred =
1278 ContinueOnTrue ? Pred.dropSameSign() : CmpInst::getInversePredicate(Pred);
1279 BasicBlock *InLoopSucc = Br->getSuccessor(ContinueOnTrue ? 0 : 1);
1280
1281 // The peeled condition only implies the compare on the edge where the
1282 // combined condition forces its operands, which must be the in-loop edge.
1283 if (PeeledOnEdge && *PeeledOnEdge != ContinueOnTrue)
1284 return;
1285
1286 if (!L->contains(InLoopSucc) || !L->isLoopExiting(&BB))
1287 return;
1288
1289 BasicBlock *LoopPred = L->getLoopPredecessor();
1290 if (!LoopPred || !L->isLoopInvariant(B))
1291 return;
1292
1293 auto [StartValue, Backedge] = getStartAndBackedgeValue(*PN, LoopPred);
1294 DomTreeNode *DTN = DT.getNode(InLoopSucc);
1295 DomTreeNode *HeaderDTN = DT.getNode(Header);
1296
1297 // BB is the header or the latch, so every iteration taking the backedge
1298 // checked PN ContinuePred B, which guarantees PN != B for NE and LT
1299 // predicates. For an increment by one, PN != B together with StartValue <= B
1300 // (added precondition) imply PN <= B.
1301 const APInt *Step;
1302 bool HasHeaderBound =
1303 !IncStep && match(Backedge, m_IncrementOf(m_Specific(PN), Step)) &&
1304 Step->isOne() &&
1305 (ContinuePred == CmpInst::ICMP_NE || ICmpInst::isLT(ContinuePred));
1306 if (HasHeaderBound) {
1308 WorkList.push_back(FactOrCheck::getConditionFact(
1309 HeaderDTN, BoundPred, PN, B, ConditionTy(BoundPred, StartValue, B)));
1310 }
1311
1312 // For latch conditions, we need to inject the condition that holds for the
1313 // next iteration into the header. We limit to post-inc conditions, for which
1314 // an original PN + Step != B condition results in a PN < B constraint in the
1315 // header, which also holds for the next loop iteration. This would no longer
1316 // be correct if the post-inc handling would inject a more precise PN + Step <
1317 // B constraint instead.
1318 if (&BB == Latch && !IncStep)
1319 return;
1320
1321 if (ICmpInst::isRelational(ContinuePred)) {
1322 if (A != Backedge)
1323 return;
1324
1325 // The condition ensures ContinuePred holds in the header on each iteration
1326 // other than the first. Together with a precondition on the start value
1327 // (StartValue ContinuePred B), we can add B as bound of PN.
1328 WorkList.push_back(FactOrCheck::getConditionFact(
1329 HeaderDTN, ContinuePred, PN, B,
1330 ConditionTy(ContinuePred, StartValue, B)));
1331
1332 // A signed bound can be translated to the unsigned system if PN is signed
1333 // non-decreasing (StartValue s<= PN s< B) and StartValue u< B holds.
1334 // Then StartValue, PN and B must all have the same sign.
1335 if (ICmpInst::isSigned(ContinuePred)) {
1336 assert((ContinuePred == CmpInst::ICMP_SLT ||
1337 ContinuePred == CmpInst::ICMP_SLE) &&
1338 "Expected a signed less-than continuation predicate");
1339 MonotonicInfo Info = getMonotonicityInfo(*PN, Backedge);
1340 if (Info.Signed && !Info.Decreasing) {
1342 WorkList.push_back(FactOrCheck::getConditionFact(
1343 HeaderDTN, UPred, PN, B, ConditionTy(UPred, StartValue, B)));
1344 }
1345 }
1346
1347 // A relational latch steps past B rather than landing on it, so none of the
1348 // reasoning below applies.
1349 return;
1350 }
1351
1352 const APInt *StepOffset = nullptr;
1353 const SCEV *StartSCEV = nullptr;
1354 if (match(Backedge, m_c_Add(m_Specific(PN), m_APInt(StepOffset)))) {
1355 if (StepOffset->isZero())
1356 return;
1357 } else {
1358 const SCEV *Expr = SE->getSCEV(PN);
1359 if (!match(Expr,
1360 m_scev_AffineAddRec(m_SCEV(StartSCEV), m_scev_APInt(StepOffset),
1361 m_SpecificLoop(L))))
1362 return;
1363 }
1364
1365 // If we looked through `PN + C`, only derive facts when that add is
1366 // really the induction's post-increment or post-decrement.
1367 if (IncStep && *IncStep != *StepOffset)
1368 return;
1369
1370 MonotonicInfo Info = getMonotonicityInfo(*PN, Backedge);
1371
1372 // Handle negative steps.
1373 if (StepOffset->isNegative()) {
1374 // TODO: Extend to allow steps > -1.
1375 if (!(-*StepOffset).isOne())
1376 return;
1377
1378 // AR may wrap.
1379 // The loop exits once the compared value reaches B, that is at PN == B when
1380 // comparing the phi, and at PN == B + 1 for a post-decrement. Use
1381 // non-strict predicate for the former, and a strict one for the latter to
1382 // ensure the loop exits before wrapping.
1383 CmpInst::Predicate UPrecond =
1385 ConditionTy BBeforeStartUnsigned = {UPrecond, B, StartValue};
1386 ConditionTy BBeforeStartSigned = {ICmpInst::getSignedPredicate(UPrecond), B,
1387 StartValue};
1388
1389 // AR may wrap, so both facts are conditional on B being below StartValue.
1390 // Add StartValue >= PN, which holds as the loop exits before wrapping.
1391 WorkList.push_back(FactOrCheck::getConditionFact(
1392 DTN, CmpInst::ICMP_UGE, StartValue, PN, BBeforeStartUnsigned));
1393 if (!(Info.Decreasing && Info.Signed))
1394 WorkList.push_back(FactOrCheck::getConditionFact(
1395 DTN, CmpInst::ICMP_SGE, StartValue, PN, BBeforeStartSigned));
1396 // Add PN > B, which holds as the loop exits when reaching B.
1397 WorkList.push_back(FactOrCheck::getConditionFact(DTN, CmpInst::ICMP_UGT, PN,
1398 B, BBeforeStartUnsigned));
1399 WorkList.push_back(FactOrCheck::getConditionFact(DTN, CmpInst::ICMP_SGT, PN,
1400 B, BBeforeStartSigned));
1401 return;
1402 }
1403
1404 // Make sure AR either steps by 1 or that the value we compare against is a
1405 // GEP based on the same start value and all offsets are a multiple of the
1406 // step size, to guarantee that the induction will reach the value.
1407 if (StepOffset->isZero() || StepOffset->isNegative())
1408 return;
1409
1410 if (!StepOffset->isOne()) {
1411 // Check whether B-Start is known to be a multiple of StepOffset.
1412 if (!StartSCEV)
1413 StartSCEV = SE->getSCEV(StartValue);
1414 const SCEV *BMinusStart = SE->getMinusSCEV(SE->getSCEV(B), StartSCEV);
1415 if (isa<SCEVCouldNotCompute>(BMinusStart) ||
1416 !SE->getConstantMultiple(BMinusStart).urem(*StepOffset).isZero())
1417 return;
1418 }
1419
1420 // We already established that B - Start is a multiple of Step above. The loop
1421 // exits once the compared value reaches B, that is at PN == B when comparing
1422 // the phi, and at PN + Step == B for a post-increment. Together with the
1423 // added precondition StartValue <= B for the former and the strict
1424 // StartValue < B for the latter (which implies StartValue + Step <= B),
1425 // neither PN nor the increment can wrap.
1427 ConditionTy StartBeforeBoundUnsigned = {UPrecond, StartValue, B};
1428 ConditionTy StartBeforeBoundSigned = {ICmpInst::getSignedPredicate(UPrecond),
1429 StartValue, B};
1430
1431 // Add PN >= StartValue, as the loop exits before wrapping.
1432 if (!Info.Unsigned)
1433 WorkList.push_back(FactOrCheck::getConditionFact(
1434 DTN, CmpInst::ICMP_UGE, PN, StartValue, StartBeforeBoundUnsigned));
1435 if (!Info.Signed)
1436 WorkList.push_back(FactOrCheck::getConditionFact(
1437 DTN, CmpInst::ICMP_SGE, PN, StartValue, StartBeforeBoundSigned));
1438 // Add PN < B, as the loop exits once the compared value reaches B. With a
1439 // header bound, the PN != B condition fact in InLoopSucc already tightens it
1440 // to PN < B.
1441 if (!HasHeaderBound || !canAddSuccessor(BB, InLoopSucc)) {
1442 WorkList.push_back(FactOrCheck::getConditionFact(
1443 DTN, CmpInst::ICMP_SLT, PN, B, StartBeforeBoundSigned));
1444 WorkList.push_back(FactOrCheck::getConditionFact(
1445 DTN, CmpInst::ICMP_ULT, PN, B, StartBeforeBoundUnsigned));
1446 }
1447
1448 // Try to add condition from the header or latch to the dedicated exit
1449 // blocks. When exiting either with EQ or NE, we know that the induction value
1450 // must be u<= B, as other exits may only exit earlier.
1451 assert(!StepOffset->isNegative() && "induction must be increasing");
1452 assert(ContinuePred == CmpInst::ICMP_NE && "unsupported predicate");
1453 // The header bound already implies PN u<= B in the exits.
1454 if (HasHeaderBound)
1455 return;
1457 L->getExitBlocks(ExitBBs);
1458 for (BasicBlock *EB : ExitBBs) {
1459 // Bail out on non-dedicated exits.
1460 if (DT.dominates(&BB, EB)) {
1461 WorkList.emplace_back(FactOrCheck::getConditionFact(
1462 DT.getNode(EB), CmpInst::ICMP_ULE, A, B, StartBeforeBoundUnsigned));
1463 }
1464 }
1465}
1466
1468 uint64_t AccessSize,
1469 CmpPredicate &Pred, Value *&A,
1470 Value *&B, const DataLayout &DL,
1471 const TargetLibraryInfo &TLI) {
1472 if (!GEP.hasNoUnsignedWrap())
1473 return false;
1474
1475 Value *Base = GEP.getPointerOperand();
1476 if (auto *InnerGEP = dyn_cast<GetElementPtrInst>(Base))
1477 Base = InnerGEP->getPointerOperand();
1478
1479 ObjectSizeOpts Opts;
1480 // Workaround for gep inbounds, ptr null, idx.
1481 Opts.NullIsUnknownSize = true;
1482 // Be conservative since we are not clear on whether an out of bounds access
1483 // to the padding is UB or not.
1484 Opts.RoundToAlign = true;
1485 std::optional<TypeSize> Size = getBaseObjectSize(Base, DL, &TLI, Opts);
1486 if (!Size || Size->isScalable())
1487 return false;
1488
1490 if (Offset.BasePtr != Base || !Offset.NW.hasNoUnsignedWrap())
1491 return false;
1492
1493 if (Offset.VariableOffsets.size() != 1)
1494 return false;
1495
1496 uint64_t BitWidth = Offset.ConstantOffset.getBitWidth();
1497 auto &[Index, Scale] = Offset.VariableOffsets.front();
1498 // Bail out on non-canonical GEPs.
1499 if (Index->getType()->getScalarSizeInBits() != BitWidth)
1500 return false;
1501
1502 // Index * Scale + ConstOffset + AccessSize <= AllocSize
1503 // With nuw flag, we know that the index addition doesn't have unsigned wrap.
1504 // If (AllocSize - (ConstOffset + AccessSize)) wraps around, there is no valid
1505 // value for Index.
1506 APInt MaxIndex = (APInt(BitWidth, Size->getFixedValue() - AccessSize,
1507 /*isSigned=*/false, /*implicitTrunc=*/true) -
1508 Offset.ConstantOffset)
1509 .udiv(Scale);
1510 Pred = ICmpInst::ICMP_ULE;
1511 A = Index;
1512 B = ConstantInt::get(Index->getType(), MaxIndex);
1513 return true;
1514}
1515
1516/// Returns true if \p I is a candidate whose poison-generating flags may be
1517/// strengthened using the constraint systems.
1519 if (auto *Trunc = dyn_cast<TruncInst>(I))
1520 return Trunc->getType()->isIntegerTy() && Trunc->hasNoSignedWrap() &&
1521 !Trunc->hasNoUnsignedWrap();
1522
1523 auto *BO = dyn_cast<BinaryOperator>(I);
1524 if (!BO || !BO->getType()->isIntegerTy())
1525 return false;
1526
1527 switch (BO->getOpcode()) {
1528 case Instruction::Sub:
1529 if (BO->hasNoUnsignedWrap() && BO->hasNoSignedWrap())
1530 return false;
1531 // A - B does not wrap unsigned if A >=u B, and does not wrap signed if
1532 // 0 <=s B <=s A. With a constant B, bounds on A can refine both flags.
1533 return true;
1534 case Instruction::Add:
1535 case Instruction::Mul:
1536 case Instruction::Shl:
1537 if (BO->hasNoUnsignedWrap() && BO->hasNoSignedWrap())
1538 return false;
1539 // With a constant second operand, we can use bounds on the first operand to
1540 // refine no-wrap flags. Independently, nuw can be added for nsw if the
1541 // operands are non-negative.
1542 return isa<ConstantInt>(BO->getOperand(1)) || BO->hasNoSignedWrap();
1543 default:
1544 return false;
1545 }
1546}
1547
1548/// Try to strengthen \p I's poison generating flags using \p Info. Returns
1549/// true if \p I was modified.
1550static bool tryToStrengthenFlags(Instruction *I, ConstraintInfo &Info) {
1551 assert(canStrengthenFlags(I) && "not a candidate for flag strengthening");
1552
1553 bool Changed = false;
1554 if (!I->hasNoSignedWrap() && isKnownNoWrap(I, Info, /*Signed=*/true)) {
1555 LLVM_DEBUG(dbgs() << "Adding nsw to " << *I << "\n");
1556 I->setHasNoSignedWrap();
1557 Changed = true;
1558 }
1559 if (!I->hasNoUnsignedWrap() && isKnownNoWrap(I, Info, /*Signed=*/false)) {
1560 LLVM_DEBUG(dbgs() << "Adding nuw to " << *I << "\n");
1561 I->setHasNoUnsignedWrap();
1562 Changed = true;
1563 }
1564 return Changed;
1565}
1566
1567void State::addInfoFor(BasicBlock &BB) {
1568 addBoundsForHeaderInductions(BB);
1569 addInfoForInductions(BB);
1570 auto &DL = BB.getDataLayout();
1571
1572 Value *A, *B;
1573 CmpPredicate Pred;
1574 // True as long as the current instruction is guaranteed to execute.
1575 bool GuaranteedToExecute = true;
1576 // Queue conditions and assumes.
1577 for (Instruction &I : BB) {
1578 if (match(&I, m_ICmpLike(Pred, m_Value(), m_Value()))) {
1579 for (Use &U : I.uses()) {
1580 auto *UserI = getContextInstForUse(U);
1581 auto *DTN = DT.getNode(UserI->getParent());
1582 if (!DTN)
1583 continue;
1584 WorkList.push_back(FactOrCheck::getCheck(DTN, &U));
1585 }
1586 continue;
1587 }
1588
1589 auto AddFactFromMemoryAccess = [&](Value *Ptr, Type *AccessType) {
1590 auto *GEP = dyn_cast<GetElementPtrInst>(Ptr);
1591 if (!GEP)
1592 return;
1593 TypeSize AccessSize = DL.getTypeStoreSize(AccessType);
1594 if (!AccessSize.isFixed())
1595 return;
1596 if (GuaranteedToExecute) {
1598 Pred, A, B, DL, TLI)) {
1599 // The memory access is guaranteed to execute when BB is entered,
1600 // hence the constraint holds on entry to BB.
1601 WorkList.emplace_back(FactOrCheck::getConditionFact(
1602 DT.getNode(I.getParent()), Pred, A, B));
1603 }
1604 } else {
1605 WorkList.emplace_back(
1606 FactOrCheck::getInstFact(DT.getNode(I.getParent()), &I));
1607 }
1608 };
1609
1610 if (auto *LI = dyn_cast<LoadInst>(&I)) {
1611 if (!LI->isVolatile())
1612 AddFactFromMemoryAccess(LI->getPointerOperand(), LI->getAccessType());
1613 }
1614 if (auto *SI = dyn_cast<StoreInst>(&I)) {
1615 if (!SI->isVolatile())
1616 AddFactFromMemoryAccess(SI->getPointerOperand(), SI->getAccessType());
1617 }
1618
1619 auto *II = dyn_cast<IntrinsicInst>(&I);
1620 Intrinsic::ID ID = II ? II->getIntrinsicID() : Intrinsic::not_intrinsic;
1621 switch (ID) {
1622 case Intrinsic::assume: {
1623 if (!match(I.getOperand(0), m_ICmpLike(Pred, m_Value(A), m_Value(B))))
1624 break;
1625 if (GuaranteedToExecute) {
1626 // The assume is guaranteed to execute when BB is entered, hence Cond
1627 // holds on entry to BB.
1628 WorkList.emplace_back(FactOrCheck::getConditionFact(
1629 DT.getNode(I.getParent()), Pred, A, B));
1630 } else {
1631 WorkList.emplace_back(
1632 FactOrCheck::getInstFact(DT.getNode(I.getParent()), &I));
1633 }
1634 break;
1635 }
1636 // Enqueue intrinsics for simplification.
1637 case Intrinsic::uadd_with_overflow:
1638 case Intrinsic::sadd_with_overflow:
1639 case Intrinsic::usub_with_overflow:
1640 case Intrinsic::ssub_with_overflow:
1641 case Intrinsic::umul_with_overflow:
1642 case Intrinsic::smul_with_overflow:
1643 case Intrinsic::ucmp:
1644 case Intrinsic::scmp:
1645 WorkList.push_back(
1646 FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
1647 break;
1648 // Enqueue the intrinsics to add extra info.
1649 case Intrinsic::umin:
1650 case Intrinsic::umax:
1651 case Intrinsic::smin:
1652 case Intrinsic::smax:
1653 case Intrinsic::usub_sat:
1654 // TODO: handle llvm.abs as well
1655 WorkList.push_back(
1656 FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
1657 [[fallthrough]];
1658 case Intrinsic::uadd_sat:
1659 // TODO: Check if it is possible to instead only added the min/max facts
1660 // when simplifying uses of the min/max intrinsics.
1662 break;
1663 [[fallthrough]];
1664 case Intrinsic::abs:
1665 WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I));
1666 break;
1667 }
1668
1669 // Add facts from unsigned division, remainder and logical shift right, and
1670 // from signed division and remainder.
1671 // urem x, n: result < n and result <= x
1672 // udiv x, n: result <= x
1673 // lshr x, n: result <= x
1674 // srem x, n: result >= 0 and result <= x, if x >= 0
1675 // result < n, if n > 0
1676 // sdiv x, n: result >= 0 and result <= x, if x >= 0 and n > 0
1677 // result >= 0 and result < x, if x > 0 and n > 1
1678 if (auto *BO = dyn_cast<BinaryOperator>(&I)) {
1679 if ((BO->getOpcode() == Instruction::URem ||
1680 BO->getOpcode() == Instruction::UDiv ||
1681 BO->getOpcode() == Instruction::LShr ||
1682 BO->getOpcode() == Instruction::SRem ||
1683 BO->getOpcode() == Instruction::SDiv) &&
1685 WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), BO));
1686 }
1687
1688 // Queue instructions whose flags may be strengthened, checked at the
1689 // closest point dominating all uses.
1690 if (canStrengthenFlags(&I)) {
1691 Instruction *CommonDom = findCommonDominatorOfUses(I, DT);
1692 WorkList.push_back(FactOrCheck::getCheck(
1693 DT.getNode(CommonDom->getParent()), &I, CommonDom));
1694 }
1695
1696 GuaranteedToExecute &= isGuaranteedToTransferExecutionToSuccessor(&I);
1697 }
1698
1699 if (auto *Switch = dyn_cast<SwitchInst>(BB.getTerminator())) {
1700 for (auto &Case : Switch->cases()) {
1701 BasicBlock *Succ = Case.getCaseSuccessor();
1702 Value *V = Case.getCaseValue();
1703 if (!canAddSuccessor(BB, Succ))
1704 continue;
1705 WorkList.emplace_back(FactOrCheck::getConditionFact(
1706 DT.getNode(Succ), CmpInst::ICMP_EQ, Switch->getCondition(), V));
1707 }
1708 return;
1709 }
1710
1711 auto *Br = dyn_cast<CondBrInst>(BB.getTerminator());
1712 if (!Br)
1713 return;
1714
1715 Value *Cond = Br->getCondition();
1716
1717 // If the condition is a chain of ORs/AND and the successor only has the
1718 // current block as predecessor, queue conditions for the successor.
1719 Value *Op0, *Op1;
1720 if (match(Cond, m_LogicalOr(m_Value(Op0), m_Value(Op1))) ||
1721 match(Cond, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) {
1722 bool IsOr = match(Cond, m_LogicalOr());
1723 bool IsAnd = match(Cond, m_LogicalAnd());
1724 // If there's a select that matches both AND and OR, we need to commit to
1725 // one of the options. Arbitrarily pick OR.
1726 if (IsOr && IsAnd)
1727 IsAnd = false;
1728
1729 BasicBlock *Successor = Br->getSuccessor(IsOr ? 1 : 0);
1730 if (canAddSuccessor(BB, Successor)) {
1731 SmallVector<Value *> CondWorkList;
1732 SmallPtrSet<Value *, 8> SeenCond;
1733 auto QueueValue = [&CondWorkList, &SeenCond](Value *V) {
1734 if (SeenCond.insert(V).second)
1735 CondWorkList.push_back(V);
1736 };
1737 QueueValue(Op1);
1738 QueueValue(Op0);
1739 while (!CondWorkList.empty()) {
1740 Value *Cur = CondWorkList.pop_back_val();
1741 if (match(Cur, m_ICmpLike(Pred, m_Value(A), m_Value(B)))) {
1742 WorkList.emplace_back(FactOrCheck::getConditionFact(
1743 DT.getNode(Successor),
1744 IsOr ? CmpPredicate::getInverse(Pred) : Pred, A, B));
1745 continue;
1746 }
1747 if (IsOr && match(Cur, m_LogicalOr(m_Value(Op0), m_Value(Op1)))) {
1748 QueueValue(Op1);
1749 QueueValue(Op0);
1750 continue;
1751 }
1752 if (IsAnd && match(Cur, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) {
1753 QueueValue(Op1);
1754 QueueValue(Op0);
1755 continue;
1756 }
1757 }
1758 }
1759 return;
1760 }
1761
1762 if (!match(Br->getCondition(), m_ICmpLike(Pred, m_Value(A), m_Value(B))))
1763 return;
1764 if (canAddSuccessor(BB, Br->getSuccessor(0)))
1765 WorkList.emplace_back(FactOrCheck::getConditionFact(
1766 DT.getNode(Br->getSuccessor(0)), Pred, A, B));
1767 if (canAddSuccessor(BB, Br->getSuccessor(1)))
1768 WorkList.emplace_back(FactOrCheck::getConditionFact(
1769 DT.getNode(Br->getSuccessor(1)), CmpPredicate::getInverse(Pred), A, B));
1770}
1771
1772#ifndef NDEBUG
1774 Value *LHS, Value *RHS) {
1775 OS << "icmp " << Pred << ' ';
1776 LHS->printAsOperand(OS, /*PrintType=*/true);
1777 OS << ", ";
1778 RHS->printAsOperand(OS, /*PrintType=*/false);
1779}
1780#endif
1781
1782namespace {
1783/// Helper to keep track of a condition and if it should be treated as negated
1784/// for reproducer construction.
1785/// Pred == Predicate::BAD_ICMP_PREDICATE indicates that this entry is a
1786/// placeholder to keep the ReproducerCondStack in sync with DFSInStack.
1787struct ReproducerEntry {
1788 ICmpInst::Predicate Pred;
1789 Value *LHS;
1790 Value *RHS;
1791
1792 ReproducerEntry(ICmpInst::Predicate Pred, Value *LHS, Value *RHS)
1793 : Pred(Pred), LHS(LHS), RHS(RHS) {}
1794};
1795} // namespace
1796
1797/// Helper function to generate a reproducer function for simplifying \p Cond.
1798/// The reproducer function contains a series of @llvm.assume calls, one for
1799/// each condition in \p Stack. For each condition, the operand instruction are
1800/// cloned until we reach operands that have an entry in \p Value2Index. Those
1801/// will then be added as function arguments. \p DT is used to order cloned
1802/// instructions. The reproducer function will get added to \p M, if it is
1803/// non-null. Otherwise no reproducer function is generated.
1804static void generateReproducer(Instruction *Cond, bool IsSigned, Module *M,
1806 ConstraintInfo &Info, DominatorTree &DT) {
1807 if (!M)
1808 return;
1809
1810 LLVMContext &Ctx = Cond->getContext();
1811
1812 LLVM_DEBUG(dbgs() << "Creating reproducer for " << *Cond << "\n");
1813
1814 ValueToValueMapTy Old2New;
1817 // Traverse Cond and its operands recursively until we reach a value that's in
1818 // Value2Index or not an instruction, or not a operation that
1819 // ConstraintElimination can decompose. Such values will be considered as
1820 // external inputs to the reproducer, they are collected and added as function
1821 // arguments later.
1822 auto CollectArguments = [&](ArrayRef<Value *> Ops, bool IsSigned) {
1823 auto &Value2Index = Info.getValue2Index(IsSigned);
1824 SmallVector<Value *, 4> WorkList(Ops);
1825 while (!WorkList.empty()) {
1826 Value *V = WorkList.pop_back_val();
1827 if (!Seen.insert(V).second)
1828 continue;
1829 if (Old2New.find(V) != Old2New.end())
1830 continue;
1831 if (isa<Constant>(V))
1832 continue;
1833
1834 auto *I = dyn_cast<Instruction>(V);
1835 if (Value2Index.contains(V) || !I ||
1837 Old2New[V] = V;
1838 Args.push_back(V);
1839 LLVM_DEBUG(dbgs() << " found external input " << *V << "\n");
1840 } else {
1841 append_range(WorkList, I->operands());
1842 }
1843 }
1844 };
1845
1846 for (auto &Entry : Stack)
1847 if (Entry.Pred != ICmpInst::BAD_ICMP_PREDICATE)
1848 CollectArguments({Entry.LHS, Entry.RHS}, ICmpInst::isSigned(Entry.Pred));
1849 CollectArguments(Cond, IsSigned);
1850
1851 SmallVector<Type *> ParamTys;
1852 for (auto *P : Args)
1853 ParamTys.push_back(P->getType());
1854
1855 FunctionType *FTy = FunctionType::get(Cond->getType(), ParamTys,
1856 /*isVarArg=*/false);
1858 Cond->getModule()->getName() +
1859 Cond->getFunction()->getName() + "repro",
1860 M);
1861 // Add arguments to the reproducer function for each external value collected.
1862 for (unsigned I = 0; I < Args.size(); ++I) {
1863 F->getArg(I)->setName(Args[I]->getName());
1864 Old2New[Args[I]] = F->getArg(I);
1865 }
1866
1867 BasicBlock *Entry = BasicBlock::Create(Ctx, "entry", F);
1868 IRBuilder<> Builder(Entry);
1869 Builder.CreateRet(Builder.getTrue());
1870 Builder.SetInsertPoint(Entry->getTerminator());
1871
1872 // Clone instructions in \p Ops and their operands recursively until reaching
1873 // an value in Value2Index (external input to the reproducer). Update Old2New
1874 // mapping for the original and cloned instructions. Sort instructions to
1875 // clone by dominance, then insert the cloned instructions in the function.
1876 auto CloneInstructions = [&](ArrayRef<Value *> Ops, bool IsSigned) {
1877 SmallVector<Value *, 4> WorkList(Ops);
1879 auto &Value2Index = Info.getValue2Index(IsSigned);
1880 while (!WorkList.empty()) {
1881 Value *V = WorkList.pop_back_val();
1882 if (Old2New.find(V) != Old2New.end())
1883 continue;
1884
1885 auto *I = dyn_cast<Instruction>(V);
1886 if (!Value2Index.contains(V) && I) {
1887 Old2New[V] = nullptr;
1888 ToClone.push_back(I);
1889 append_range(WorkList, I->operands());
1890 }
1891 }
1892
1893 sort(ToClone,
1894 [&DT](Instruction *A, Instruction *B) { return DT.dominates(A, B); });
1895 for (Instruction *I : ToClone) {
1896 Instruction *Cloned = I->clone();
1897 Old2New[I] = Cloned;
1898 Old2New[I]->setName(I->getName());
1899 Cloned->insertBefore(Builder.GetInsertPoint());
1901 Cloned->setDebugLoc({});
1902 }
1903 };
1904
1905 // Materialize the assumptions for the reproducer using the entries in Stack.
1906 // That is, first clone the operands of the condition recursively until we
1907 // reach an external input to the reproducer and add them to the reproducer
1908 // function. Then add an ICmp for the condition (with the inverse predicate if
1909 // the entry is negated) and an assert using the ICmp.
1910 for (auto &Entry : Stack) {
1911 if (Entry.Pred == ICmpInst::BAD_ICMP_PREDICATE)
1912 continue;
1913
1914 LLVM_DEBUG(dbgs() << " Materializing assumption ";
1915 dumpUnpackedICmp(dbgs(), Entry.Pred, Entry.LHS, Entry.RHS);
1916 dbgs() << "\n");
1917 CloneInstructions({Entry.LHS, Entry.RHS}, CmpInst::isSigned(Entry.Pred));
1918
1919 auto *Cmp = Builder.CreateICmp(Entry.Pred, Entry.LHS, Entry.RHS);
1920 Builder.CreateAssumption(Cmp);
1921 }
1922
1923 // Finally, clone the condition to reproduce and remap instruction operands in
1924 // the reproducer using Old2New.
1925 CloneInstructions(Cond, IsSigned);
1926 Entry->getTerminator()->setOperand(0, Cond);
1927 remapInstructionsInBlocks({Entry}, Old2New);
1928
1929 assert(!verifyFunction(*F, &dbgs()));
1930}
1931
1932/// If \p V is a variable in the system and constraint \p C does not contain \p
1933/// V, we managed to decompose \p V at this point, but likely not earlier when
1934/// the fact involving \p V was added. In that case, return a new row for
1935/// V <= decompose(V) to link the variable with the decomposition result.
1936static RowTy getDecompositionLinkRow(Value *V, const ConstraintTy &C,
1937 ConstraintInfo &Info,
1938 const DataLayout &DL) {
1939 const auto &Value2Index = Info.getValue2Index(C.IsSigned);
1940 auto It = Value2Index.find(V);
1941 if (It == Value2Index.end() ||
1942 any_of(C.Coefficients,
1943 [Id = It->second](const Entry &E) { return E.Id == Id; }))
1944 return {};
1945
1946 SmallVector<Value *> NewVariables;
1947 RowTy Row =
1948 getRowForLessEqual(Decomposition(V), decompose(V, Info, C.IsSigned, DL),
1949 Value2Index, NewVariables);
1950 return NewVariables.empty() ? Row : RowTy();
1951}
1952
1953static std::optional<bool> checkCondition(CmpInst::Predicate Pred, Value *A,
1954 Value *B, Instruction *CheckInst,
1955 ConstraintInfo &Info) {
1956 LLVM_DEBUG(dbgs() << "Checking " << *CheckInst << "\n");
1957
1958 auto TryWithConstraint = [&](const ConstraintTy &R) -> std::optional<bool> {
1959 if (R.empty()) {
1960 LLVM_DEBUG(dbgs() << " failed to decompose condition\n");
1961 return std::nullopt;
1962 }
1963
1964 auto &CSToUse = Info.getCS(R.IsSigned);
1965 if (auto ImpliedCondition = R.isImpliedBy(CSToUse)) {
1966 if (!DebugCounter::shouldExecute(EliminatedCounter))
1967 return std::nullopt;
1968 LLVM_DEBUG({
1969 dbgs() << "Condition ";
1971 *ImpliedCondition ? Pred
1973 A, B);
1974 dbgs() << " implied by dominating constraints\n";
1975 CSToUse.dump();
1976 });
1977 return ImpliedCondition;
1978 }
1979 return std::nullopt;
1980 };
1981
1982 // Retry the query after adding additional facts for A == decompose(A) and B
1983 // == decompose(B), if needed.
1984 auto TryWithLinkedDecomposition =
1985 [&](const ConstraintTy &C) -> std::optional<bool> {
1986 if (C.empty())
1987 return std::nullopt;
1988
1989 auto &CS = Info.getCS(C.IsSigned);
1990 unsigned NumVars = Info.getValue2Index(C.IsSigned).size();
1991 unsigned NumPushed = 0;
1992 for (Value *V : {A, B}) {
1993 RowTy Row =
1994 getDecompositionLinkRow(V, C, Info, CheckInst->getDataLayout());
1995 RowTy Negated = ConstraintSystem::negateOrEqual(Row);
1996 if (Row.empty() || Negated.empty())
1997 continue;
1998 NumPushed += CS.addRow(Row, NumVars);
1999 NumPushed += CS.addRow(Negated, NumVars);
2000 }
2001 if (NumPushed == 0)
2002 return std::nullopt;
2003
2004 std::optional<bool> Res = TryWithConstraint(C);
2005 while (NumPushed--)
2006 CS.popLastConstraint();
2007 return Res;
2008 };
2009
2010 auto R = Info.getConstraintForSolving(Pred, A, B);
2011 if (auto ImpliedCondition = TryWithConstraint(R))
2012 return ImpliedCondition;
2013 if (auto ImpliedCondition = TryWithLinkedDecomposition(R))
2014 return ImpliedCondition;
2015
2016 // For non-negative operands unsigned queries can also be checked against the
2017 // signed system.
2018 if (CmpInst::isUnsigned(Pred) && A->getType()->isIntegerTy()) {
2019 SmallVector<Value *> NewVariables;
2020 auto SR = Info.getConstraint(ICmpInst::getSignedPredicate(Pred), A, B,
2021 NewVariables);
2022 if (NewVariables.empty() && !SR.empty() && Info.isKnownNonNegative(A) &&
2023 Info.isKnownNonNegative(B))
2024 if (auto ImpliedCondition = TryWithConstraint(SR))
2025 return ImpliedCondition;
2026 }
2027
2028 // Additionally, query the signed system for eq/ne predicates if we know about
2029 // A or B.
2030 if (CmpInst::isEquality(Pred)) {
2031 const auto &Value2Index = Info.getValue2Index(/*Signed=*/true);
2032 if (!Value2Index.contains(A) && !Value2Index.contains(B))
2033 return std::nullopt;
2034
2035 SmallVector<Value *> NewVariables;
2036 auto SR = Info.getConstraint(Pred, A, B, NewVariables,
2037 /*ForceSignedSystem=*/true);
2038 if (NewVariables.empty()) {
2039 if (auto ImpliedCondition = TryWithConstraint(SR))
2040 return ImpliedCondition;
2041 if (auto ImpliedCondition = TryWithLinkedDecomposition(SR))
2042 return ImpliedCondition;
2043 }
2044 }
2045 return std::nullopt;
2046}
2047
2049 CmpPredicate Pred, Value *A, Value *B, Instruction *CheckInst,
2050 ConstraintInfo &Info, unsigned NumIn, unsigned NumOut,
2051 Instruction *ContextInst, Module *ReproducerModule,
2052 ArrayRef<ReproducerEntry> ReproducerCondStack, DominatorTree &DT,
2054 auto ReplaceCmpWithConstant = [&](Instruction *CheckInst, bool IsTrue) {
2055 generateReproducer(CheckInst, ICmpInst::isSigned(Pred), ReproducerModule,
2056 ReproducerCondStack, Info, DT);
2057 Constant *ConstantC = ConstantInt::getBool(
2058 CmpInst::makeCmpResultType(CheckInst->getType()), IsTrue);
2059 bool Changed = CheckInst->replaceUsesWithIf(ConstantC, [&](Use &U) {
2060 auto *UserI = getContextInstForUse(U);
2061 auto *DTN = DT.getNode(UserI->getParent());
2062 if (!DTN || DTN->getDFSNumIn() < NumIn || DTN->getDFSNumOut() > NumOut)
2063 return false;
2064 if (UserI->getParent() == ContextInst->getParent() &&
2065 UserI->comesBefore(ContextInst))
2066 return false;
2067
2068 // Conditions in an assume trivially simplify to true. Skip uses
2069 // in assume calls to not destroy the available information.
2070 auto *II = dyn_cast<IntrinsicInst>(U.getUser());
2071 return !II || II->getIntrinsicID() != Intrinsic::assume;
2072 });
2073 NumCondsRemoved++;
2074
2075 // Update the debug value records that satisfy the same condition used
2076 // in replaceUsesWithIf.
2078 findDbgUsers(CheckInst, DVRUsers);
2079
2080 for (auto *DVR : DVRUsers) {
2081 auto *DTN = DT.getNode(DVR->getParent());
2082 if (!DTN || DTN->getDFSNumIn() < NumIn || DTN->getDFSNumOut() > NumOut)
2083 continue;
2084
2085 auto *MarkedI = DVR->getInstruction();
2086 if (MarkedI->getParent() == ContextInst->getParent() &&
2087 MarkedI->comesBefore(ContextInst))
2088 continue;
2089
2090 DVR->replaceVariableLocationOp(CheckInst, ConstantC);
2091 }
2092
2093 if (CheckInst->use_empty())
2094 ToRemove.push_back(CheckInst);
2095
2096 return Changed;
2097 };
2098
2099 if (auto ImpliedCondition = checkCondition(Pred, A, B, CheckInst, Info))
2100 return ReplaceCmpWithConstant(CheckInst, *ImpliedCondition);
2101
2102 // When the predicate is samesign and unsigned, we can also make use of the
2103 // signed predicate information.
2104 if (Pred.hasSameSign() && ICmpInst::isUnsigned(Pred))
2105 if (auto ImpliedCondition = checkCondition(
2106 ICmpInst::getSignedPredicate(Pred), A, B, CheckInst, Info))
2107 return ReplaceCmpWithConstant(CheckInst, *ImpliedCondition);
2108
2109 return false;
2110}
2111
2112static bool checkAndReplaceMinMax(MinMaxIntrinsic *MinMax, ConstraintInfo &Info,
2114 auto ReplaceMinMaxWithOperand = [&](MinMaxIntrinsic *MinMax, bool UseLHS) {
2115 // TODO: generate reproducer for min/max.
2116 MinMax->replaceAllUsesWith(MinMax->getOperand(UseLHS ? 0 : 1));
2117 ToRemove.push_back(MinMax);
2118 return true;
2119 };
2120
2121 ICmpInst::Predicate Pred =
2122 ICmpInst::getNonStrictPredicate(MinMax->getPredicate());
2123 if (auto ImpliedCondition = checkCondition(
2124 Pred, MinMax->getOperand(0), MinMax->getOperand(1), MinMax, Info))
2125 return ReplaceMinMaxWithOperand(MinMax, *ImpliedCondition);
2126 if (auto ImpliedCondition = checkCondition(
2127 Pred, MinMax->getOperand(1), MinMax->getOperand(0), MinMax, Info))
2128 return ReplaceMinMaxWithOperand(MinMax, !*ImpliedCondition);
2129 return false;
2130}
2131
2132static bool checkAndReplaceCmp(CmpIntrinsic *I, ConstraintInfo &Info,
2134 Value *LHS = I->getOperand(0);
2135 Value *RHS = I->getOperand(1);
2136 if (checkCondition(I->getGTPredicate(), LHS, RHS, I, Info).value_or(false)) {
2137 I->replaceAllUsesWith(ConstantInt::get(I->getType(), 1));
2138 ToRemove.push_back(I);
2139 return true;
2140 }
2141 if (checkCondition(I->getLTPredicate(), LHS, RHS, I, Info).value_or(false)) {
2142 I->replaceAllUsesWith(ConstantInt::getSigned(I->getType(), -1));
2143 ToRemove.push_back(I);
2144 return true;
2145 }
2146 if (checkCondition(ICmpInst::ICMP_EQ, LHS, RHS, I, Info).value_or(false)) {
2147 I->replaceAllUsesWith(ConstantInt::get(I->getType(), 0));
2148 ToRemove.push_back(I);
2149 return true;
2150 }
2151 return false;
2152}
2153
2154/// Try to replace \p USub by a plain subtract, if \p Info proves it cannot
2155/// saturate. Returns true if \p USub was replaced.
2156static bool checkAndReplaceUSubSat(SaturatingInst *USub, ConstraintInfo &Info,
2158 // usub.sat(A, B) is A - B exactly when A >=u B.
2159 Value *A = USub->getLHS();
2160 Value *B = USub->getRHS();
2161 if (!checkCondition(CmpInst::ICMP_UGE, A, B, USub, Info).value_or(false))
2162 return false;
2163
2164 IRBuilder<> Builder(USub);
2165 Value *Sub = Builder.CreateSub(A, B, "", /*HasNUW=*/true,
2166 /*HasNSW=*/Info.isKnownNonNegative(A));
2167 USub->replaceAllUsesWith(Sub);
2168 Sub->takeName(USub);
2169 ToRemove.push_back(USub);
2170 return true;
2171}
2172
2173static void
2174removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info,
2175 Module *ReproducerModule,
2176 SmallVectorImpl<ReproducerEntry> &ReproducerCondStack,
2177 SmallVectorImpl<StackEntry> &DFSInStack) {
2178 Info.getDecomposeCache().clear();
2179 Info.popLastConstraint(E.IsSigned);
2180 // Remove variables in the system that went out of scope.
2181 auto &Mapping = Info.getValue2Index(E.IsSigned);
2182 for (Value *V : E.ValuesToRelease)
2183 Mapping.erase(V);
2184 Info.popLastNVariables(E.IsSigned, E.ValuesToRelease.size());
2185 DFSInStack.pop_back();
2186 if (ReproducerModule)
2187 ReproducerCondStack.pop_back();
2188}
2189
2190/// Check if either the first condition of an AND or OR is implied by the
2191/// (negated in case of OR) second condition or vice versa.
2193 FactOrCheck &CB, ConstraintInfo &Info, Module *ReproducerModule,
2194 SmallVectorImpl<ReproducerEntry> &ReproducerCondStack,
2195 SmallVectorImpl<StackEntry> &DFSInStack,
2197 Instruction *JoinOp = CB.getContextInst();
2198 if (JoinOp->use_empty())
2199 return false;
2200
2201 Instruction *CmpToCheck = cast<Instruction>(CB.getInstructionToSimplify());
2202 unsigned OtherOpIdx = JoinOp->getOperand(0) == CmpToCheck ? 1 : 0;
2203
2204 // Don't try to simplify the first condition of a select by the second, as
2205 // this may make the select more poisonous than the original one.
2206 // TODO: check if the first operand may be poison.
2207 if (OtherOpIdx != 0 && isa<SelectInst>(JoinOp))
2208 return false;
2209
2210 unsigned OldSize = DFSInStack.size();
2211 llvm::scope_exit InfoRestorer([&]() {
2212 // Remove entries again.
2213 while (OldSize < DFSInStack.size()) {
2214 StackEntry E = DFSInStack.back();
2215 removeEntryFromStack(E, Info, ReproducerModule, ReproducerCondStack,
2216 DFSInStack);
2217 }
2218 });
2219 bool IsOr = match(JoinOp, m_LogicalOr());
2220 SmallVector<Value *, 4> Worklist({JoinOp->getOperand(OtherOpIdx)});
2221 // Do a traversal of the AND/OR tree to add facts from leaf compares.
2222 while (!Worklist.empty()) {
2223 Value *Val = Worklist.pop_back_val();
2224 Value *LHS, *RHS;
2225 CmpPredicate Pred;
2226 if (match(Val, m_ICmpLike(Pred, m_Value(LHS), m_Value(RHS)))) {
2227 // For OR, check if the negated condition implies CmpToCheck.
2228 if (IsOr)
2229 Pred = CmpInst::getInversePredicate(Pred);
2230 // Optimistically add fact from the other compares in the AND/OR.
2231 Info.addFact(Pred, LHS, RHS, CB.NumIn, CB.NumOut, DFSInStack);
2232 continue;
2233 }
2234 if (IsOr ? match(Val, m_LogicalOr(m_Value(LHS), m_Value(RHS)))
2235 : match(Val, m_LogicalAnd(m_Value(LHS), m_Value(RHS)))) {
2236 Worklist.push_back(LHS);
2237 Worklist.push_back(RHS);
2238 }
2239 }
2240 if (OldSize == DFSInStack.size())
2241 return false;
2242
2243 Value *A, *B;
2244 CmpPredicate Pred;
2245 [[maybe_unused]] bool Matched =
2246 match(CmpToCheck, m_ICmpLike(Pred, m_Value(A), m_Value(B)));
2247 assert(Matched && "expected icmp-like match");
2248 // Check if the second condition can be simplified now.
2249 if (auto ImpliedCondition = checkCondition(Pred, A, B, CmpToCheck, Info)) {
2250 if (IsOr == *ImpliedCondition)
2251 JoinOp->replaceAllUsesWith(
2252 ConstantInt::getBool(JoinOp->getType(), *ImpliedCondition));
2253 else
2254 JoinOp->replaceAllUsesWith(JoinOp->getOperand(OtherOpIdx));
2255 ToRemove.push_back(JoinOp);
2256 return true;
2257 }
2258
2259 return false;
2260}
2261
2262void ConstraintInfo::addFact(CmpInst::Predicate Pred, Value *A, Value *B,
2263 unsigned NumIn, unsigned NumOut,
2264 SmallVectorImpl<StackEntry> &DFSInStack) {
2265 addFactImpl(Pred, A, B, NumIn, NumOut, DFSInStack, false);
2266 // If the Pred is eq/ne, also add the fact to signed system.
2267 if (CmpInst::isEquality(Pred))
2268 addFactImpl(Pred, A, B, NumIn, NumOut, DFSInStack, true);
2269 if (Pred == CmpInst::ICMP_NE)
2270 tightenBoundUsingNe(A, B, NumIn, NumOut, DFSInStack);
2271}
2272
2273void ConstraintInfo::tightenBoundUsingNe(
2274 Value *A, Value *B, unsigned NumIn, unsigned NumOut,
2275 SmallVectorImpl<StackEntry> &DFSInStack) {
2276 if (!A->getType()->isIntOrPtrTy())
2277 return;
2278
2279 for (bool IsSigned : {false, true}) {
2280 // In the unsigned system `A u>= 0` holds for every A, so getConstraint
2281 // already turned `A != 0` into `A u> 0`.
2282 if (!IsSigned && match(B, m_Zero()))
2283 continue;
2284
2285 // Skip if there are any unknown variables.
2286 const auto &Value2Index = getValue2Index(IsSigned);
2287 if (any_of(decompose(A, *this, IsSigned, DL).Vars,
2288 [&Value2Index](const DecompEntry &E) {
2289 return !Value2Index.contains(E.Variable);
2290 }))
2291 continue;
2292
2293 // If the system implies `A >= B` then together with `A != B` we get the
2294 // strict `A > B`; symmetrically `A <= B` becomes `A < B`.
2295 CmpInst::Predicate GEPred =
2297 CmpInst::Predicate LEPred =
2299 for (CmpInst::Predicate NonStrict : {GEPred, LEPred}) {
2300 if (!doesHold(NonStrict, A, B))
2301 continue;
2303 LLVM_DEBUG(dbgs() << "Tightening '";
2304 dumpUnpackedICmp(dbgs(), NonStrict, A, B); dbgs() << "' to '";
2306 dbgs() << "' using inequality\n");
2307 addFactImpl(Strict, A, B, NumIn, NumOut, DFSInStack,
2308 /*ForceSignedSystem=*/false);
2309 break;
2310 }
2311 }
2312}
2313
2314void ConstraintInfo::addFactImpl(CmpInst::Predicate Pred, Value *A, Value *B,
2315 unsigned NumIn, unsigned NumOut,
2316 SmallVectorImpl<StackEntry> &DFSInStack,
2317 bool ForceSignedSystem) {
2318 SmallVector<Value *> NewVariables;
2319 auto R = getConstraint(Pred, A, B, NewVariables, ForceSignedSystem);
2320
2321 // TODO: Support non-equality for facts as well.
2322 if (R.empty() || R.isNe())
2323 return;
2324
2325 auto &CSToUse = getCS(R.IsSigned);
2326 // A row implied by a single existing row adds no information. Rows in the
2327 // system are removed in reverse order, so the existing row outlives R. Rows
2328 // in the system are normalized, so normalize R before comparing.
2329 if (!R.isEq() && NewVariables.empty()) {
2330 ConstraintSystem::normalizeByGCD(R.Coefficients);
2331 if (CSToUse.isImpliedBySingleRow(R.Coefficients))
2332 return;
2333 }
2334 LLVM_DEBUG(dbgs() << "Adding '"; dumpUnpackedICmp(dbgs(), Pred, A, B);
2335 dbgs() << "'\n");
2336 bool Added = CSToUse.addRow(R.Coefficients, R.NumVars);
2337 if (!Added)
2338 return;
2339
2340 DecomposeCache.clear();
2341
2342 // If R has been added to the system, add the new variables and queue it for
2343 // removal once it goes out-of-scope.
2344 SmallVector<Value *, 2> ValuesToRelease;
2345 auto &Value2Index = getValue2Index(R.IsSigned);
2346 for (Value *V : NewVariables) {
2347 Value2Index.try_emplace(V, Value2Index.size() + 1);
2348 ValuesToRelease.push_back(V);
2349 }
2350
2351 LLVM_DEBUG({
2352 dbgs() << " constraint: ";
2353 dumpConstraint(R.Coefficients, getValue2Index(R.IsSigned));
2354 dbgs() << "\n";
2355 });
2356
2357 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
2358 std::move(ValuesToRelease));
2359
2360 if (!R.IsSigned) {
2361 for (Value *V : NewVariables) {
2362 // Add V > -1 constraints for all new variables.
2363 CSToUse.addRow({Entry(0, 0), Entry(-1, Value2Index.at(V))},
2364 Value2Index.size());
2365 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
2366 SmallVector<Value *, 2>());
2367 }
2368 }
2369
2370 if (R.isEq()) {
2371 // Also add the inverted constraint for equality constraints.
2372 for (Entry &E : R.Coefficients)
2373 if (MulOverflow(E.Coefficient, int64_t(-1), E.Coefficient))
2374 return;
2375 CSToUse.addRow(R.Coefficients, R.NumVars);
2376
2377 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
2378 SmallVector<Value *, 2>());
2379 }
2380}
2381
2382/// Replace the uses of \p II, which is known not to overflow, by the
2383/// corresponding plain binary operation and a false overflow flag.
2386 bool Changed = false;
2387 IRBuilder<> Builder(II->getIterator());
2388 Value *Res = nullptr;
2389 for (User *U : make_early_inc_range(II->users())) {
2390 if (match(U, m_ExtractValue<0>(m_Value()))) {
2391 if (!Res)
2392 Res = Builder.CreateNoWrapBinOp(II->getBinaryOp(), II->getLHS(),
2393 II->getRHS(),
2394 /*IsNUW=*/!II->isSigned(),
2395 /*IsNSW=*/II->isSigned());
2396 U->replaceAllUsesWith(Res);
2397 Changed = true;
2398 } else if (match(U, m_ExtractValue<1>(m_Value()))) {
2399 U->replaceAllUsesWith(Builder.getFalse());
2400 Changed = true;
2401 } else
2402 continue;
2403
2404 if (U->use_empty()) {
2405 auto *I = cast<Instruction>(U);
2406 ToRemove.push_back(I);
2407 I->setOperand(0, PoisonValue::get(II->getType()));
2408 Changed = true;
2409 }
2410 }
2411
2412 if (II->use_empty()) {
2413 // Do not erase II here: the worklist may still hold Uses of II's operands.
2414 for (Use &Arg : II->args())
2415 Arg.set(PoisonValue::get(Arg->getType()));
2416 ToRemove.push_back(II);
2417 Changed = true;
2418 }
2419 return Changed;
2420}
2421
2422static bool
2425 if (!isKnownNoWrap(II, Info, II->isSigned()))
2426 return false;
2428}
2429
2431 ScalarEvolution *SE,
2433 TargetLibraryInfo &TLI) {
2434 const ScalarOptions &Opts = getScalarOptions(F);
2435 bool Changed = false;
2436 DT.updateDFSNumbers();
2437 SmallVector<Value *> FunctionArgs(llvm::make_pointer_range(F.args()));
2438 ConstraintInfo Info(F.getDataLayout(), FunctionArgs);
2439 State S(DT, LI, SE, TLI);
2440 std::unique_ptr<Module> ReproducerModule(
2441 Opts.constraint_elimination_dump_reproducers
2442 ? new Module(F.getName(), F.getContext())
2443 : nullptr);
2444
2445 // First, collect conditions implied by branches and blocks with their
2446 // Dominator DFS in and out numbers.
2447 for (BasicBlock &BB : F) {
2448 if (!DT.getNode(&BB))
2449 continue;
2450 S.addInfoFor(BB);
2451 }
2452
2453 // Next, sort worklist by dominance, so that dominating conditions to check
2454 // and facts come before conditions and facts dominated by them. If a
2455 // condition to check and a fact have the same numbers, conditional facts come
2456 // first. Assume facts and checks are ordered according to their relative
2457 // order in the containing basic block. Also make sure conditions with
2458 // constant operands come before conditions without constant operands. This
2459 // increases the effectiveness of the current signed <-> unsigned fact
2460 // transfer logic.
2461 stable_sort(S.WorkList, [](const FactOrCheck &A, const FactOrCheck &B) {
2462 auto HasNoConstOp = [](const FactOrCheck &B) {
2463 Value *V0 = B.isConditionFact() ? B.Cond.Op0 : B.Inst->getOperand(0);
2464 Value *V1 = B.isConditionFact() ? B.Cond.Op1 : B.Inst->getOperand(1);
2465 return !isa<ConstantInt>(V0) && !isa<ConstantInt>(V1);
2466 };
2467 // If both entries have the same In numbers, conditional facts come first.
2468 // Otherwise use the relative order in the basic block.
2469 if (A.NumIn == B.NumIn) {
2470 if (A.isConditionFact() && B.isConditionFact()) {
2471 bool NoConstOpA = HasNoConstOp(A);
2472 bool NoConstOpB = HasNoConstOp(B);
2473 return NoConstOpA < NoConstOpB;
2474 }
2475 if (A.isConditionFact())
2476 return true;
2477 if (B.isConditionFact())
2478 return false;
2479 auto *InstA = A.getContextInst();
2480 auto *InstB = B.getContextInst();
2481 return InstA->comesBefore(InstB);
2482 }
2483 return A.NumIn < B.NumIn;
2484 });
2485
2486 SmallVector<Instruction *> ToRemove;
2487
2488 // Finally, process ordered worklist and eliminate implied conditions.
2489 SmallVector<StackEntry, 16> DFSInStack;
2490 SmallVector<ReproducerEntry> ReproducerCondStack;
2491 for (FactOrCheck &CB : S.WorkList) {
2492 // First, pop entries from the stack that are out-of-scope for CB. Remove
2493 // the corresponding entry from the constraint system.
2494 while (!DFSInStack.empty()) {
2495 auto &E = DFSInStack.back();
2496 LLVM_DEBUG(dbgs() << "Top of stack : " << E.NumIn << " " << E.NumOut
2497 << "\n");
2498 LLVM_DEBUG(dbgs() << "CB: " << CB.NumIn << " " << CB.NumOut << "\n");
2499 assert(E.NumIn <= CB.NumIn);
2500 if (CB.NumOut <= E.NumOut)
2501 break;
2502 LLVM_DEBUG({
2503 dbgs() << "Removing ";
2504 dumpConstraint(Info.getCS(E.IsSigned).getLastConstraint(),
2505 Info.getValue2Index(E.IsSigned));
2506 dbgs() << "\n";
2507 });
2508 removeEntryFromStack(E, Info, ReproducerModule.get(), ReproducerCondStack,
2509 DFSInStack);
2510 }
2511
2512 CmpPredicate Pred;
2513 Value *A, *B;
2514 // For a block, check if any CmpInsts become known based on the current set
2515 // of constraints.
2516 if (CB.isCheck()) {
2517 Instruction *Inst = CB.getInstructionToSimplify();
2518 if (!Inst)
2519 continue;
2520 if (canStrengthenFlags(Inst)) {
2521 Changed |= tryToStrengthenFlags(Inst, Info);
2522 continue;
2523 }
2524 LLVM_DEBUG(dbgs() << "Processing condition to simplify: " << *Inst
2525 << "\n");
2526 if (auto *II = dyn_cast<WithOverflowInst>(Inst)) {
2528 } else if (match(Inst, m_ICmpLike(Pred, m_Value(A), m_Value(B)))) {
2530 Pred, A, B, Inst, Info, CB.NumIn, CB.NumOut, CB.getContextInst(),
2531 ReproducerModule.get(), ReproducerCondStack, S.DT, ToRemove);
2532 if (!Simplified &&
2533 match(CB.getContextInst(), m_LogicalOp(m_Value(), m_Value()))) {
2535 CB, Info, ReproducerModule.get(), ReproducerCondStack, DFSInStack,
2536 ToRemove);
2537 }
2539 } else if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(Inst)) {
2540 Changed |= checkAndReplaceMinMax(MinMax, Info, ToRemove);
2541 } else if (auto *CmpIntr = dyn_cast<CmpIntrinsic>(Inst)) {
2542 Changed |= checkAndReplaceCmp(CmpIntr, Info, ToRemove);
2543 } else if (match(Inst, m_Intrinsic<Intrinsic::usub_sat>())) {
2544 Changed |=
2546 }
2547 continue;
2548 }
2549
2550 auto AddFact = [&](CmpPredicate Pred, Value *A, Value *B) {
2551 LLVM_DEBUG(dbgs() << "Processing fact to add to the system: ";
2552 dumpUnpackedICmp(dbgs(), Pred, A, B); dbgs() << "\n");
2553 if (Info.getCS(CmpInst::isSigned(Pred)).size() >
2554 Opts.constraint_elimination_max_rows) {
2555 LLVM_DEBUG(
2556 dbgs()
2557 << "Skip adding constraint because system has too many rows.\n");
2558 return;
2559 }
2560
2561 Info.addFact(Pred, A, B, CB.NumIn, CB.NumOut, DFSInStack);
2562 if (ReproducerModule && DFSInStack.size() > ReproducerCondStack.size())
2563 ReproducerCondStack.emplace_back(Pred, A, B);
2564
2565 if (ICmpInst::isRelational(Pred)) {
2566 // If samesign is present on the ICmp, simply flip the sign of the
2567 // predicate, transferring the information from the signed system to the
2568 // unsigned system, and viceversa.
2569 if (Pred.hasSameSign())
2571 CB.NumIn, CB.NumOut, DFSInStack);
2572 else
2573 Info.transferToOtherSystem(Pred, A, B, CB.NumIn, CB.NumOut,
2574 DFSInStack);
2575 }
2576
2577 // (X | Y) >s -1 implies X >s -1 and Y >s -1, because the sign bit of an
2578 // OR is the OR of the operand sign bits. Similarly, (X & Y) <s 0 implies
2579 // X <s 0 and Y <s 0. Look through these canonical forms produced by
2580 // InstCombine so the sign facts on the operands are available to the
2581 // solver.
2582 if ((Pred == CmpInst::ICMP_SGT && match(B, m_AllOnes())) ||
2583 (Pred == CmpInst::ICMP_SLT && match(B, m_Zero()))) {
2584 unsigned Opc =
2585 Pred == CmpInst::ICMP_SGT ? Instruction::Or : Instruction::And;
2586 SmallVector<Value *> Worklist = {A};
2587 SmallPtrSet<Value *, 4> Seen;
2588 while (!Worklist.empty()) {
2589 Value *Cur = Worklist.pop_back_val();
2590 auto *BO = dyn_cast<BinaryOperator>(Cur);
2591 if (!BO || BO->getOpcode() != Opc)
2592 continue;
2593 for (Value *Op : {BO->getOperand(0), BO->getOperand(1)}) {
2594 if (!Seen.insert(Op).second)
2595 continue;
2596 Worklist.push_back(Op);
2597 Info.addFact(Pred, Op, B, CB.NumIn, CB.NumOut, DFSInStack);
2598 }
2599 }
2600 }
2601
2602 if (ReproducerModule && DFSInStack.size() > ReproducerCondStack.size()) {
2603 // Add dummy entries to ReproducerCondStack to keep it in sync with
2604 // DFSInStack.
2605 for (unsigned I = 0,
2606 E = (DFSInStack.size() - ReproducerCondStack.size());
2607 I < E; ++I) {
2608 ReproducerCondStack.emplace_back(ICmpInst::BAD_ICMP_PREDICATE,
2609 nullptr, nullptr);
2610 }
2611 }
2612 };
2613
2614 if (!CB.isConditionFact()) {
2615 Value *X;
2616 if (match(CB.Inst, m_Intrinsic<Intrinsic::abs>(m_Value(X)))) {
2617 // If is_int_min_poison is true then we may assume llvm.abs >= 0.
2618 if (cast<ConstantInt>(CB.Inst->getOperand(1))->isOne())
2619 AddFact(CmpInst::ICMP_SGE, CB.Inst,
2620 ConstantInt::get(CB.Inst->getType(), 0));
2621 AddFact(CmpInst::ICMP_SGE, CB.Inst, X);
2622 continue;
2623 }
2624
2625 if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(CB.Inst)) {
2626 Pred = ICmpInst::getNonStrictPredicate(MinMax->getPredicate());
2627 AddFact(Pred, MinMax, MinMax->getLHS());
2628 AddFact(Pred, MinMax, MinMax->getRHS());
2629 continue;
2630 }
2631 if (auto *USatI = dyn_cast<SaturatingInst>(CB.Inst)) {
2632 switch (USatI->getIntrinsicID()) {
2633 default:
2634 llvm_unreachable("Unexpected intrinsic.");
2635 case Intrinsic::uadd_sat:
2636 AddFact(ICmpInst::ICMP_UGE, USatI, USatI->getLHS());
2637 AddFact(ICmpInst::ICMP_UGE, USatI, USatI->getRHS());
2638 break;
2639 case Intrinsic::usub_sat:
2640 AddFact(ICmpInst::ICMP_ULE, USatI, USatI->getLHS());
2641 break;
2642 }
2643 continue;
2644 }
2645
2646 if (auto *BO = dyn_cast<BinaryOperator>(CB.Inst)) {
2647 if (BO->getOpcode() == Instruction::URem) {
2648 // urem x, n: result < n (remainder is always less than divisor)
2649 AddFact(CmpInst::ICMP_ULT, BO, BO->getOperand(1));
2650 // urem x, n: result <= x (remainder is at most the dividend)
2651 AddFact(CmpInst::ICMP_ULE, BO, BO->getOperand(0));
2652 continue;
2653 }
2654 if (BO->getOpcode() == Instruction::UDiv) {
2655 // udiv x, n: result <= x (quotient is at most the dividend)
2656 AddFact(CmpInst::ICMP_ULE, BO, BO->getOperand(0));
2657 continue;
2658 }
2659 if (BO->getOpcode() == Instruction::LShr) {
2660 // lshr x, n: result <= x (right shift cannot increase the value)
2661 AddFact(CmpInst::ICMP_ULE, BO, BO->getOperand(0));
2662 continue;
2663 }
2664 if (BO->getOpcode() == Instruction::SRem) {
2665 Value *X = BO->getOperand(0);
2666 Value *N = BO->getOperand(1);
2667 Constant *Zero = Constant::getNullValue(BO->getType());
2668 if (Info.doesHold(CmpInst::ICMP_SGE, X, Zero) ||
2669 isKnownNonNegative(X, F.getDataLayout())) {
2670 // srem x, n: result >= 0, if x >= 0 (result has the sign of x)
2671 AddFact(CmpInst::ICMP_SGE, BO, Zero);
2672 // srem x, n: result <= x, if x >= 0 (|result| <= |x| and both are
2673 // non-negative)
2674 AddFact(CmpInst::ICMP_SLE, BO, X);
2675 }
2676 if (Info.doesHold(CmpInst::ICMP_SGE, N, Zero) ||
2677 isKnownPositive(N, F.getDataLayout())) {
2678 // srem x, n: result <= n, if n >= 0 (|result| < n, so result <= n -
2679 // 1
2680 AddFact(CmpInst::ICMP_SLT, BO, N);
2681 }
2682 continue;
2683 }
2684 if (BO->getOpcode() == Instruction::SDiv) {
2685 Value *X = BO->getOperand(0);
2686 Value *N = BO->getOperand(1);
2687 if (!Info.isKnownNonNegative(X) || !Info.isKnownPositive(N))
2688 continue;
2689
2690 bool IsStrict = Info.isKnownPositive(X) &&
2691 Info.doesHold(CmpInst::ICMP_SGT, N,
2692 ConstantInt::get(N->getType(), 1));
2693 AddFact(CmpInst::ICMP_SGE, BO, Constant::getNullValue(BO->getType()));
2694 AddFact(IsStrict ? CmpInst::ICMP_SLT : CmpInst::ICMP_SLE, BO, X);
2695 continue;
2696 }
2697 }
2698
2699 auto &DL = F.getDataLayout();
2700 auto AddFactsAboutIndices = [&](Value *Ptr, Type *AccessType) {
2701 CmpPredicate Pred;
2702 Value *A, *B;
2705 DL.getTypeStoreSize(AccessType).getFixedValue(), Pred, A, B, DL,
2706 TLI))
2707 AddFact(Pred, A, B);
2708 };
2709
2710 if (auto *LI = dyn_cast<LoadInst>(CB.Inst)) {
2711 AddFactsAboutIndices(LI->getPointerOperand(), LI->getAccessType());
2712 continue;
2713 }
2714 if (auto *SI = dyn_cast<StoreInst>(CB.Inst)) {
2715 AddFactsAboutIndices(SI->getPointerOperand(), SI->getAccessType());
2716 continue;
2717 }
2718 }
2719
2720 if (CB.isConditionFact()) {
2721 Pred = CB.Cond.Pred;
2722 A = CB.Cond.Op0;
2723 B = CB.Cond.Op1;
2724 if (CB.DoesHold.Pred != CmpInst::BAD_ICMP_PREDICATE &&
2725 !Info.doesHold(CB.DoesHold.Pred, CB.DoesHold.Op0, CB.DoesHold.Op1)) {
2726 LLVM_DEBUG({
2727 dbgs() << "Not adding fact ";
2728 dumpUnpackedICmp(dbgs(), Pred, A, B);
2729 dbgs() << " because precondition ";
2730 dumpUnpackedICmp(dbgs(), CB.DoesHold.Pred, CB.DoesHold.Op0,
2731 CB.DoesHold.Op1);
2732 dbgs() << " does not hold.\n";
2733 });
2734 continue;
2735 }
2736 } else {
2737 [[maybe_unused]] bool Matched =
2739 m_ICmpLike(Pred, m_Value(A), m_Value(B))));
2740 assert(Matched &&
2741 "Must have an assume intrinsic with a icmp like operand");
2742 }
2743 AddFact(Pred, A, B);
2744 }
2745
2746 if (ReproducerModule && !ReproducerModule->functions().empty()) {
2747 std::string S;
2748 raw_string_ostream StringS(S);
2749 ReproducerModule->print(StringS, nullptr);
2750 OptimizationRemark Rem(DEBUG_TYPE, "Reproducer", &F);
2751 Rem << ore::NV("module") << S;
2752 ORE.emit(Rem);
2753 }
2754
2755#ifndef NDEBUG
2756 unsigned SignedEntries =
2757 count_if(DFSInStack, [](const StackEntry &E) { return E.IsSigned; });
2758 assert(Info.getCS(false).size() - FunctionArgs.size() ==
2759 DFSInStack.size() - SignedEntries &&
2760 "updates to CS and DFSInStack are out of sync");
2761 assert(Info.getCS(true).size() == SignedEntries &&
2762 "updates to CS and DFSInStack are out of sync");
2763#endif
2764
2765 for (Instruction *I : ToRemove)
2766 I->eraseFromParent();
2767 return Changed;
2768}
2769
2772 auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
2773 auto &LI = AM.getResult<LoopAnalysis>(F);
2774 // SCEV is only used for loops, only construct it if there are some.
2775 auto *SE = LI.empty() ? nullptr : &AM.getResult<ScalarEvolutionAnalysis>(F);
2777 auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
2778 if (!eliminateConstraints(F, DT, LI, SE, ORE, TLI))
2779 return PreservedAnalyses::all();
2780
2784 return PA;
2785}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t 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 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
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
bool ult(const APInt &RHS) const
Unsigned less than comparison.
Definition APInt.h:1115
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:509
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
unsigned getBitWidth() const
getBitWidth - Return the scalar bitwidth of this constant.
Definition Constants.h:162
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
Definition Constants.h:168
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:44
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.
static LLVM_ABI void normalizeByGCD(MutableArrayRef< Entry > R)
Divide the variable coefficients of R by their greatest common divisor G and round the constant down ...
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:766
iterator end()
Definition DenseMap.h:686
unsigned size() const
Definition DenseMap.h:717
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:2909
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:76
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:549
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:716
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:557
Represents an op.with.overflow intrinsic.
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:201
constexpr bool isFixed() const
Returns true if the quantity is not scaled by vscale.
Definition TypeSize.h:172
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)
BinOpPred_match< LHS, RHS, is_right_shift_op > m_Shr(const LHS &L, const RHS &R)
Matches logical shift operations.
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.
is_zero< true > m_Zero()
Match any null constant or a vector with all elements equal to 0.
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))
Exact_match< T > m_Exact(const T &SubPattern)
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.
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)
@ 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
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
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
const ScalarOptions & getScalarOptions(const LLVMContext &C)
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