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 "llvm/ADT/STLExtras.h"
16#include "llvm/ADT/ScopeExit.h"
18#include "llvm/ADT/Statistic.h"
29#include "llvm/IR/DataLayout.h"
30#include "llvm/IR/DebugInfo.h"
31#include "llvm/IR/Dominators.h"
32#include "llvm/IR/Function.h"
33#include "llvm/IR/IRBuilder.h"
34#include "llvm/IR/InstrTypes.h"
36#include "llvm/IR/Module.h"
38#include "llvm/IR/Verifier.h"
39#include "llvm/Pass.h"
41#include "llvm/Support/Debug.h"
46
47#include <optional>
48#include <string>
49
50using namespace llvm;
51using namespace PatternMatch;
52using namespace SCEVPatternMatch;
53
54#define DEBUG_TYPE "constraint-elimination"
55
56STATISTIC(NumCondsRemoved, "Number of instructions removed");
57DEBUG_COUNTER(EliminatedCounter, "conds-eliminated",
58 "Controls which conditions are eliminated");
59
61 MaxRows("constraint-elimination-max-rows", cl::init(500), cl::Hidden,
62 cl::desc("Maximum number of rows to keep in constraint system"));
63
65 "constraint-elimination-dump-reproducers", cl::init(false), cl::Hidden,
66 cl::desc("Dump IR to reproduce successful transformations."));
67
68static int64_t MaxConstraintValue = std::numeric_limits<int64_t>::max();
69static int64_t MinSignedConstraintValue = std::numeric_limits<int64_t>::min();
70
72 Instruction *UserI = cast<Instruction>(U.getUser());
73 if (auto *Phi = dyn_cast<PHINode>(UserI))
74 UserI = Phi->getIncomingBlock(U)->getTerminator();
75 return UserI;
76}
77
78namespace {
79using Entry = ConstraintSystem::Entry;
80using RowTy = ConstraintSystem::RowTy;
81
82/// Struct to express a condition of the form %Op0 Pred %Op1.
83struct ConditionTy {
84 CmpPredicate Pred;
85 Value *Op0 = nullptr;
86 Value *Op1 = nullptr;
87
88 ConditionTy() = default;
89 ConditionTy(CmpPredicate Pred, Value *Op0, Value *Op1)
90 : Pred(Pred), Op0(Op0), Op1(Op1) {}
91};
92
93/// Represents either
94/// * a condition that holds on entry to a block (=condition fact)
95/// * an assume (=assume fact)
96/// * a use of a compare instruction to simplify.
97/// It also tracks the Dominator DFS in and out numbers for each entry.
98struct FactOrCheck {
99 enum class EntryTy {
100 ConditionFact, /// A condition that holds on entry to a block.
101 InstFact, /// A fact that holds after Inst executed (e.g. an assume or
102 /// min/mix intrinsic.
103 InstCheck, /// An instruction to simplify (e.g. an overflow math
104 /// intrinsics).
105 UseCheck /// An use of a compare instruction to simplify.
106 };
107
108 union {
109 Instruction *Inst;
110 Use *U;
112 };
113
114 /// A pre-condition that must hold for the current fact to be added to the
115 /// system.
116 ConditionTy DoesHold;
117
118 unsigned NumIn;
119 unsigned NumOut;
120 EntryTy Ty;
121
122 FactOrCheck(EntryTy Ty, DomTreeNode *DTN, Instruction *Inst)
123 : Inst(Inst), NumIn(DTN->getDFSNumIn()), NumOut(DTN->getDFSNumOut()),
124 Ty(Ty) {}
125
126 FactOrCheck(DomTreeNode *DTN, Use *U)
127 : U(U), NumIn(DTN->getDFSNumIn()), NumOut(DTN->getDFSNumOut()),
128 Ty(EntryTy::UseCheck) {}
129
130 FactOrCheck(DomTreeNode *DTN, CmpPredicate Pred, Value *Op0, Value *Op1,
131 ConditionTy Precond = {})
132 : Cond(Pred, Op0, Op1), DoesHold(Precond), NumIn(DTN->getDFSNumIn()),
133 NumOut(DTN->getDFSNumOut()), Ty(EntryTy::ConditionFact) {}
134
135 static FactOrCheck getConditionFact(DomTreeNode *DTN, CmpPredicate Pred,
136 Value *Op0, Value *Op1,
137 ConditionTy Precond = {}) {
138 return FactOrCheck(DTN, Pred, Op0, Op1, Precond);
139 }
140
141 static FactOrCheck getInstFact(DomTreeNode *DTN, Instruction *Inst) {
142 return FactOrCheck(EntryTy::InstFact, DTN, Inst);
143 }
144
145 static FactOrCheck getCheck(DomTreeNode *DTN, Use *U) {
146 return FactOrCheck(DTN, U);
147 }
148
149 static FactOrCheck getCheck(DomTreeNode *DTN, CallInst *CI) {
150 return FactOrCheck(EntryTy::InstCheck, DTN, CI);
151 }
152
153 bool isCheck() const {
154 return Ty == EntryTy::InstCheck || Ty == EntryTy::UseCheck;
155 }
156
157 Instruction *getContextInst() const {
158 assert(!isConditionFact());
159 if (Ty == EntryTy::UseCheck)
160 return getContextInstForUse(*U);
161 return Inst;
162 }
163
164 Instruction *getInstructionToSimplify() const {
165 assert(isCheck());
166 if (Ty == EntryTy::InstCheck)
167 return Inst;
168 // The use may have been simplified to a constant already.
169 return dyn_cast<Instruction>(*U);
170 }
171
172 bool isConditionFact() const { return Ty == EntryTy::ConditionFact; }
173};
174
175/// The senses in which an induction phi is monotonic, together with the
176/// direction it moves in.
177struct MonotonicInfo {
178 /// True if the phi steps by a negative constant.
179 bool Decreasing = false;
180 /// True if the phi is monotonic in the unsigned sense.
181 bool Unsigned = false;
182 /// True if the phi is monotonic in the signed sense.
183 bool Signed = false;
184};
185
186/// Keep state required to build worklist.
187struct State {
188 DominatorTree &DT;
189 LoopInfo &LI;
190 ScalarEvolution &SE;
191 TargetLibraryInfo &TLI;
193
194 State(DominatorTree &DT, LoopInfo &LI, ScalarEvolution &SE,
195 TargetLibraryInfo &TLI)
196 : DT(DT), LI(LI), SE(SE), TLI(TLI) {}
197
198 /// Process block \p BB and add known facts to work-list.
199 void addInfoFor(BasicBlock &BB);
200
201 /// If \p BB is a loop header, bound each induction phi in it by its start
202 /// value.
203 void addBoundsForHeaderInductions(BasicBlock &BB);
204
205 /// Try to add facts for loop inductions (AddRecs) in EQ/NE compares
206 /// controlling the loop header.
207 void addInfoForInductions(BasicBlock &BB);
208
209 /// Returns the direction the induction phi \p PN with backedge value \p Step
210 /// moves in, and the senses in which it is monotonic in that direction.
211 MonotonicInfo getMonotonicityInfo(PHINode &PN, Value *Step);
212
213 /// Returns true if we can add a known condition from BB to its successor
214 /// block Succ.
215 bool canAddSuccessor(BasicBlock &BB, BasicBlock *Succ) const {
216 return DT.dominates(BasicBlockEdge(&BB, Succ), Succ);
217 }
218};
219
220class ConstraintInfo;
221
222struct StackEntry {
223 unsigned NumIn;
224 unsigned NumOut;
225 bool IsSigned = false;
226 /// Variables that can be removed from the system once the stack entry gets
227 /// removed.
228 SmallVector<Value *, 2> ValuesToRelease;
229
230 StackEntry(unsigned NumIn, unsigned NumOut, bool IsSigned,
231 SmallVector<Value *, 2> ValuesToRelease)
232 : NumIn(NumIn), NumOut(NumOut), IsSigned(IsSigned),
233 ValuesToRelease(std::move(ValuesToRelease)) {}
234};
235
236struct ConstraintTy {
237 RowTy Coefficients;
238
239 /// Number of variables the constraint is defined over.
240 unsigned NumVars = 0;
241
242 bool IsSigned = false;
243
244 ConstraintTy() = default;
245
246 ConstraintTy(RowTy Coefficients, unsigned NumVars, bool IsSigned, bool IsEq,
247 bool IsNe)
248 : Coefficients(std::move(Coefficients)), NumVars(NumVars),
249 IsSigned(IsSigned), IsEq(IsEq), IsNe(IsNe) {}
250
251 bool empty() const { return Coefficients.empty(); }
252
253 /// Returns true if the constraint does not reference any variable, i.e. it is
254 /// of the form 'c >= 0'.
255 bool isConstantOnly() const { return Coefficients.size() < 2; }
256
257 bool isEq() const { return IsEq; }
258
259 bool isNe() const { return IsNe; }
260
261 /// Check if the current constraint is implied by the given ConstraintSystem.
262 ///
263 /// \return true or false if the constraint is proven to be respectively true,
264 /// or false. When the constraint cannot be proven to be either true or false,
265 /// std::nullopt is returned.
266 std::optional<bool> isImpliedBy(const ConstraintSystem &CS) const;
267
268private:
269 bool IsEq = false;
270 bool IsNe = false;
271};
272
273/// Wrapper encapsulating separate constraint systems and corresponding value
274/// mappings for both unsigned and signed information. Facts are added to and
275/// conditions are checked against the corresponding system depending on the
276/// signed-ness of their predicates. While the information is kept separate
277/// based on signed-ness, certain conditions can be transferred between the two
278/// systems.
279class ConstraintInfo {
280
281 ConstraintSystem UnsignedCS;
282 ConstraintSystem SignedCS;
283
284 const DataLayout &DL;
285
286public:
287 ConstraintInfo(const DataLayout &DL, ArrayRef<Value *> FunctionArgs)
288 : UnsignedCS(FunctionArgs), SignedCS(FunctionArgs), DL(DL) {
289 auto &Value2Index = getValue2Index(false);
290 // Add Arg > -1 constraints to unsigned system for all function arguments.
291 for (Value *Arg : FunctionArgs)
292 UnsignedCS.addRow({Entry(0, 0), Entry(-1, Value2Index.at(Arg))},
293 Value2Index.size());
294 }
295
296 DenseMap<Value *, unsigned> &getValue2Index(bool Signed) {
297 return Signed ? SignedCS.getValue2Index() : UnsignedCS.getValue2Index();
298 }
299 const DenseMap<Value *, unsigned> &getValue2Index(bool Signed) const {
300 return Signed ? SignedCS.getValue2Index() : UnsignedCS.getValue2Index();
301 }
302
303 ConstraintSystem &getCS(bool Signed) {
304 return Signed ? SignedCS : UnsignedCS;
305 }
306 const ConstraintSystem &getCS(bool Signed) const {
307 return Signed ? SignedCS : UnsignedCS;
308 }
309
310 void popLastConstraint(bool Signed) { getCS(Signed).popLastConstraint(); }
311 void popLastNVariables(bool Signed, unsigned N) {
312 getCS(Signed).popLastNVariables(N);
313 }
314
315 bool doesHold(CmpInst::Predicate Pred, Value *A, Value *B) const;
316
317 /// Returns true if \p V is known to be non-negative, either because the
318 /// signed system implies it or because ValueTracking can prove it.
319 bool isKnownNonNegative(Value *V) const;
320
321 void addFact(CmpInst::Predicate Pred, Value *A, Value *B, unsigned NumIn,
322 unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack);
323
324 /// Turn a comparison of the form \p Op0 \p Pred \p Op1 into a vector of
325 /// constraints, using indices from the corresponding constraint system.
326 /// New variables that need to be added to the system are collected in
327 /// \p NewVariables.
328 ConstraintTy getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
329 SmallVectorImpl<Value *> &NewVariables,
330 bool ForceSignedSystem = false) const;
331
332 /// Turns a comparison of the form \p Op0 \p Pred \p Op1 into a vector of
333 /// constraints using getConstraint. Returns an empty constraint if the result
334 /// cannot be used to query the existing constraint system, e.g. because it
335 /// would require adding new variables. Also tries to convert signed
336 /// predicates to unsigned ones if possible to allow using the unsigned system
337 /// which increases the effectiveness of the signed <-> unsigned transfer
338 /// logic.
339 ConstraintTy getConstraintForSolving(CmpInst::Predicate Pred, Value *Op0,
340 Value *Op1) const;
341
342 /// Try to add information from \p A \p Pred \p B to the unsigned/signed
343 /// system if \p Pred is signed/unsigned.
344 void transferToOtherSystem(CmpInst::Predicate Pred, Value *A, Value *B,
345 unsigned NumIn, unsigned NumOut,
346 SmallVectorImpl<StackEntry> &DFSInStack);
347
348private:
349 /// Adds facts into constraint system. \p ForceSignedSystem can be set when
350 /// the \p Pred is eq/ne, and signed constraint system is used when it's
351 /// specified.
352 void addFactImpl(CmpInst::Predicate Pred, Value *A, Value *B, unsigned NumIn,
353 unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack,
354 bool ForceSignedSystem);
355
356 /// Try to use the inequality \p A != \p B to tighten a non-strict bound the
357 /// system already implies to the corresponding strict bound.
358 void tightenBoundUsingNe(Value *A, Value *B, unsigned NumIn, unsigned NumOut,
359 SmallVectorImpl<StackEntry> &DFSInStack);
360};
361
362/// Represents a (Coefficient * Variable) entry after IR decomposition.
363struct DecompEntry {
364 int64_t Coefficient;
365 Value *Variable;
366
367 DecompEntry(int64_t Coefficient, Value *Variable)
368 : Coefficient(Coefficient), Variable(Variable) {}
369};
370
371/// Represents an Offset + Coefficient1 * Variable1 + ... decomposition.
372struct Decomposition {
373 int64_t Offset = 0;
375
376 Decomposition(int64_t Offset) : Offset(Offset) {}
377 Decomposition(Value *V) { Vars.emplace_back(1, V); }
378 Decomposition(int64_t Offset, ArrayRef<DecompEntry> Vars)
379 : Offset(Offset), Vars(Vars) {}
380
381 /// Add \p OtherOffset and return true if the operation overflows, i.e. the
382 /// new decomposition is invalid.
383 [[nodiscard]] bool add(int64_t OtherOffset) {
384 return AddOverflow(Offset, OtherOffset, Offset);
385 }
386
387 /// Add \p Other and return true if the operation overflows, i.e. the new
388 /// decomposition is invalid.
389 [[nodiscard]] bool add(const Decomposition &Other) {
390 if (add(Other.Offset))
391 return true;
392 append_range(Vars, Other.Vars);
393 return false;
394 }
395
396 /// Subtract \p Other and return true if the operation overflows, i.e. the new
397 /// decomposition is invalid.
398 [[nodiscard]] bool sub(const Decomposition &Other) {
399 Decomposition Tmp = Other;
400 if (Tmp.mul(-1))
401 return true;
402 if (add(Tmp.Offset))
403 return true;
404 append_range(Vars, Tmp.Vars);
405 return false;
406 }
407
408 /// Multiply all coefficients by \p Factor and return true if the operation
409 /// overflows, i.e. the new decomposition is invalid.
410 [[nodiscard]] bool mul(int64_t Factor) {
411 if (MulOverflow(Offset, Factor, Offset))
412 return true;
413 for (auto &Var : Vars)
414 if (MulOverflow(Var.Coefficient, Factor, Var.Coefficient))
415 return true;
416 return false;
417 }
418};
419
420// Variable and constant offsets for a chain of GEPs, with base pointer BasePtr.
421struct OffsetResult {
422 Value *BasePtr;
423 APInt ConstantOffset;
424 SmallMapVector<Value *, APInt, 4> VariableOffsets;
425 GEPNoWrapFlags NW;
426
427 OffsetResult() : BasePtr(nullptr), ConstantOffset(0, uint64_t(0)) {}
428
429 OffsetResult(GEPOperator &GEP, const DataLayout &DL)
430 : BasePtr(GEP.getPointerOperand()), NW(GEP.getNoWrapFlags()) {
431 ConstantOffset = APInt(DL.getIndexTypeSizeInBits(BasePtr->getType()), 0);
432 }
433};
434} // namespace
435
436// Try to collect variable and constant offsets for \p GEP, partly traversing
437// nested GEPs. Returns an OffsetResult with nullptr as BasePtr of collecting
438// the offset fails.
440 OffsetResult Result(GEP, DL);
441 unsigned BitWidth = Result.ConstantOffset.getBitWidth();
442 if (!GEP.collectOffset(DL, BitWidth, Result.VariableOffsets,
443 Result.ConstantOffset))
444 return {};
445
446 // If we have a nested GEP, check if we can combine the constant offset of the
447 // inner GEP with the outer GEP.
448 if (auto *InnerGEP = dyn_cast<GetElementPtrInst>(Result.BasePtr)) {
449 SmallMapVector<Value *, APInt, 4> VariableOffsets2;
450 APInt ConstantOffset2(BitWidth, 0);
451 bool CanCollectInner = InnerGEP->collectOffset(
452 DL, BitWidth, VariableOffsets2, ConstantOffset2);
453 // TODO: Support cases with more than 1 variable offset.
454 if (!CanCollectInner || Result.VariableOffsets.size() > 1 ||
455 VariableOffsets2.size() > 1 ||
456 (Result.VariableOffsets.size() >= 1 && VariableOffsets2.size() >= 1)) {
457 // More than 1 variable index, use outer result.
458 return Result;
459 }
460 Result.BasePtr = InnerGEP->getPointerOperand();
461 Result.ConstantOffset += ConstantOffset2;
462 if (Result.VariableOffsets.size() == 0 && VariableOffsets2.size() == 1)
463 Result.VariableOffsets = std::move(VariableOffsets2);
464 Result.NW &= InnerGEP->getNoWrapFlags();
465 }
466 return Result;
467}
468
469static Decomposition decompose(Value *V, const ConstraintInfo &Info,
470 bool IsSigned, const DataLayout &DL);
471
472static bool canUseSExt(ConstantInt *CI) {
473 const APInt &Val = CI->getValue();
475}
476
477/// Returns true if the pre-condition \p Op \p Pred \p RHS, required to look
478/// through an expression while decomposing it, is known to hold given \p Info.
479static bool preconditionHolds(const ConstraintInfo &Info,
480 CmpInst::Predicate Pred, Value *Op, int64_t RHS) {
481 return Info.doesHold(Pred, Op, ConstantInt::get(Op->getType(), RHS));
482}
483
484static Decomposition decomposeGEP(GEPOperator &GEP, const ConstraintInfo &Info,
485 bool IsSigned, const DataLayout &DL) {
486 // Do not reason about pointers where the index size is larger than 64 bits,
487 // as the coefficients used to encode constraints are 64 bit integers.
488 if (DL.getIndexTypeSizeInBits(GEP.getPointerOperand()->getType()) > 64)
489 return &GEP;
490
491 assert(!IsSigned && "The logic below only supports decomposition for "
492 "unsigned predicates at the moment.");
493 const auto &[BasePtr, ConstantOffset, VariableOffsets, NW] =
495 // We support either plain gep nuw, or gep nusw with non-negative offset,
496 // which implies gep nuw.
497 if (!BasePtr || NW == GEPNoWrapFlags::none())
498 return &GEP;
499
500 // For a nuw-only GEP (nuw without nusw/inbounds), the offset must be
501 // interpreted as unsigned.
502 if (!NW.hasNoUnsignedSignedWrap() && ConstantOffset.isNegative())
503 return &GEP;
504
505 Decomposition Result(ConstantOffset.getSExtValue(), DecompEntry(1, BasePtr));
506 for (auto [Index, Scale] : VariableOffsets) {
507 if (!NW.hasNoUnsignedWrap()) {
508 // Try to prove nuw from nusw and nneg. If the index cannot be proven
509 // non-negative, keep the GEP as-is instead of decomposing it.
510 assert(NW.hasNoUnsignedSignedWrap() && "Must have nusw flag");
511 if (!isKnownNonNegative(Index, DL) &&
512 !preconditionHolds(Info, CmpInst::ICMP_SGE, Index, 0))
513 return &GEP;
514 }
515
516 auto IdxResult = decompose(Index, Info, IsSigned, DL);
517 if (IdxResult.mul(Scale.getSExtValue()))
518 return &GEP;
519 if (Result.add(IdxResult))
520 return &GEP;
521 }
522 return Result;
523}
524
525// Decomposes \p V into a constant offset + list of pairs { Coefficient,
526// Variable } where Coefficient * Variable. The sum of the constant offset and
527// pairs equals \p V.
528//
529// Looking through certain expressions is only valid if a pre-condition holds.
530// Pre-conditions are checked against \p Info as needed.
531static Decomposition decompose(Value *V, const ConstraintInfo &Info,
532 bool IsSigned, const DataLayout &DL) {
533 auto MergeResults = [&Info, IsSigned,
534 &DL](Value *A, Value *B,
535 bool IsSignedB) -> std::optional<Decomposition> {
536 auto ResA = decompose(A, Info, IsSigned, DL);
537 auto ResB = decompose(B, Info, IsSignedB, DL);
538 if (ResA.add(ResB))
539 return std::nullopt;
540 return ResA;
541 };
542
543 Type *Ty = V->getType()->getScalarType();
544 if (Ty->isPointerTy() && !IsSigned) {
545 if (auto *GEP = dyn_cast<GEPOperator>(V))
546 return decomposeGEP(*GEP, Info, IsSigned, DL);
548 return int64_t(0);
549
550 return V;
551 }
552
553 // Don't handle integers > 64 bit. Our coefficients are 64-bit large, so
554 // coefficient add/mul may wrap, while the operation in the full bit width
555 // would not.
556 if (!Ty->isIntegerTy() || Ty->getIntegerBitWidth() > 64)
557 return V;
558
559 // Decompose \p V used with a signed predicate.
560 if (IsSigned) {
561 if (auto *CI = dyn_cast<ConstantInt>(V)) {
562 if (canUseSExt(CI))
563 return CI->getSExtValue();
564 }
565 Value *Op0;
566 Value *Op1;
567
568 if (match(V, m_SExt(m_Value(Op0))))
569 V = Op0;
570 else if (match(V, m_NNegZExt(m_Value(Op0)))) {
571 V = Op0;
572 } else if (match(V, m_NSWTrunc(m_Value(Op0)))) {
573 if (Op0->getType()->getScalarSizeInBits() <= 64)
574 V = Op0;
575 }
576
577 if (match(V, m_NSWAdd(m_Value(Op0), m_Value(Op1)))) {
578 if (auto Decomp = MergeResults(Op0, Op1, IsSigned))
579 return *Decomp;
580 return V;
581 }
582
583 // `xor %x, -1` is equivalent to `sub nsw -1, %x`.
584 if (match(V, m_Not(m_Value(Op0)))) {
585 Decomposition Result(-1);
586 if (!Result.sub(decompose(Op0, Info, IsSigned, DL)))
587 return Result;
588 return V;
589 }
590
591 if (match(V, m_NSWSub(m_Value(Op0), m_Value(Op1)))) {
592 auto ResA = decompose(Op0, Info, IsSigned, DL);
593 auto ResB = decompose(Op1, Info, IsSigned, DL);
594 if (!ResA.sub(ResB))
595 return ResA;
596 return V;
597 }
598
599 ConstantInt *CI;
600 if (match(V, m_NSWMul(m_Value(Op0), m_ConstantInt(CI))) && canUseSExt(CI)) {
601 auto Result = decompose(Op0, Info, IsSigned, DL);
602 if (!Result.mul(CI->getSExtValue()))
603 return Result;
604 return V;
605 }
606
607 // (shl nsw x, shift) is (mul nsw x, (1<<shift)), with the exception of
608 // shift == bw-1.
609 if (match(V, m_NSWShl(m_Value(Op0), m_ConstantInt(CI)))) {
610 uint64_t Shift = CI->getValue().getLimitedValue();
611 if (Shift < Ty->getIntegerBitWidth() - 1) {
612 assert(Shift < 64 && "Would overflow");
613 auto Result = decompose(Op0, Info, IsSigned, DL);
614 if (!Result.mul(int64_t(1) << Shift))
615 return Result;
616 return V;
617 }
618 }
619
620 return V;
621 }
622
623 if (auto *CI = dyn_cast<ConstantInt>(V)) {
624 if (CI->uge(MaxConstraintValue))
625 return V;
626 return int64_t(CI->getZExtValue());
627 }
628
629 Value *Op0;
630 if (match(V, m_ZExt(m_Value(Op0)))) {
631 V = Op0;
632 } else if (match(V, m_SExt(m_Value(Op0)))) {
633 // Looking through the sext is only valid if the operand is non-negative.
634 if (!preconditionHolds(Info, CmpInst::ICMP_SGE, Op0, 0))
635 return V;
636 V = Op0;
637 } else if (auto *Trunc = dyn_cast<TruncInst>(V)) {
638 if (Trunc->getSrcTy()->getScalarSizeInBits() <= 64 &&
639 (Trunc->hasNoUnsignedWrap() || Trunc->hasNoSignedWrap())) {
640 Value *Src = Trunc->getOperand(0);
641 // A trunc nsw only truncates without unsigned wrap if its operand is
642 // non-negative.
643 if (!Trunc->hasNoUnsignedWrap() &&
644 !preconditionHolds(Info, CmpInst::ICMP_SGE, Src, 0))
645 return V;
646 V = Src;
647 }
648 }
649
650 Value *Op1;
651 ConstantInt *CI;
652 if (match(V, m_NUWAdd(m_Value(Op0), m_Value(Op1)))) {
653 if (auto Decomp = MergeResults(Op0, Op1, IsSigned))
654 return *Decomp;
655 return V;
656 }
657
658 if (match(V, m_Add(m_Value(Op0), m_ConstantInt(CI))) && CI->isNegative() &&
659 canUseSExt(CI)) {
660 // Adding a negative constant only wraps if Op0 is smaller than it.
661 if (!preconditionHolds(Info, CmpInst::ICMP_UGE, Op0,
662 CI->getSExtValue() * -1))
663 return V;
664 if (auto Decomp = MergeResults(Op0, CI, true))
665 return *Decomp;
666 return V;
667 }
668
669 if (match(V, m_NSWAdd(m_Value(Op0), m_Value(Op1)))) {
670 // An add nsw only adds without unsigned wrap if both operands are
671 // non-negative.
672 if ((!isKnownNonNegative(Op0, DL) &&
673 !preconditionHolds(Info, CmpInst::ICMP_SGE, Op0, 0)) ||
674 (!isKnownNonNegative(Op1, DL) &&
675 !preconditionHolds(Info, CmpInst::ICMP_SGE, Op1, 0)))
676 return V;
677
678 if (auto Decomp = MergeResults(Op0, Op1, IsSigned))
679 return *Decomp;
680 return V;
681 }
682
683 // Decompose or as an add if there are no common bits between the operands.
684 if (match(V, m_DisjointOr(m_Value(Op0), m_ConstantInt(CI)))) {
685 if (auto Decomp = MergeResults(Op0, CI, IsSigned))
686 return *Decomp;
687 return V;
688 }
689
690 if (match(V, m_NUWShl(m_Value(Op1), m_ConstantInt(CI))) && canUseSExt(CI)) {
691 // The scale 1 << shift must fit in the signed coefficient, so reject a
692 // shift of 63, for which int64_t{1} << 63 is INT64_MIN.
693 if (CI->getSExtValue() < 0 || CI->getSExtValue() >= 63)
694 return V;
695 auto Result = decompose(Op1, Info, IsSigned, DL);
696 if (!Result.mul(int64_t{1} << CI->getSExtValue()))
697 return Result;
698 return V;
699 }
700
701 if (match(V, m_NUWMul(m_Value(Op1), m_ConstantInt(CI))) && canUseSExt(CI) &&
702 (!CI->isNegative())) {
703 auto Result = decompose(Op1, Info, IsSigned, DL);
704 if (!Result.mul(CI->getSExtValue()))
705 return Result;
706 return V;
707 }
708
709 if (match(V, m_Sub(m_Value(Op0), m_Value(Op1)))) {
710 // a - b can be decomposed when there is no unsigned wrap (either known via
711 // flag or proven as precondition).
713 !Info.doesHold(CmpInst::ICMP_ULE, Op1, Op0))
714 return V;
715 auto ResA = decompose(Op0, Info, IsSigned, DL);
716 auto ResB = decompose(Op1, Info, IsSigned, DL);
717 if (!ResA.sub(ResB))
718 return ResA;
719 return V;
720 }
721
722 return V;
723}
724
725ConstraintTy
726ConstraintInfo::getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
727 SmallVectorImpl<Value *> &NewVariables,
728 bool ForceSignedSystem) const {
729 assert(NewVariables.empty() && "NewVariables must be empty when passed in");
730 assert((!ForceSignedSystem || CmpInst::isEquality(Pred)) &&
731 "signed system can only be forced on eq/ne");
732
733 bool IsEq = false;
734 bool IsNe = false;
735
736 // Try to convert Pred to one of ULE/ULT/SLE/SLT.
737 switch (Pred) {
741 case CmpInst::ICMP_SGE: {
742 Pred = CmpInst::getSwappedPredicate(Pred);
743 std::swap(Op0, Op1);
744 break;
745 }
746 case CmpInst::ICMP_EQ:
747 if (!ForceSignedSystem && match(Op1, m_Zero())) {
748 Pred = CmpInst::ICMP_ULE;
749 } else {
750 IsEq = true;
751 Pred = CmpInst::ICMP_ULE;
752 }
753 break;
754 case CmpInst::ICMP_NE:
755 if (!ForceSignedSystem && match(Op1, m_Zero())) {
757 std::swap(Op0, Op1);
758 } else {
759 IsNe = true;
760 Pred = CmpInst::ICMP_ULE;
761 }
762 break;
763 default:
764 break;
765 }
766
767 if (Pred != CmpInst::ICMP_ULE && Pred != CmpInst::ICMP_ULT &&
768 Pred != CmpInst::ICMP_SLE && Pred != CmpInst::ICMP_SLT)
769 return {};
770
771 bool IsSigned = ForceSignedSystem || CmpInst::isSigned(Pred);
772 auto &Value2Index = getValue2Index(IsSigned);
773 auto ADec = decompose(Op0->stripPointerCastsSameRepresentation(), *this,
774 IsSigned, DL);
775 auto BDec = decompose(Op1->stripPointerCastsSameRepresentation(), *this,
776 IsSigned, DL);
777 int64_t Offset1 = ADec.Offset;
778 int64_t Offset2 = BDec.Offset;
779 Offset1 *= -1;
780
781 auto &VariablesA = ADec.Vars;
782 auto &VariablesB = BDec.Vars;
783
784 // First try to look up \p V in Value2Index and NewVariables. Otherwise add a
785 // new entry to NewVariables.
786 auto GetOrAddIndex = [&Value2Index, &NewVariables](Value *V) -> unsigned {
787 auto V2I = Value2Index.find(V);
788 if (V2I != Value2Index.end())
789 return V2I->second;
790 unsigned Idx = find(NewVariables, V) - NewVariables.begin();
791 if (Idx == NewVariables.size())
792 NewVariables.push_back(V);
793 return Value2Index.size() + Idx + 1;
794 };
795
796 // Build result constraint, by first adding all coefficients from A and then
797 // subtracting all coefficients from B.
798 RowTy R(1, Entry(0, 0));
799 auto GetCoefficient = [&R](unsigned Idx) -> int64_t & {
800 // The entry for Idx, or the place to insert it at, is the first entry with
801 // an index >= Idx.
802 Entry *I =
803 find_if(drop_begin(R), [Idx](const Entry &E) { return E.Id >= Idx; });
804 if (I == R.end() || I->Id != Idx)
805 I = R.insert(I, Entry(0, Idx));
806 return I->Coefficient;
807 };
808 for (const auto &KV : VariablesA)
809 GetCoefficient(GetOrAddIndex(KV.Variable)) += KV.Coefficient;
810
811 for (const auto &KV : VariablesB) {
812 auto &Coeff = GetCoefficient(GetOrAddIndex(KV.Variable));
813 if (SubOverflow(Coeff, KV.Coefficient, Coeff))
814 return {};
815 }
816
817 int64_t OffsetSum;
818 if (AddOverflow(Offset1, Offset2, OffsetSum))
819 return {};
820 if (Pred == CmpInst::ICMP_SLT || Pred == CmpInst::ICMP_ULT)
821 if (AddOverflow(OffsetSum, int64_t(-1), OffsetSum))
822 return {};
823 R[0].Coefficient = OffsetSum;
824
825 // Drop coefficients that cancelled out.
826 erase_if(R, [](const Entry &E) { return E.Id != 0 && E.Coefficient == 0; });
827
828 // Remove any new variable without a coefficient in the row.
829 unsigned NumV2I = Value2Index.size();
830 NewVariables.truncate(R.back().Id > NumV2I ? R.back().Id - NumV2I : 0);
831
832 return ConstraintTy(std::move(R), Value2Index.size() + NewVariables.size(),
833 IsSigned, IsEq, IsNe);
834}
835
836ConstraintTy ConstraintInfo::getConstraintForSolving(CmpInst::Predicate Pred,
837 Value *Op0,
838 Value *Op1) const {
839 Constant *NullC = Constant::getNullValue(Op0->getType());
840 // Handle trivially true compares directly to avoid adding V UGE 0 constraints
841 // for all variables in the unsigned system.
842 if ((Pred == CmpInst::ICMP_ULE && Op0 == NullC) ||
843 (Pred == CmpInst::ICMP_UGE && Op1 == NullC)) {
844 // Return constraint that's trivially true.
845 return ConstraintTy(RowTy(1, Entry(0, 0)), /*NumVars=*/0,
846 /*IsSigned=*/false, /*IsEq=*/false, /*IsNe=*/false);
847 }
848
849 // If both operands are known to be non-negative, change signed predicates to
850 // unsigned ones. This increases the reasoning effectiveness in combination
851 // with the signed <-> unsigned transfer logic.
852 if (CmpInst::isSigned(Pred) &&
856
857 SmallVector<Value *> NewVariables;
858 ConstraintTy R = getConstraint(Pred, Op0, Op1, NewVariables);
859 if (!NewVariables.empty())
860 return {};
861 return R;
862}
863
864std::optional<bool>
865ConstraintTy::isImpliedBy(const ConstraintSystem &CS) const {
866 const auto &[SubCS, NewCoefficients] = CS.getSubSystem(Coefficients);
867 bool IsConditionImplied = SubCS.isConditionImplied(NewCoefficients);
868
869 if (IsEq || IsNe) {
870 auto NegatedOrEqual = ConstraintSystem::negateOrEqual(NewCoefficients);
871 bool IsNegatedOrEqualImplied =
872 !NegatedOrEqual.empty() && SubCS.isConditionImplied(NegatedOrEqual);
873
874 // In order to check that `%a == %b` is true (equality), both conditions `%a
875 // >= %b` and `%a <= %b` must hold true. When checking for equality (`IsEq`
876 // is true), we return true if they both hold, false in the other cases.
877 if (IsConditionImplied && IsNegatedOrEqualImplied)
878 return IsEq;
879
880 auto Negated = ConstraintSystem::negate(NewCoefficients);
881 bool IsNegatedImplied =
882 !Negated.empty() && SubCS.isConditionImplied(Negated);
883
884 auto StrictLessThan = ConstraintSystem::toStrictLessThan(NewCoefficients);
885 bool IsStrictLessThanImplied =
886 !StrictLessThan.empty() && SubCS.isConditionImplied(StrictLessThan);
887
888 // In order to check that `%a != %b` is true (non-equality), either
889 // condition `%a > %b` or `%a < %b` must hold true. When checking for
890 // non-equality (`IsNe` is true), we return true if one of the two holds,
891 // false in the other cases.
892 if (IsNegatedImplied || IsStrictLessThanImplied)
893 return IsNe;
894
895 return std::nullopt;
896 }
897
898 if (IsConditionImplied)
899 return true;
900
901 auto Negated = ConstraintSystem::negate(NewCoefficients);
902 auto IsNegatedImplied = !Negated.empty() && SubCS.isConditionImplied(Negated);
903 if (IsNegatedImplied)
904 return false;
905
906 // Neither the condition nor its negated holds, did not prove anything.
907 return std::nullopt;
908}
909
910bool ConstraintInfo::doesHold(CmpInst::Predicate Pred, Value *A,
911 Value *B) const {
912 auto R = getConstraintForSolving(Pred, A, B);
913 return !R.empty() &&
914 getCS(R.IsSigned).isConditionImpliedInSubSystem(R.Coefficients);
915}
916
917bool ConstraintInfo::isKnownNonNegative(Value *V) const {
918 return doesHold(CmpInst::ICMP_SGE, V, ConstantInt::get(V->getType(), 0)) ||
920}
921
922void ConstraintInfo::transferToOtherSystem(
923 CmpInst::Predicate Pred, Value *A, Value *B, unsigned NumIn,
924 unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack) {
925 // Check if we can combine facts from the signed and unsigned systems to
926 // derive additional facts.
927 if (!A->getType()->isIntegerTy())
928 return;
929 // FIXME: This currently depends on the order we add facts. Ideally we
930 // would first add all known facts and only then try to add additional
931 // facts.
932 switch (Pred) {
933 default:
934 break;
937 // If B is a signed positive constant, then A >=s 0 and A <s (or <=s) B.
938 if (isKnownNonNegative(B)) {
939 addFact(CmpInst::ICMP_SGE, A, ConstantInt::get(B->getType(), 0), NumIn,
940 NumOut, DFSInStack);
941 addFact(ICmpInst::getSignedPredicate(Pred), A, B, NumIn, NumOut,
942 DFSInStack);
943 }
944 break;
947 // If A is a signed positive constant, then B >=s 0 and A >s (or >=s) B.
948 if (isKnownNonNegative(A)) {
949 addFact(CmpInst::ICMP_SGE, B, ConstantInt::get(B->getType(), 0), NumIn,
950 NumOut, DFSInStack);
951 addFact(ICmpInst::getSignedPredicate(Pred), A, B, NumIn, NumOut,
952 DFSInStack);
953 }
954 break;
958 addFact(ICmpInst::getUnsignedPredicate(Pred), A, B, NumIn, NumOut,
959 DFSInStack);
960 break;
961 case CmpInst::ICMP_SGT: {
962 if (doesHold(CmpInst::ICMP_SGE, B, Constant::getAllOnesValue(B->getType())))
963 addFact(CmpInst::ICMP_UGE, A, ConstantInt::get(B->getType(), 0), NumIn,
964 NumOut, DFSInStack);
966 addFact(CmpInst::ICMP_UGT, A, B, NumIn, NumOut, DFSInStack);
967
968 break;
969 }
972 addFact(CmpInst::ICMP_UGE, A, B, NumIn, NumOut, DFSInStack);
973 break;
974 }
975}
976
977#ifndef NDEBUG
978
980 const DenseMap<Value *, unsigned> &Value2Index) {
981 ConstraintSystem CS(Value2Index);
982 CS.addRow(C, Value2Index.size());
983 CS.dump();
984}
985#endif
986
987/// Splits the induction phi \p PN into the start value, coming from the loop
988/// predecessor \p LoopPred, and the backedge value, coming from inside the
989/// loop. Returns {nullptr, nullptr} if \p PN has other incoming values.
990static std::pair<Value *, Value *>
991getStartAndBackedgeValue(const PHINode &PN, const BasicBlock *LoopPred) {
992 assert(PN.getBasicBlockIndex(LoopPred) >= 0 &&
993 "LoopPred must be a predecessor of the phi's block");
994 if (PN.getNumIncomingValues() != 2)
995 return {nullptr, nullptr};
996 unsigned StartIdx = PN.getIncomingBlock(0) == LoopPred ? 0 : 1;
997 return {PN.getIncomingValue(StartIdx), PN.getIncomingValue(1 - StartIdx)};
998}
999
1000MonotonicInfo State::getMonotonicityInfo(PHINode &PN, Value *Step) {
1001 MonotonicInfo Info;
1002 const APInt *StepOffset = nullptr;
1003 if (match(Step, m_c_Add(m_Specific(&PN), m_APInt(StepOffset)))) {
1004 Info.Decreasing = StepOffset->isNegative();
1005 const auto *Add = cast<OverflowingBinaryOperator>(Step);
1006 Info.Unsigned = !Info.Decreasing && Add->hasNoUnsignedWrap();
1007 Info.Signed = Add->hasNoSignedWrap();
1008 } else if (const auto *GEP = dyn_cast<GEPOperator>(Step)) {
1009 // TODO: Handle the non-increasing direction, which needs a nusw GEP with a
1010 // negative constant offset.
1011 const DataLayout &DL = PN.getDataLayout();
1012 APInt GEPOffset(DL.getIndexTypeSizeInBits(GEP->getType()), 0);
1013 Info.Unsigned = GEP->getPointerOperand() == &PN &&
1014 (GEP->hasNoUnsignedWrap() ||
1015 ((GEP->hasNoUnsignedSignedWrap() &&
1016 GEP->accumulateConstantOffset(DL, GEPOffset) &&
1017 !GEPOffset.isNegative())));
1018 }
1019
1020 // Forming the SCEV of a phi is expensive, so only consult it for a PN + C
1021 // step whose no-wrap flags prove nothing.
1022 if (Info.Unsigned || Info.Signed || !StepOffset)
1023 return Info;
1024
1025 const auto *AR = dyn_cast<SCEVAddRecExpr>(SE.getSCEV(&PN));
1026 if (!AR)
1027 return Info;
1031 auto IsMonotonic = [&](CmpInst::Predicate Pred) {
1032 return SE.getMonotonicPredicateType(AR, Pred) == Expected;
1033 };
1034 Info.Signed = IsMonotonic(CmpInst::ICMP_SGT);
1035 Info.Unsigned = !Info.Decreasing && IsMonotonic(CmpInst::ICMP_UGT);
1036 return Info;
1037}
1038
1039void State::addBoundsForHeaderInductions(BasicBlock &BB) {
1040 Loop *L = LI.getLoopFor(&BB);
1041 if (!L || L->getHeader() != &BB)
1042 return;
1043 BasicBlock *LoopPred = L->getLoopPredecessor();
1044 if (!LoopPred)
1045 return;
1046
1047 DomTreeNode *DTN = DT.getNode(&BB);
1048 for (PHINode &PN : BB.phis()) {
1049 if (!PN.getType()->isIntegerTy() && !PN.getType()->isPointerTy())
1050 continue;
1051
1052 auto [Start, Step] = getStartAndBackedgeValue(PN, LoopPred);
1053 if (!Start)
1054 continue;
1055
1056 MonotonicInfo Info = getMonotonicityInfo(PN, Step);
1057 // Every variable in the unsigned system already has a `V >= 0` row, so a
1058 // zero start value would just duplicate it.
1059 if (match(Start, m_Zero()))
1060 Info.Unsigned = false;
1061 if (!Info.Unsigned && !Info.Signed)
1062 continue;
1063
1064 // A non-decreasing induction cannot step below its start value, and a
1065 // non-increasing one cannot step above it.
1066 Value *LHS = &PN, *RHS = Start;
1067 if (Info.Decreasing)
1068 std::swap(LHS, RHS);
1069 CmpPredicate Pred(Info.Unsigned ? CmpInst::ICMP_UGE : CmpInst::ICMP_SGE,
1070 /*HasSameSign=*/Info.Unsigned && Info.Signed);
1071 WorkList.push_back(FactOrCheck::getConditionFact(DTN, Pred, LHS, RHS));
1072 }
1073}
1074
1075void State::addInfoForInductions(BasicBlock &BB) {
1076 auto *L = LI.getLoopFor(&BB);
1077 if (!L)
1078 return;
1079
1080 BasicBlock *Header = L->getHeader();
1081 BasicBlock *Latch = L->getLoopLatch();
1082 if (Header != &BB && Latch != &BB)
1083 return;
1084
1085 // A is either a phi or a post-increment PN + C with constant step. For the
1086 // latter, extract the constant IncStep.
1087 Value *A;
1088 Value *B;
1089 PHINode *PN = nullptr;
1090 const APInt *IncStep = nullptr;
1091 CmpPredicate Pred;
1092 auto IndValue =
1093 m_Value(A, m_CombineOr(m_Phi(PN), m_c_Add(m_Phi(PN), m_APInt(IncStep))));
1094
1095 if (!match(BB.getTerminator(),
1096 m_Br(m_c_ICmp(Pred, IndValue, m_Value(B)), m_Value(), m_Value())))
1097 return;
1098 if (PN->getParent() != Header || PN->getNumIncomingValues() != 2 ||
1099 !SE.isSCEVable(PN->getType()))
1100 return;
1101
1102 // For latch conditions, we need to inject the condition that holds for the
1103 // next iteration into the header. We limit to post-inc conditions, for which
1104 // an original PN + Step != B condition results in a PN < B constraint in the
1105 // header, which also holds for the next loop iteration. This would no longer
1106 // be correct if the post-inc handling would inject a more precise PN + Step <
1107 // B constraint instead.
1108 if (&BB == Latch && !IncStep)
1109 return;
1110
1111 BasicBlock *InLoopSucc = nullptr;
1112 if (Pred == CmpInst::ICMP_NE)
1113 InLoopSucc = cast<CondBrInst>(BB.getTerminator())->getSuccessor(0);
1114 else if (Pred == CmpInst::ICMP_EQ)
1115 InLoopSucc = cast<CondBrInst>(BB.getTerminator())->getSuccessor(1);
1116 else
1117 return;
1118
1119 if (!L->contains(InLoopSucc) || !L->isLoopExiting(&BB) || InLoopSucc == &BB)
1120 return;
1121
1122 BasicBlock *LoopPred = L->getLoopPredecessor();
1123 if (!LoopPred || !L->isLoopInvariant(B))
1124 return;
1125
1126 auto [StartValue, Backedge] = getStartAndBackedgeValue(*PN, LoopPred);
1127 const APInt *StepOffset = nullptr;
1128 const SCEV *StartSCEV = nullptr;
1129 if (match(Backedge, m_c_Add(m_Specific(PN), m_APInt(StepOffset)))) {
1130 if (StepOffset->isZero())
1131 return;
1132 } else {
1133 const SCEV *Expr = SE.getSCEV(PN);
1134 if (!match(Expr,
1135 m_scev_AffineAddRec(m_SCEV(StartSCEV), m_scev_APInt(StepOffset),
1136 m_SpecificLoop(L))))
1137 return;
1138 }
1139
1140 DomTreeNode *DTN = DT.getNode(InLoopSucc);
1141
1142 // If we looked through `PN + C`, only derive facts when that add is
1143 // really the induction's post-increment.
1144 if (IncStep && (*IncStep != *StepOffset || StepOffset->isNegative()))
1145 return;
1146
1147 MonotonicInfo Info = getMonotonicityInfo(*PN, Backedge);
1148
1149 // Handle negative steps.
1150 if (StepOffset->isNegative()) {
1151 // TODO: Extend to allow steps > -1.
1152 if (!(-*StepOffset).isOne())
1153 return;
1154
1155 // AR may wrap.
1156 // Add StartValue >= PN conditional on B <= StartValue which guarantees that
1157 // the loop exits before wrapping with a step of -1.
1158 WorkList.push_back(FactOrCheck::getConditionFact(
1159 DTN, CmpInst::ICMP_UGE, StartValue, PN,
1160 ConditionTy(CmpInst::ICMP_ULE, B, StartValue)));
1161 if (!(Info.Decreasing && Info.Signed))
1162 WorkList.push_back(FactOrCheck::getConditionFact(
1163 DTN, CmpInst::ICMP_SGE, StartValue, PN,
1164 ConditionTy(CmpInst::ICMP_SLE, B, StartValue)));
1165 // Add PN > B conditional on B <= StartValue which guarantees that the loop
1166 // exits when reaching B with a step of -1.
1167 WorkList.push_back(FactOrCheck::getConditionFact(
1168 DTN, CmpInst::ICMP_UGT, PN, B,
1169 ConditionTy(CmpInst::ICMP_ULE, B, StartValue)));
1170 WorkList.push_back(FactOrCheck::getConditionFact(
1171 DTN, CmpInst::ICMP_SGT, PN, B,
1172 ConditionTy(CmpInst::ICMP_SLE, B, StartValue)));
1173 return;
1174 }
1175
1176 // Make sure AR either steps by 1 or that the value we compare against is a
1177 // GEP based on the same start value and all offsets are a multiple of the
1178 // step size, to guarantee that the induction will reach the value.
1179 if (StepOffset->isZero() || StepOffset->isNegative())
1180 return;
1181
1182 if (!StepOffset->isOne()) {
1183 // Check whether B-Start is known to be a multiple of StepOffset.
1184 if (!StartSCEV)
1185 StartSCEV = SE.getSCEV(StartValue);
1186 const SCEV *BMinusStart = SE.getMinusSCEV(SE.getSCEV(B), StartSCEV);
1187 if (isa<SCEVCouldNotCompute>(BMinusStart) ||
1188 !SE.getConstantMultiple(BMinusStart).urem(*StepOffset).isZero())
1189 return;
1190 }
1191
1192 Value *LowerBound = StartValue;
1193 bool LowerBoundNUW = true, LowerBoundNSW = true;
1194 if (IncStep) {
1195 auto *StartC = dyn_cast<ConstantInt>(StartValue);
1196 if (!StartC)
1197 return;
1198 bool UOverflow = false, SOverflow = false;
1199 APInt Sum = StartC->getValue().uadd_ov(*StepOffset, UOverflow);
1200 (void)StartC->getValue().sadd_ov(*StepOffset, SOverflow);
1201 LowerBound = ConstantInt::get(StartValue->getType(), Sum);
1202 LowerBoundNUW = !UOverflow;
1203 LowerBoundNSW = !SOverflow;
1204 }
1205
1206 // AR may wrap. Add PN >= StartValue conditional on LowerBound <= B, which
1207 // guarantees that the loop exits before wrapping in combination with the
1208 // restrictions on B and the step above.
1209 ConditionTy StartBeforeBoundULE = {CmpInst::ICMP_ULE, LowerBound, B};
1210 ConditionTy StartBeforeBoundSLE = {CmpInst::ICMP_SLE, LowerBound, B};
1211 if (!Info.Unsigned && LowerBoundNUW)
1212 WorkList.push_back(FactOrCheck::getConditionFact(
1213 DTN, CmpInst::ICMP_UGE, PN, StartValue, StartBeforeBoundULE));
1214 if (!Info.Signed && LowerBoundNSW)
1215 WorkList.push_back(FactOrCheck::getConditionFact(
1216 DTN, CmpInst::ICMP_SGE, PN, StartValue, StartBeforeBoundSLE));
1217
1218 if (LowerBoundNSW)
1219 WorkList.push_back(FactOrCheck::getConditionFact(DTN, CmpInst::ICMP_SLT, PN,
1220 B, StartBeforeBoundSLE));
1221
1222 if (!LowerBoundNUW)
1223 return;
1224
1225 WorkList.push_back(FactOrCheck::getConditionFact(DTN, CmpInst::ICMP_ULT, PN,
1226 B, StartBeforeBoundULE));
1227
1228 // Try to add condition from the header or latch to the dedicated exit
1229 // blocks. When exiting either with EQ or NE, we know that the induction value
1230 // must be u<= B, as other exits may only exit earlier.
1231 assert(!StepOffset->isNegative() && "induction must be increasing");
1232 assert((Pred == CmpInst::ICMP_EQ || Pred == CmpInst::ICMP_NE) &&
1233 "unsupported predicate");
1235 L->getExitBlocks(ExitBBs);
1236 for (BasicBlock *EB : ExitBBs) {
1237 // Bail out on non-dedicated exits.
1238 if (DT.dominates(&BB, EB)) {
1239 WorkList.emplace_back(FactOrCheck::getConditionFact(
1240 DT.getNode(EB), CmpInst::ICMP_ULE, A, B, StartBeforeBoundULE));
1241 }
1242 }
1243}
1244
1246 uint64_t AccessSize,
1247 CmpPredicate &Pred, Value *&A,
1248 Value *&B, const DataLayout &DL,
1249 const TargetLibraryInfo &TLI) {
1251 if (!Offset.NW.hasNoUnsignedWrap())
1252 return false;
1253
1254 if (Offset.VariableOffsets.size() != 1)
1255 return false;
1256
1257 uint64_t BitWidth = Offset.ConstantOffset.getBitWidth();
1258 auto &[Index, Scale] = Offset.VariableOffsets.front();
1259 // Bail out on non-canonical GEPs.
1260 if (Index->getType()->getScalarSizeInBits() != BitWidth)
1261 return false;
1262
1263 ObjectSizeOpts Opts;
1264 // Workaround for gep inbounds, ptr null, idx.
1265 Opts.NullIsUnknownSize = true;
1266 // Be conservative since we are not clear on whether an out of bounds access
1267 // to the padding is UB or not.
1268 Opts.RoundToAlign = true;
1269 std::optional<TypeSize> Size =
1270 getBaseObjectSize(Offset.BasePtr, DL, &TLI, Opts);
1271 if (!Size || Size->isScalable())
1272 return false;
1273
1274 // Index * Scale + ConstOffset + AccessSize <= AllocSize
1275 // With nuw flag, we know that the index addition doesn't have unsigned wrap.
1276 // If (AllocSize - (ConstOffset + AccessSize)) wraps around, there is no valid
1277 // value for Index.
1278 APInt MaxIndex = (APInt(BitWidth, Size->getFixedValue() - AccessSize,
1279 /*isSigned=*/false, /*implicitTrunc=*/true) -
1280 Offset.ConstantOffset)
1281 .udiv(Scale);
1282 Pred = ICmpInst::ICMP_ULE;
1283 A = Index;
1284 B = ConstantInt::get(Index->getType(), MaxIndex);
1285 return true;
1286}
1287
1288void State::addInfoFor(BasicBlock &BB) {
1289 addBoundsForHeaderInductions(BB);
1290 addInfoForInductions(BB);
1291 auto &DL = BB.getDataLayout();
1292
1293 Value *A, *B;
1294 CmpPredicate Pred;
1295 // True as long as the current instruction is guaranteed to execute.
1296 bool GuaranteedToExecute = true;
1297 // Queue conditions and assumes.
1298 for (Instruction &I : BB) {
1299 if (match(&I, m_ICmpLike(Pred, m_Value(), m_Value()))) {
1300 for (Use &U : I.uses()) {
1301 auto *UserI = getContextInstForUse(U);
1302 auto *DTN = DT.getNode(UserI->getParent());
1303 if (!DTN)
1304 continue;
1305 WorkList.push_back(FactOrCheck::getCheck(DTN, &U));
1306 }
1307 continue;
1308 }
1309
1310 auto AddFactFromMemoryAccess = [&](Value *Ptr, Type *AccessType) {
1311 auto *GEP = dyn_cast<GetElementPtrInst>(Ptr);
1312 if (!GEP)
1313 return;
1314 TypeSize AccessSize = DL.getTypeStoreSize(AccessType);
1315 if (!AccessSize.isFixed())
1316 return;
1317 if (GuaranteedToExecute) {
1319 Pred, A, B, DL, TLI)) {
1320 // The memory access is guaranteed to execute when BB is entered,
1321 // hence the constraint holds on entry to BB.
1322 WorkList.emplace_back(FactOrCheck::getConditionFact(
1323 DT.getNode(I.getParent()), Pred, A, B));
1324 }
1325 } else {
1326 WorkList.emplace_back(
1327 FactOrCheck::getInstFact(DT.getNode(I.getParent()), &I));
1328 }
1329 };
1330
1331 if (auto *LI = dyn_cast<LoadInst>(&I)) {
1332 if (!LI->isVolatile())
1333 AddFactFromMemoryAccess(LI->getPointerOperand(), LI->getAccessType());
1334 }
1335 if (auto *SI = dyn_cast<StoreInst>(&I)) {
1336 if (!SI->isVolatile())
1337 AddFactFromMemoryAccess(SI->getPointerOperand(), SI->getAccessType());
1338 }
1339
1340 auto *II = dyn_cast<IntrinsicInst>(&I);
1341 Intrinsic::ID ID = II ? II->getIntrinsicID() : Intrinsic::not_intrinsic;
1342 switch (ID) {
1343 case Intrinsic::assume: {
1344 if (!match(I.getOperand(0), m_ICmpLike(Pred, m_Value(A), m_Value(B))))
1345 break;
1346 if (GuaranteedToExecute) {
1347 // The assume is guaranteed to execute when BB is entered, hence Cond
1348 // holds on entry to BB.
1349 WorkList.emplace_back(FactOrCheck::getConditionFact(
1350 DT.getNode(I.getParent()), Pred, A, B));
1351 } else {
1352 WorkList.emplace_back(
1353 FactOrCheck::getInstFact(DT.getNode(I.getParent()), &I));
1354 }
1355 break;
1356 }
1357 // Enqueue ssub_with_overflow for simplification.
1358 case Intrinsic::ssub_with_overflow:
1359 case Intrinsic::ucmp:
1360 case Intrinsic::scmp:
1361 WorkList.push_back(
1362 FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
1363 break;
1364 // Enqueue the intrinsics to add extra info.
1365 case Intrinsic::umin:
1366 case Intrinsic::umax:
1367 case Intrinsic::smin:
1368 case Intrinsic::smax:
1369 // TODO: handle llvm.abs as well
1370 WorkList.push_back(
1371 FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
1372 [[fallthrough]];
1373 case Intrinsic::uadd_sat:
1374 case Intrinsic::usub_sat:
1375 // TODO: Check if it is possible to instead only added the min/max facts
1376 // when simplifying uses of the min/max intrinsics.
1378 break;
1379 [[fallthrough]];
1380 case Intrinsic::abs:
1381 WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I));
1382 break;
1383 }
1384
1385 // Add facts from unsigned division, remainder and logical shift right, and
1386 // from signed remainder.
1387 // urem x, n: result < n and result <= x
1388 // udiv x, n: result <= x
1389 // lshr x, n: result <= x
1390 // srem x, n: result >= 0 and result <= x, if x >= 0
1391 // result < n, if n > 0
1392 if (auto *BO = dyn_cast<BinaryOperator>(&I)) {
1393 if ((BO->getOpcode() == Instruction::URem ||
1394 BO->getOpcode() == Instruction::UDiv ||
1395 BO->getOpcode() == Instruction::LShr ||
1396 BO->getOpcode() == Instruction::SRem) &&
1398 WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), BO));
1399 }
1400
1401 GuaranteedToExecute &= isGuaranteedToTransferExecutionToSuccessor(&I);
1402 }
1403
1404 if (auto *Switch = dyn_cast<SwitchInst>(BB.getTerminator())) {
1405 for (auto &Case : Switch->cases()) {
1406 BasicBlock *Succ = Case.getCaseSuccessor();
1407 Value *V = Case.getCaseValue();
1408 if (!canAddSuccessor(BB, Succ))
1409 continue;
1410 WorkList.emplace_back(FactOrCheck::getConditionFact(
1411 DT.getNode(Succ), CmpInst::ICMP_EQ, Switch->getCondition(), V));
1412 }
1413 return;
1414 }
1415
1416 auto *Br = dyn_cast<CondBrInst>(BB.getTerminator());
1417 if (!Br)
1418 return;
1419
1420 Value *Cond = Br->getCondition();
1421
1422 // If the condition is a chain of ORs/AND and the successor only has the
1423 // current block as predecessor, queue conditions for the successor.
1424 Value *Op0, *Op1;
1425 if (match(Cond, m_LogicalOr(m_Value(Op0), m_Value(Op1))) ||
1426 match(Cond, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) {
1427 bool IsOr = match(Cond, m_LogicalOr());
1428 bool IsAnd = match(Cond, m_LogicalAnd());
1429 // If there's a select that matches both AND and OR, we need to commit to
1430 // one of the options. Arbitrarily pick OR.
1431 if (IsOr && IsAnd)
1432 IsAnd = false;
1433
1434 BasicBlock *Successor = Br->getSuccessor(IsOr ? 1 : 0);
1435 if (canAddSuccessor(BB, Successor)) {
1436 SmallVector<Value *> CondWorkList;
1437 SmallPtrSet<Value *, 8> SeenCond;
1438 auto QueueValue = [&CondWorkList, &SeenCond](Value *V) {
1439 if (SeenCond.insert(V).second)
1440 CondWorkList.push_back(V);
1441 };
1442 QueueValue(Op1);
1443 QueueValue(Op0);
1444 while (!CondWorkList.empty()) {
1445 Value *Cur = CondWorkList.pop_back_val();
1446 if (match(Cur, m_ICmpLike(Pred, m_Value(A), m_Value(B)))) {
1447 WorkList.emplace_back(FactOrCheck::getConditionFact(
1448 DT.getNode(Successor),
1449 IsOr ? CmpPredicate::getInverse(Pred) : Pred, A, B));
1450 continue;
1451 }
1452 if (IsOr && match(Cur, m_LogicalOr(m_Value(Op0), m_Value(Op1)))) {
1453 QueueValue(Op1);
1454 QueueValue(Op0);
1455 continue;
1456 }
1457 if (IsAnd && match(Cur, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) {
1458 QueueValue(Op1);
1459 QueueValue(Op0);
1460 continue;
1461 }
1462 }
1463 }
1464 return;
1465 }
1466
1467 if (!match(Br->getCondition(), m_ICmpLike(Pred, m_Value(A), m_Value(B))))
1468 return;
1469 if (canAddSuccessor(BB, Br->getSuccessor(0)))
1470 WorkList.emplace_back(FactOrCheck::getConditionFact(
1471 DT.getNode(Br->getSuccessor(0)), Pred, A, B));
1472 if (canAddSuccessor(BB, Br->getSuccessor(1)))
1473 WorkList.emplace_back(FactOrCheck::getConditionFact(
1474 DT.getNode(Br->getSuccessor(1)), CmpPredicate::getInverse(Pred), A, B));
1475}
1476
1477#ifndef NDEBUG
1479 Value *LHS, Value *RHS) {
1480 OS << "icmp " << Pred << ' ';
1481 LHS->printAsOperand(OS, /*PrintType=*/true);
1482 OS << ", ";
1483 RHS->printAsOperand(OS, /*PrintType=*/false);
1484}
1485#endif
1486
1487namespace {
1488/// Helper to keep track of a condition and if it should be treated as negated
1489/// for reproducer construction.
1490/// Pred == Predicate::BAD_ICMP_PREDICATE indicates that this entry is a
1491/// placeholder to keep the ReproducerCondStack in sync with DFSInStack.
1492struct ReproducerEntry {
1493 ICmpInst::Predicate Pred;
1494 Value *LHS;
1495 Value *RHS;
1496
1497 ReproducerEntry(ICmpInst::Predicate Pred, Value *LHS, Value *RHS)
1498 : Pred(Pred), LHS(LHS), RHS(RHS) {}
1499};
1500} // namespace
1501
1502/// Helper function to generate a reproducer function for simplifying \p Cond.
1503/// The reproducer function contains a series of @llvm.assume calls, one for
1504/// each condition in \p Stack. For each condition, the operand instruction are
1505/// cloned until we reach operands that have an entry in \p Value2Index. Those
1506/// will then be added as function arguments. \p DT is used to order cloned
1507/// instructions. The reproducer function will get added to \p M, if it is
1508/// non-null. Otherwise no reproducer function is generated.
1509static void generateReproducer(Instruction *Cond, bool IsSigned, Module *M,
1511 ConstraintInfo &Info, DominatorTree &DT) {
1512 if (!M)
1513 return;
1514
1515 LLVMContext &Ctx = Cond->getContext();
1516
1517 LLVM_DEBUG(dbgs() << "Creating reproducer for " << *Cond << "\n");
1518
1519 ValueToValueMapTy Old2New;
1522 // Traverse Cond and its operands recursively until we reach a value that's in
1523 // Value2Index or not an instruction, or not a operation that
1524 // ConstraintElimination can decompose. Such values will be considered as
1525 // external inputs to the reproducer, they are collected and added as function
1526 // arguments later.
1527 auto CollectArguments = [&](ArrayRef<Value *> Ops, bool IsSigned) {
1528 auto &Value2Index = Info.getValue2Index(IsSigned);
1529 SmallVector<Value *, 4> WorkList(Ops);
1530 while (!WorkList.empty()) {
1531 Value *V = WorkList.pop_back_val();
1532 if (!Seen.insert(V).second)
1533 continue;
1534 if (Old2New.find(V) != Old2New.end())
1535 continue;
1536 if (isa<Constant>(V))
1537 continue;
1538
1539 auto *I = dyn_cast<Instruction>(V);
1540 if (Value2Index.contains(V) || !I ||
1542 Old2New[V] = V;
1543 Args.push_back(V);
1544 LLVM_DEBUG(dbgs() << " found external input " << *V << "\n");
1545 } else {
1546 append_range(WorkList, I->operands());
1547 }
1548 }
1549 };
1550
1551 for (auto &Entry : Stack)
1552 if (Entry.Pred != ICmpInst::BAD_ICMP_PREDICATE)
1553 CollectArguments({Entry.LHS, Entry.RHS}, ICmpInst::isSigned(Entry.Pred));
1554 CollectArguments(Cond, IsSigned);
1555
1556 SmallVector<Type *> ParamTys;
1557 for (auto *P : Args)
1558 ParamTys.push_back(P->getType());
1559
1560 FunctionType *FTy = FunctionType::get(Cond->getType(), ParamTys,
1561 /*isVarArg=*/false);
1563 Cond->getModule()->getName() +
1564 Cond->getFunction()->getName() + "repro",
1565 M);
1566 // Add arguments to the reproducer function for each external value collected.
1567 for (unsigned I = 0; I < Args.size(); ++I) {
1568 F->getArg(I)->setName(Args[I]->getName());
1569 Old2New[Args[I]] = F->getArg(I);
1570 }
1571
1572 BasicBlock *Entry = BasicBlock::Create(Ctx, "entry", F);
1573 IRBuilder<> Builder(Entry);
1574 Builder.CreateRet(Builder.getTrue());
1575 Builder.SetInsertPoint(Entry->getTerminator());
1576
1577 // Clone instructions in \p Ops and their operands recursively until reaching
1578 // an value in Value2Index (external input to the reproducer). Update Old2New
1579 // mapping for the original and cloned instructions. Sort instructions to
1580 // clone by dominance, then insert the cloned instructions in the function.
1581 auto CloneInstructions = [&](ArrayRef<Value *> Ops, bool IsSigned) {
1582 SmallVector<Value *, 4> WorkList(Ops);
1584 auto &Value2Index = Info.getValue2Index(IsSigned);
1585 while (!WorkList.empty()) {
1586 Value *V = WorkList.pop_back_val();
1587 if (Old2New.find(V) != Old2New.end())
1588 continue;
1589
1590 auto *I = dyn_cast<Instruction>(V);
1591 if (!Value2Index.contains(V) && I) {
1592 Old2New[V] = nullptr;
1593 ToClone.push_back(I);
1594 append_range(WorkList, I->operands());
1595 }
1596 }
1597
1598 sort(ToClone,
1599 [&DT](Instruction *A, Instruction *B) { return DT.dominates(A, B); });
1600 for (Instruction *I : ToClone) {
1601 Instruction *Cloned = I->clone();
1602 Old2New[I] = Cloned;
1603 Old2New[I]->setName(I->getName());
1604 Cloned->insertBefore(Builder.GetInsertPoint());
1606 Cloned->setDebugLoc({});
1607 }
1608 };
1609
1610 // Materialize the assumptions for the reproducer using the entries in Stack.
1611 // That is, first clone the operands of the condition recursively until we
1612 // reach an external input to the reproducer and add them to the reproducer
1613 // function. Then add an ICmp for the condition (with the inverse predicate if
1614 // the entry is negated) and an assert using the ICmp.
1615 for (auto &Entry : Stack) {
1616 if (Entry.Pred == ICmpInst::BAD_ICMP_PREDICATE)
1617 continue;
1618
1619 LLVM_DEBUG(dbgs() << " Materializing assumption ";
1620 dumpUnpackedICmp(dbgs(), Entry.Pred, Entry.LHS, Entry.RHS);
1621 dbgs() << "\n");
1622 CloneInstructions({Entry.LHS, Entry.RHS}, CmpInst::isSigned(Entry.Pred));
1623
1624 auto *Cmp = Builder.CreateICmp(Entry.Pred, Entry.LHS, Entry.RHS);
1625 Builder.CreateAssumption(Cmp);
1626 }
1627
1628 // Finally, clone the condition to reproduce and remap instruction operands in
1629 // the reproducer using Old2New.
1630 CloneInstructions(Cond, IsSigned);
1631 Entry->getTerminator()->setOperand(0, Cond);
1632 remapInstructionsInBlocks({Entry}, Old2New);
1633
1634 assert(!verifyFunction(*F, &dbgs()));
1635}
1636
1637static std::optional<bool> checkCondition(CmpInst::Predicate Pred, Value *A,
1638 Value *B, Instruction *CheckInst,
1639 ConstraintInfo &Info) {
1640 LLVM_DEBUG(dbgs() << "Checking " << *CheckInst << "\n");
1641
1642 auto TryWithConstraint = [&](const ConstraintTy &R) -> std::optional<bool> {
1643 if (R.empty()) {
1644 LLVM_DEBUG(dbgs() << " failed to decompose condition\n");
1645 return std::nullopt;
1646 }
1647
1648 auto &CSToUse = Info.getCS(R.IsSigned);
1649 if (auto ImpliedCondition = R.isImpliedBy(CSToUse)) {
1650 if (!DebugCounter::shouldExecute(EliminatedCounter))
1651 return std::nullopt;
1652 LLVM_DEBUG({
1653 dbgs() << "Condition ";
1655 *ImpliedCondition ? Pred
1657 A, B);
1658 dbgs() << " implied by dominating constraints\n";
1659 CSToUse.dump();
1660 });
1661 return ImpliedCondition;
1662 }
1663 return std::nullopt;
1664 };
1665
1666 auto R = Info.getConstraintForSolving(Pred, A, B);
1667 if (auto ImpliedCondition = TryWithConstraint(R))
1668 return ImpliedCondition;
1669
1670 // For non-negative operands unsigned queries can also be checked against the
1671 // signed system.
1672 if (CmpInst::isUnsigned(Pred) && A->getType()->isIntegerTy()) {
1673 SmallVector<Value *> NewVariables;
1674 auto SR = Info.getConstraint(ICmpInst::getSignedPredicate(Pred), A, B,
1675 NewVariables);
1676 if (NewVariables.empty() && !SR.empty() && Info.isKnownNonNegative(A) &&
1677 Info.isKnownNonNegative(B))
1678 if (auto ImpliedCondition = TryWithConstraint(SR))
1679 return ImpliedCondition;
1680 }
1681
1682 // Additionally, query the signed system for eq/ne predicates if we know about
1683 // A or B.
1684 if (CmpInst::isEquality(Pred)) {
1685 const auto &Value2Index = Info.getValue2Index(/*Signed=*/true);
1686 if (!Value2Index.contains(A) && !Value2Index.contains(B))
1687 return std::nullopt;
1688
1689 SmallVector<Value *> NewVariables;
1690 auto SR = Info.getConstraint(Pred, A, B, NewVariables,
1691 /*ForceSignedSystem=*/true);
1692 if (NewVariables.empty())
1693 if (auto ImpliedCondition = TryWithConstraint(SR))
1694 return ImpliedCondition;
1695 }
1696 return std::nullopt;
1697}
1698
1700 CmpPredicate Pred, Value *A, Value *B, Instruction *CheckInst,
1701 ConstraintInfo &Info, unsigned NumIn, unsigned NumOut,
1702 Instruction *ContextInst, Module *ReproducerModule,
1703 ArrayRef<ReproducerEntry> ReproducerCondStack, DominatorTree &DT,
1705 auto ReplaceCmpWithConstant = [&](Instruction *CheckInst, bool IsTrue) {
1706 generateReproducer(CheckInst, ICmpInst::isSigned(Pred), ReproducerModule,
1707 ReproducerCondStack, Info, DT);
1708 Constant *ConstantC = ConstantInt::getBool(
1709 CmpInst::makeCmpResultType(CheckInst->getType()), IsTrue);
1710 bool Changed = CheckInst->replaceUsesWithIf(ConstantC, [&](Use &U) {
1711 auto *UserI = getContextInstForUse(U);
1712 auto *DTN = DT.getNode(UserI->getParent());
1713 if (!DTN || DTN->getDFSNumIn() < NumIn || DTN->getDFSNumOut() > NumOut)
1714 return false;
1715 if (UserI->getParent() == ContextInst->getParent() &&
1716 UserI->comesBefore(ContextInst))
1717 return false;
1718
1719 // Conditions in an assume trivially simplify to true. Skip uses
1720 // in assume calls to not destroy the available information.
1721 auto *II = dyn_cast<IntrinsicInst>(U.getUser());
1722 return !II || II->getIntrinsicID() != Intrinsic::assume;
1723 });
1724 NumCondsRemoved++;
1725
1726 // Update the debug value records that satisfy the same condition used
1727 // in replaceUsesWithIf.
1729 findDbgUsers(CheckInst, DVRUsers);
1730
1731 for (auto *DVR : DVRUsers) {
1732 auto *DTN = DT.getNode(DVR->getParent());
1733 if (!DTN || DTN->getDFSNumIn() < NumIn || DTN->getDFSNumOut() > NumOut)
1734 continue;
1735
1736 auto *MarkedI = DVR->getInstruction();
1737 if (MarkedI->getParent() == ContextInst->getParent() &&
1738 MarkedI->comesBefore(ContextInst))
1739 continue;
1740
1741 DVR->replaceVariableLocationOp(CheckInst, ConstantC);
1742 }
1743
1744 if (CheckInst->use_empty())
1745 ToRemove.push_back(CheckInst);
1746
1747 return Changed;
1748 };
1749
1750 if (auto ImpliedCondition = checkCondition(Pred, A, B, CheckInst, Info))
1751 return ReplaceCmpWithConstant(CheckInst, *ImpliedCondition);
1752
1753 // When the predicate is samesign and unsigned, we can also make use of the
1754 // signed predicate information.
1755 if (Pred.hasSameSign() && ICmpInst::isUnsigned(Pred))
1756 if (auto ImpliedCondition = checkCondition(
1757 ICmpInst::getSignedPredicate(Pred), A, B, CheckInst, Info))
1758 return ReplaceCmpWithConstant(CheckInst, *ImpliedCondition);
1759
1760 return false;
1761}
1762
1763static bool checkAndReplaceMinMax(MinMaxIntrinsic *MinMax, ConstraintInfo &Info,
1765 auto ReplaceMinMaxWithOperand = [&](MinMaxIntrinsic *MinMax, bool UseLHS) {
1766 // TODO: generate reproducer for min/max.
1767 MinMax->replaceAllUsesWith(MinMax->getOperand(UseLHS ? 0 : 1));
1768 ToRemove.push_back(MinMax);
1769 return true;
1770 };
1771
1772 ICmpInst::Predicate Pred =
1773 ICmpInst::getNonStrictPredicate(MinMax->getPredicate());
1774 if (auto ImpliedCondition = checkCondition(
1775 Pred, MinMax->getOperand(0), MinMax->getOperand(1), MinMax, Info))
1776 return ReplaceMinMaxWithOperand(MinMax, *ImpliedCondition);
1777 if (auto ImpliedCondition = checkCondition(
1778 Pred, MinMax->getOperand(1), MinMax->getOperand(0), MinMax, Info))
1779 return ReplaceMinMaxWithOperand(MinMax, !*ImpliedCondition);
1780 return false;
1781}
1782
1783static bool checkAndReplaceCmp(CmpIntrinsic *I, ConstraintInfo &Info,
1785 Value *LHS = I->getOperand(0);
1786 Value *RHS = I->getOperand(1);
1787 if (checkCondition(I->getGTPredicate(), LHS, RHS, I, Info).value_or(false)) {
1788 I->replaceAllUsesWith(ConstantInt::get(I->getType(), 1));
1789 ToRemove.push_back(I);
1790 return true;
1791 }
1792 if (checkCondition(I->getLTPredicate(), LHS, RHS, I, Info).value_or(false)) {
1793 I->replaceAllUsesWith(ConstantInt::getSigned(I->getType(), -1));
1794 ToRemove.push_back(I);
1795 return true;
1796 }
1797 if (checkCondition(ICmpInst::ICMP_EQ, LHS, RHS, I, Info).value_or(false)) {
1798 I->replaceAllUsesWith(ConstantInt::get(I->getType(), 0));
1799 ToRemove.push_back(I);
1800 return true;
1801 }
1802 return false;
1803}
1804
1805static void
1806removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info,
1807 Module *ReproducerModule,
1808 SmallVectorImpl<ReproducerEntry> &ReproducerCondStack,
1809 SmallVectorImpl<StackEntry> &DFSInStack) {
1810 Info.popLastConstraint(E.IsSigned);
1811 // Remove variables in the system that went out of scope.
1812 auto &Mapping = Info.getValue2Index(E.IsSigned);
1813 for (Value *V : E.ValuesToRelease)
1814 Mapping.erase(V);
1815 Info.popLastNVariables(E.IsSigned, E.ValuesToRelease.size());
1816 DFSInStack.pop_back();
1817 if (ReproducerModule)
1818 ReproducerCondStack.pop_back();
1819}
1820
1821/// Check if either the first condition of an AND or OR is implied by the
1822/// (negated in case of OR) second condition or vice versa.
1824 FactOrCheck &CB, ConstraintInfo &Info, Module *ReproducerModule,
1825 SmallVectorImpl<ReproducerEntry> &ReproducerCondStack,
1826 SmallVectorImpl<StackEntry> &DFSInStack,
1828 Instruction *JoinOp = CB.getContextInst();
1829 if (JoinOp->use_empty())
1830 return false;
1831
1832 Instruction *CmpToCheck = cast<Instruction>(CB.getInstructionToSimplify());
1833 unsigned OtherOpIdx = JoinOp->getOperand(0) == CmpToCheck ? 1 : 0;
1834
1835 // Don't try to simplify the first condition of a select by the second, as
1836 // this may make the select more poisonous than the original one.
1837 // TODO: check if the first operand may be poison.
1838 if (OtherOpIdx != 0 && isa<SelectInst>(JoinOp))
1839 return false;
1840
1841 unsigned OldSize = DFSInStack.size();
1842 llvm::scope_exit InfoRestorer([&]() {
1843 // Remove entries again.
1844 while (OldSize < DFSInStack.size()) {
1845 StackEntry E = DFSInStack.back();
1846 removeEntryFromStack(E, Info, ReproducerModule, ReproducerCondStack,
1847 DFSInStack);
1848 }
1849 });
1850 bool IsOr = match(JoinOp, m_LogicalOr());
1851 SmallVector<Value *, 4> Worklist({JoinOp->getOperand(OtherOpIdx)});
1852 // Do a traversal of the AND/OR tree to add facts from leaf compares.
1853 while (!Worklist.empty()) {
1854 Value *Val = Worklist.pop_back_val();
1855 Value *LHS, *RHS;
1856 CmpPredicate Pred;
1857 if (match(Val, m_ICmpLike(Pred, m_Value(LHS), m_Value(RHS)))) {
1858 // For OR, check if the negated condition implies CmpToCheck.
1859 if (IsOr)
1860 Pred = CmpInst::getInversePredicate(Pred);
1861 // Optimistically add fact from the other compares in the AND/OR.
1862 Info.addFact(Pred, LHS, RHS, CB.NumIn, CB.NumOut, DFSInStack);
1863 continue;
1864 }
1865 if (IsOr ? match(Val, m_LogicalOr(m_Value(LHS), m_Value(RHS)))
1866 : match(Val, m_LogicalAnd(m_Value(LHS), m_Value(RHS)))) {
1867 Worklist.push_back(LHS);
1868 Worklist.push_back(RHS);
1869 }
1870 }
1871 if (OldSize == DFSInStack.size())
1872 return false;
1873
1874 Value *A, *B;
1875 CmpPredicate Pred;
1876 [[maybe_unused]] bool Matched =
1877 match(CmpToCheck, m_ICmpLike(Pred, m_Value(A), m_Value(B)));
1878 assert(Matched && "expected icmp-like match");
1879 // Check if the second condition can be simplified now.
1880 if (auto ImpliedCondition = checkCondition(Pred, A, B, CmpToCheck, Info)) {
1881 if (IsOr == *ImpliedCondition)
1882 JoinOp->replaceAllUsesWith(
1883 ConstantInt::getBool(JoinOp->getType(), *ImpliedCondition));
1884 else
1885 JoinOp->replaceAllUsesWith(JoinOp->getOperand(OtherOpIdx));
1886 ToRemove.push_back(JoinOp);
1887 return true;
1888 }
1889
1890 return false;
1891}
1892
1893void ConstraintInfo::addFact(CmpInst::Predicate Pred, Value *A, Value *B,
1894 unsigned NumIn, unsigned NumOut,
1895 SmallVectorImpl<StackEntry> &DFSInStack) {
1896 addFactImpl(Pred, A, B, NumIn, NumOut, DFSInStack, false);
1897 // If the Pred is eq/ne, also add the fact to signed system.
1898 if (CmpInst::isEquality(Pred))
1899 addFactImpl(Pred, A, B, NumIn, NumOut, DFSInStack, true);
1900 if (Pred == CmpInst::ICMP_NE)
1901 tightenBoundUsingNe(A, B, NumIn, NumOut, DFSInStack);
1902}
1903
1904void ConstraintInfo::tightenBoundUsingNe(
1905 Value *A, Value *B, unsigned NumIn, unsigned NumOut,
1906 SmallVectorImpl<StackEntry> &DFSInStack) {
1907 if (!A->getType()->isIntegerTy())
1908 return;
1909
1910 for (bool IsSigned : {false, true}) {
1911 // In the unsigned system `A u>= 0` holds for every A, so getConstraint
1912 // already turned `A != 0` into `A u> 0`.
1913 if (!IsSigned && match(B, m_Zero()))
1914 continue;
1915
1916 // Skip if there are any unknown variables.
1917 const auto &Value2Index = getValue2Index(IsSigned);
1918 if (any_of(decompose(A, *this, IsSigned, DL).Vars,
1919 [&Value2Index](const DecompEntry &E) {
1920 return !Value2Index.contains(E.Variable);
1921 }))
1922 continue;
1923
1924 // If the system implies `A >= B` then together with `A != B` we get the
1925 // strict `A > B`; symmetrically `A <= B` becomes `A < B`.
1926 CmpInst::Predicate GEPred =
1928 CmpInst::Predicate LEPred =
1930 for (CmpInst::Predicate NonStrict : {GEPred, LEPred}) {
1931 if (!doesHold(NonStrict, A, B))
1932 continue;
1934 LLVM_DEBUG(dbgs() << "Tightening '";
1935 dumpUnpackedICmp(dbgs(), NonStrict, A, B); dbgs() << "' to '";
1937 dbgs() << "' using inequality\n");
1938 addFactImpl(Strict, A, B, NumIn, NumOut, DFSInStack,
1939 /*ForceSignedSystem=*/false);
1940 break;
1941 }
1942 }
1943}
1944
1945void ConstraintInfo::addFactImpl(CmpInst::Predicate Pred, Value *A, Value *B,
1946 unsigned NumIn, unsigned NumOut,
1947 SmallVectorImpl<StackEntry> &DFSInStack,
1948 bool ForceSignedSystem) {
1949 SmallVector<Value *> NewVariables;
1950 auto R = getConstraint(Pred, A, B, NewVariables, ForceSignedSystem);
1951
1952 // TODO: Support non-equality for facts as well.
1953 if (R.empty() || R.isNe())
1954 return;
1955
1956 LLVM_DEBUG(dbgs() << "Adding '"; dumpUnpackedICmp(dbgs(), Pred, A, B);
1957 dbgs() << "'\n");
1958 auto &CSToUse = getCS(R.IsSigned);
1959 bool Added = CSToUse.addRow(R.Coefficients, R.NumVars);
1960 if (!Added)
1961 return;
1962
1963 // If R has been added to the system, add the new variables and queue it for
1964 // removal once it goes out-of-scope.
1965 SmallVector<Value *, 2> ValuesToRelease;
1966 auto &Value2Index = getValue2Index(R.IsSigned);
1967 for (Value *V : NewVariables) {
1968 Value2Index.try_emplace(V, Value2Index.size() + 1);
1969 ValuesToRelease.push_back(V);
1970 }
1971
1972 LLVM_DEBUG({
1973 dbgs() << " constraint: ";
1974 dumpConstraint(R.Coefficients, getValue2Index(R.IsSigned));
1975 dbgs() << "\n";
1976 });
1977
1978 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
1979 std::move(ValuesToRelease));
1980
1981 if (!R.IsSigned) {
1982 for (Value *V : NewVariables) {
1983 // Add V > -1 constraints for all new variables.
1984 CSToUse.addRow({Entry(0, 0), Entry(-1, Value2Index.at(V))},
1985 Value2Index.size());
1986 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
1987 SmallVector<Value *, 2>());
1988 }
1989 }
1990
1991 if (R.isEq()) {
1992 // Also add the inverted constraint for equality constraints.
1993 for (Entry &E : R.Coefficients)
1994 if (MulOverflow(E.Coefficient, int64_t(-1), E.Coefficient))
1995 return;
1996 CSToUse.addRow(R.Coefficients, R.NumVars);
1997
1998 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
1999 SmallVector<Value *, 2>());
2000 }
2001}
2002
2005 bool Changed = false;
2006 IRBuilder<> Builder(II->getParent(), II->getIterator());
2007 Value *Sub = nullptr;
2008 for (User *U : make_early_inc_range(II->users())) {
2009 if (match(U, m_ExtractValue<0>(m_Value()))) {
2010 if (!Sub)
2011 Sub = Builder.CreateNSWSub(A, B);
2012 U->replaceAllUsesWith(Sub);
2013 Changed = true;
2014 } else if (match(U, m_ExtractValue<1>(m_Value()))) {
2015 U->replaceAllUsesWith(Builder.getFalse());
2016 Changed = true;
2017 } else
2018 continue;
2019
2020 if (U->use_empty()) {
2021 auto *I = cast<Instruction>(U);
2022 ToRemove.push_back(I);
2023 I->setOperand(0, PoisonValue::get(II->getType()));
2024 Changed = true;
2025 }
2026 }
2027
2028 if (II->use_empty()) {
2029 // Do not erase II here: the worklist may still hold Uses of II's operands.
2030 for (Use &Arg : II->args())
2031 Arg.set(PoisonValue::get(Arg->getType()));
2032 ToRemove.push_back(II);
2033 Changed = true;
2034 }
2035 return Changed;
2036}
2037
2038static bool
2041 auto DoesConditionHold = [](CmpInst::Predicate Pred, Value *A, Value *B,
2042 ConstraintInfo &Info) {
2043 auto R = Info.getConstraintForSolving(Pred, A, B);
2044 // Nothing can be proven if the constraint has no variables. This also
2045 // covers rows that could not be decomposed, which are empty.
2046 if (R.isConstantOnly())
2047 return false;
2048
2049 auto &CSToUse = Info.getCS(R.IsSigned);
2050 return CSToUse.isConditionImpliedInSubSystem(R.Coefficients);
2051 };
2052
2053 bool Changed = false;
2054 if (II->getIntrinsicID() == Intrinsic::ssub_with_overflow) {
2055 // If A s>= B && B s>= 0, ssub.with.overflow(a, b) should not overflow and
2056 // can be simplified to a regular sub.
2057 Value *A = II->getArgOperand(0);
2058 Value *B = II->getArgOperand(1);
2059 if (!DoesConditionHold(CmpInst::ICMP_SGE, A, B, Info) ||
2060 !DoesConditionHold(CmpInst::ICMP_SGE, B,
2061 ConstantInt::get(A->getType(), 0), Info))
2062 return false;
2064 }
2065 return Changed;
2066}
2067
2069 ScalarEvolution &SE,
2071 TargetLibraryInfo &TLI) {
2072 bool Changed = false;
2073 DT.updateDFSNumbers();
2074 SmallVector<Value *> FunctionArgs(llvm::make_pointer_range(F.args()));
2075 ConstraintInfo Info(F.getDataLayout(), FunctionArgs);
2076 State S(DT, LI, SE, TLI);
2077 std::unique_ptr<Module> ReproducerModule(
2078 DumpReproducers ? new Module(F.getName(), F.getContext()) : nullptr);
2079
2080 // First, collect conditions implied by branches and blocks with their
2081 // Dominator DFS in and out numbers.
2082 for (BasicBlock &BB : F) {
2083 if (!DT.getNode(&BB))
2084 continue;
2085 S.addInfoFor(BB);
2086 }
2087
2088 // Next, sort worklist by dominance, so that dominating conditions to check
2089 // and facts come before conditions and facts dominated by them. If a
2090 // condition to check and a fact have the same numbers, conditional facts come
2091 // first. Assume facts and checks are ordered according to their relative
2092 // order in the containing basic block. Also make sure conditions with
2093 // constant operands come before conditions without constant operands. This
2094 // increases the effectiveness of the current signed <-> unsigned fact
2095 // transfer logic.
2096 stable_sort(S.WorkList, [](const FactOrCheck &A, const FactOrCheck &B) {
2097 auto HasNoConstOp = [](const FactOrCheck &B) {
2098 Value *V0 = B.isConditionFact() ? B.Cond.Op0 : B.Inst->getOperand(0);
2099 Value *V1 = B.isConditionFact() ? B.Cond.Op1 : B.Inst->getOperand(1);
2100 return !isa<ConstantInt>(V0) && !isa<ConstantInt>(V1);
2101 };
2102 // If both entries have the same In numbers, conditional facts come first.
2103 // Otherwise use the relative order in the basic block.
2104 if (A.NumIn == B.NumIn) {
2105 if (A.isConditionFact() && B.isConditionFact()) {
2106 bool NoConstOpA = HasNoConstOp(A);
2107 bool NoConstOpB = HasNoConstOp(B);
2108 return NoConstOpA < NoConstOpB;
2109 }
2110 if (A.isConditionFact())
2111 return true;
2112 if (B.isConditionFact())
2113 return false;
2114 auto *InstA = A.getContextInst();
2115 auto *InstB = B.getContextInst();
2116 return InstA->comesBefore(InstB);
2117 }
2118 return A.NumIn < B.NumIn;
2119 });
2120
2121 SmallVector<Instruction *> ToRemove;
2122
2123 // Finally, process ordered worklist and eliminate implied conditions.
2124 SmallVector<StackEntry, 16> DFSInStack;
2125 SmallVector<ReproducerEntry> ReproducerCondStack;
2126 for (FactOrCheck &CB : S.WorkList) {
2127 // First, pop entries from the stack that are out-of-scope for CB. Remove
2128 // the corresponding entry from the constraint system.
2129 while (!DFSInStack.empty()) {
2130 auto &E = DFSInStack.back();
2131 LLVM_DEBUG(dbgs() << "Top of stack : " << E.NumIn << " " << E.NumOut
2132 << "\n");
2133 LLVM_DEBUG(dbgs() << "CB: " << CB.NumIn << " " << CB.NumOut << "\n");
2134 assert(E.NumIn <= CB.NumIn);
2135 if (CB.NumOut <= E.NumOut)
2136 break;
2137 LLVM_DEBUG({
2138 dbgs() << "Removing ";
2139 dumpConstraint(Info.getCS(E.IsSigned).getLastConstraint(),
2140 Info.getValue2Index(E.IsSigned));
2141 dbgs() << "\n";
2142 });
2143 removeEntryFromStack(E, Info, ReproducerModule.get(), ReproducerCondStack,
2144 DFSInStack);
2145 }
2146
2147 CmpPredicate Pred;
2148 Value *A, *B;
2149 // For a block, check if any CmpInsts become known based on the current set
2150 // of constraints.
2151 if (CB.isCheck()) {
2152 Instruction *Inst = CB.getInstructionToSimplify();
2153 if (!Inst)
2154 continue;
2155 LLVM_DEBUG(dbgs() << "Processing condition to simplify: " << *Inst
2156 << "\n");
2157 if (auto *II = dyn_cast<WithOverflowInst>(Inst)) {
2159 } else if (match(Inst, m_ICmpLike(Pred, m_Value(A), m_Value(B)))) {
2161 Pred, A, B, Inst, Info, CB.NumIn, CB.NumOut, CB.getContextInst(),
2162 ReproducerModule.get(), ReproducerCondStack, S.DT, ToRemove);
2163 if (!Simplified &&
2164 match(CB.getContextInst(), m_LogicalOp(m_Value(), m_Value()))) {
2166 CB, Info, ReproducerModule.get(), ReproducerCondStack, DFSInStack,
2167 ToRemove);
2168 }
2170 } else if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(Inst)) {
2171 Changed |= checkAndReplaceMinMax(MinMax, Info, ToRemove);
2172 } else if (auto *CmpIntr = dyn_cast<CmpIntrinsic>(Inst)) {
2173 Changed |= checkAndReplaceCmp(CmpIntr, Info, ToRemove);
2174 }
2175 continue;
2176 }
2177
2178 auto AddFact = [&](CmpPredicate Pred, Value *A, Value *B) {
2179 LLVM_DEBUG(dbgs() << "Processing fact to add to the system: ";
2180 dumpUnpackedICmp(dbgs(), Pred, A, B); dbgs() << "\n");
2181 if (Info.getCS(CmpInst::isSigned(Pred)).size() > MaxRows) {
2182 LLVM_DEBUG(
2183 dbgs()
2184 << "Skip adding constraint because system has too many rows.\n");
2185 return;
2186 }
2187
2188 Info.addFact(Pred, A, B, CB.NumIn, CB.NumOut, DFSInStack);
2189 if (ReproducerModule && DFSInStack.size() > ReproducerCondStack.size())
2190 ReproducerCondStack.emplace_back(Pred, A, B);
2191
2192 if (ICmpInst::isRelational(Pred)) {
2193 // If samesign is present on the ICmp, simply flip the sign of the
2194 // predicate, transferring the information from the signed system to the
2195 // unsigned system, and viceversa.
2196 if (Pred.hasSameSign())
2198 CB.NumIn, CB.NumOut, DFSInStack);
2199 else
2200 Info.transferToOtherSystem(Pred, A, B, CB.NumIn, CB.NumOut,
2201 DFSInStack);
2202 }
2203
2204 // (X | Y) >s -1 implies X >s -1 and Y >s -1, because the sign bit of an
2205 // OR is the OR of the operand sign bits. Similarly, (X & Y) <s 0 implies
2206 // X <s 0 and Y <s 0. Look through these canonical forms produced by
2207 // InstCombine so the sign facts on the operands are available to the
2208 // solver.
2209 if ((Pred == CmpInst::ICMP_SGT && match(B, m_AllOnes())) ||
2210 (Pred == CmpInst::ICMP_SLT && match(B, m_Zero()))) {
2211 unsigned Opc =
2212 Pred == CmpInst::ICMP_SGT ? Instruction::Or : Instruction::And;
2213 SmallVector<Value *> Worklist = {A};
2214 SmallPtrSet<Value *, 4> Seen;
2215 while (!Worklist.empty()) {
2216 Value *Cur = Worklist.pop_back_val();
2217 auto *BO = dyn_cast<BinaryOperator>(Cur);
2218 if (!BO || BO->getOpcode() != Opc)
2219 continue;
2220 for (Value *Op : {BO->getOperand(0), BO->getOperand(1)}) {
2221 if (!Seen.insert(Op).second)
2222 continue;
2223 Worklist.push_back(Op);
2224 Info.addFact(Pred, Op, B, CB.NumIn, CB.NumOut, DFSInStack);
2225 }
2226 }
2227 }
2228
2229 if (ReproducerModule && DFSInStack.size() > ReproducerCondStack.size()) {
2230 // Add dummy entries to ReproducerCondStack to keep it in sync with
2231 // DFSInStack.
2232 for (unsigned I = 0,
2233 E = (DFSInStack.size() - ReproducerCondStack.size());
2234 I < E; ++I) {
2235 ReproducerCondStack.emplace_back(ICmpInst::BAD_ICMP_PREDICATE,
2236 nullptr, nullptr);
2237 }
2238 }
2239 };
2240
2241 if (!CB.isConditionFact()) {
2242 Value *X;
2243 if (match(CB.Inst, m_Intrinsic<Intrinsic::abs>(m_Value(X)))) {
2244 // If is_int_min_poison is true then we may assume llvm.abs >= 0.
2245 if (cast<ConstantInt>(CB.Inst->getOperand(1))->isOne())
2246 AddFact(CmpInst::ICMP_SGE, CB.Inst,
2247 ConstantInt::get(CB.Inst->getType(), 0));
2248 AddFact(CmpInst::ICMP_SGE, CB.Inst, X);
2249 continue;
2250 }
2251
2252 if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(CB.Inst)) {
2253 Pred = ICmpInst::getNonStrictPredicate(MinMax->getPredicate());
2254 AddFact(Pred, MinMax, MinMax->getLHS());
2255 AddFact(Pred, MinMax, MinMax->getRHS());
2256 continue;
2257 }
2258 if (auto *USatI = dyn_cast<SaturatingInst>(CB.Inst)) {
2259 switch (USatI->getIntrinsicID()) {
2260 default:
2261 llvm_unreachable("Unexpected intrinsic.");
2262 case Intrinsic::uadd_sat:
2263 AddFact(ICmpInst::ICMP_UGE, USatI, USatI->getLHS());
2264 AddFact(ICmpInst::ICMP_UGE, USatI, USatI->getRHS());
2265 break;
2266 case Intrinsic::usub_sat:
2267 AddFact(ICmpInst::ICMP_ULE, USatI, USatI->getLHS());
2268 break;
2269 }
2270 continue;
2271 }
2272
2273 if (auto *BO = dyn_cast<BinaryOperator>(CB.Inst)) {
2274 if (BO->getOpcode() == Instruction::URem) {
2275 // urem x, n: result < n (remainder is always less than divisor)
2276 AddFact(CmpInst::ICMP_ULT, BO, BO->getOperand(1));
2277 // urem x, n: result <= x (remainder is at most the dividend)
2278 AddFact(CmpInst::ICMP_ULE, BO, BO->getOperand(0));
2279 continue;
2280 }
2281 if (BO->getOpcode() == Instruction::UDiv) {
2282 // udiv x, n: result <= x (quotient is at most the dividend)
2283 AddFact(CmpInst::ICMP_ULE, BO, BO->getOperand(0));
2284 continue;
2285 }
2286 if (BO->getOpcode() == Instruction::LShr) {
2287 // lshr x, n: result <= x (right shift cannot increase the value)
2288 AddFact(CmpInst::ICMP_ULE, BO, BO->getOperand(0));
2289 continue;
2290 }
2291 if (BO->getOpcode() == Instruction::SRem) {
2292 Value *X = BO->getOperand(0);
2293 Value *N = BO->getOperand(1);
2294 Constant *Zero = Constant::getNullValue(BO->getType());
2295 if (Info.doesHold(CmpInst::ICMP_SGE, X, Zero) ||
2296 isKnownNonNegative(X, F.getDataLayout())) {
2297 // srem x, n: result >= 0, if x >= 0 (result has the sign of x)
2298 AddFact(CmpInst::ICMP_SGE, BO, Zero);
2299 // srem x, n: result <= x, if x >= 0 (|result| <= |x| and both are
2300 // non-negative)
2301 AddFact(CmpInst::ICMP_SLE, BO, X);
2302 }
2303 if (Info.doesHold(CmpInst::ICMP_SGE, N, Zero) ||
2304 isKnownPositive(N, F.getDataLayout())) {
2305 // srem x, n: result <= n, if n >= 0 (|result| < n, so result <= n -
2306 // 1
2307 AddFact(CmpInst::ICMP_SLT, BO, N);
2308 }
2309 continue;
2310 }
2311 }
2312
2313 auto &DL = F.getDataLayout();
2314 auto AddFactsAboutIndices = [&](Value *Ptr, Type *AccessType) {
2315 CmpPredicate Pred;
2316 Value *A, *B;
2319 DL.getTypeStoreSize(AccessType).getFixedValue(), Pred, A, B, DL,
2320 TLI))
2321 AddFact(Pred, A, B);
2322 };
2323
2324 if (auto *LI = dyn_cast<LoadInst>(CB.Inst)) {
2325 AddFactsAboutIndices(LI->getPointerOperand(), LI->getAccessType());
2326 continue;
2327 }
2328 if (auto *SI = dyn_cast<StoreInst>(CB.Inst)) {
2329 AddFactsAboutIndices(SI->getPointerOperand(), SI->getAccessType());
2330 continue;
2331 }
2332 }
2333
2334 if (CB.isConditionFact()) {
2335 Pred = CB.Cond.Pred;
2336 A = CB.Cond.Op0;
2337 B = CB.Cond.Op1;
2338 if (CB.DoesHold.Pred != CmpInst::BAD_ICMP_PREDICATE &&
2339 !Info.doesHold(CB.DoesHold.Pred, CB.DoesHold.Op0, CB.DoesHold.Op1)) {
2340 LLVM_DEBUG({
2341 dbgs() << "Not adding fact ";
2342 dumpUnpackedICmp(dbgs(), Pred, A, B);
2343 dbgs() << " because precondition ";
2344 dumpUnpackedICmp(dbgs(), CB.DoesHold.Pred, CB.DoesHold.Op0,
2345 CB.DoesHold.Op1);
2346 dbgs() << " does not hold.\n";
2347 });
2348 continue;
2349 }
2350 } else {
2351 [[maybe_unused]] bool Matched =
2353 m_ICmpLike(Pred, m_Value(A), m_Value(B))));
2354 assert(Matched &&
2355 "Must have an assume intrinsic with a icmp like operand");
2356 }
2357 AddFact(Pred, A, B);
2358 }
2359
2360 if (ReproducerModule && !ReproducerModule->functions().empty()) {
2361 std::string S;
2362 raw_string_ostream StringS(S);
2363 ReproducerModule->print(StringS, nullptr);
2364 OptimizationRemark Rem(DEBUG_TYPE, "Reproducer", &F);
2365 Rem << ore::NV("module") << S;
2366 ORE.emit(Rem);
2367 }
2368
2369#ifndef NDEBUG
2370 unsigned SignedEntries =
2371 count_if(DFSInStack, [](const StackEntry &E) { return E.IsSigned; });
2372 assert(Info.getCS(false).size() - FunctionArgs.size() ==
2373 DFSInStack.size() - SignedEntries &&
2374 "updates to CS and DFSInStack are out of sync");
2375 assert(Info.getCS(true).size() == SignedEntries &&
2376 "updates to CS and DFSInStack are out of sync");
2377#endif
2378
2379 for (Instruction *I : ToRemove)
2380 I->eraseFromParent();
2381 return Changed;
2382}
2383
2386 auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
2387 auto &LI = AM.getResult<LoopAnalysis>(F);
2388 auto &SE = AM.getResult<ScalarEvolutionAnalysis>(F);
2390 auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
2391 if (!eliminateConstraints(F, DT, LI, SE, ORE, TLI))
2392 return PreservedAnalyses::all();
2393
2397 return PA;
2398}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
ReachingDefInfo InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define X(NUM, ENUM, NAME)
Definition ELF.h:856
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 int64_t MinSignedConstraintValue
static Instruction * getContextInstForUse(Use &U)
static bool preconditionHolds(const ConstraintInfo &Info, CmpInst::Predicate Pred, Value *Op, int64_t RHS)
Returns true if the pre-condition Op Pred RHS, required to look through an expression while decomposi...
static bool canUseSExt(ConstantInt *CI)
static void removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info, Module *ReproducerModule, SmallVectorImpl< ReproducerEntry > &ReproducerCondStack, SmallVectorImpl< StackEntry > &DFSInStack)
static std::optional< bool > checkCondition(CmpInst::Predicate Pred, Value *A, Value *B, Instruction *CheckInst, ConstraintInfo &Info)
static cl::opt< unsigned > MaxRows("constraint-elimination-max-rows", cl::init(500), cl::Hidden, cl::desc("Maximum number of rows to keep in constraint system"))
static cl::opt< bool > DumpReproducers("constraint-elimination-dump-reproducers", cl::init(false), cl::Hidden, cl::desc("Dump IR to reproduce successful transformations."))
static 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 bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI, ScalarEvolution &SE, OptimizationRemarkEmitter &ORE, TargetLibraryInfo &TLI)
static OffsetResult collectOffsets(GEPOperator &GEP, const DataLayout &DL)
static bool checkAndReplaceMinMax(MinMaxIntrinsic *MinMax, ConstraintInfo &Info, SmallVectorImpl< Instruction * > &ToRemove)
static Decomposition decompose(Value *V, const ConstraintInfo &Info, bool IsSigned, const DataLayout &DL)
static Decomposition decomposeGEP(GEPOperator &GEP, const ConstraintInfo &Info, bool IsSigned, const DataLayout &DL)
static void dumpConstraint(ArrayRef< Entry > C, const DenseMap< Value *, unsigned > &Value2Index)
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 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 bool replaceSubOverflowUses(IntrinsicInst *II, Value *A, Value *B, SmallVectorImpl< Instruction * > &ToRemove)
static bool tryToSimplifyOverflowMath(IntrinsicInst *II, ConstraintInfo &Info, SmallVectorImpl< Instruction * > &ToRemove)
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,...
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.
static bool hasNoUnsignedWrap(BinaryOperator &I)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Machine Check Debug Module
uint64_t IntrinsicInst * II
#define P(N)
if(PassOpts->AAPipeline)
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
bool sgt(const APInt &RHS) const
Signed greater than comparison.
Definition APInt.h:1206
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
Definition APInt.h:377
LLVM_ABI APInt urem(const APInt &RHS) const
Unsigned remainder operation.
Definition APInt.cpp:1693
bool isNegative() const
Determine sign of this APInt.
Definition APInt.h:326
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
Definition APInt.h:472
bool slt(const APInt &RHS) const
Signed less than comparison.
Definition APInt.h:1135
bool isOne() const
Determine if this is a value of 1.
Definition APInt.h:386
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
LLVM Basic Block Representation.
Definition BasicBlock.h:62
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
Definition BasicBlock.h:515
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this basic block belongs to.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Predicate getStrictPredicate() const
For example, SGE -> SGT, SLE -> SLT, ULE -> ULT, UGE -> UGT.
Definition InstrTypes.h:921
bool isEquality() const
Determine if this is an equals/not equals predicate.
Definition InstrTypes.h:978
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ ICMP_SLT
signed less than
Definition InstrTypes.h:769
@ ICMP_SLE
signed less or equal
Definition InstrTypes.h:770
@ ICMP_UGE
unsigned greater or equal
Definition InstrTypes.h:764
@ ICMP_UGT
unsigned greater than
Definition InstrTypes.h:763
@ ICMP_SGT
signed greater than
Definition InstrTypes.h:767
@ ICMP_ULT
unsigned less than
Definition InstrTypes.h:765
@ ICMP_NE
not equal
Definition InstrTypes.h:762
@ ICMP_SGE
signed greater or equal
Definition InstrTypes.h:768
@ ICMP_ULE
unsigned less or equal
Definition InstrTypes.h:766
bool isSigned() const
Definition InstrTypes.h:993
static LLVM_ABI bool isEquality(Predicate pred)
Determine if this is an equals/not equals predicate.
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Definition InstrTypes.h:890
Predicate getNonStrictPredicate() const
For example, SGT -> SGE, SLT -> SLE, ULT -> ULE, UGT -> UGE.
Definition InstrTypes.h:934
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Definition InstrTypes.h:852
bool isUnsigned() const
Definition InstrTypes.h:999
This class represents a ucmp/scmp intrinsic.
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
static LLVM_ABI CmpPredicate getInverse(CmpPredicate P)
Get the inverse predicate of a CmpPredicate.
bool hasSameSign() const
Query samesign information, for optimizations.
This is the shared class of boolean and integer constants.
Definition Constants.h:87
bool isNegative() const
Definition Constants.h:214
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
Definition Constants.h:135
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
Definition Constants.h:174
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition Constants.h:159
static LLVM_ABI ConstantInt * getBool(LLVMContext &Context, bool V)
This is an important base class in LLVM.
Definition Constant.h:43
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &)
bool addRow(ArrayRef< Entry > R, size_t NumVars)
static RowTy negate(RowTy R)
LLVM_ABI std::pair< ConstraintSystem, RowTy > getSubSystem(ArrayRef< Entry > R) const
Build and return a sub-system of constraints connected (transitively) to query R, with variables comp...
static RowTy toStrictLessThan(RowTy R)
Converts the given row to form a strict less than inequality.
SmallVector< Entry, 8 > RowTy
A single constraint of the form 'c >= v1 * c1 + ... + vn * cn'.
static RowTy negateOrEqual(RowTy R)
Multiplies each coefficient in the given row by -1.
LLVM_ABI void dump() const
Print the constraints in the system.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
static bool shouldExecute(CounterInfo &Counter)
unsigned size() const
Definition DenseMap.h:172
unsigned getDFSNumIn() const
getDFSNumIn/getDFSNumOut - These return the DFS visitation order for nodes in the dominator tree.
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 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:168
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
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.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2893
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.
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
Analysis pass that exposes the LoopInfo for a function.
Definition LoopInfo.h:594
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
size_type size() const
Definition MapVector.h:58
This class represents min/max intrinsics.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
The optimization diagnostic interface.
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.
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
Analysis pass that exposes the ScalarEvolution for a function.
The main scalar evolution driver.
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI const SCEV * getMinusSCEV(SCEVUse LHS, SCEVUse RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Return LHS-RHS.
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:282
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:368
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:232
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
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:255
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:553
LLVM_ABI const Value * stripPointerCastsSameRepresentation() const
Strip off pointer casts, all-zero GEPs and address space casts but ensures the representation of the ...
Definition Value.cpp:721
bool use_empty() const
Definition Value.h:346
LLVM_ABI bool replaceUsesWithIf(Value *New, llvm::function_ref< bool(Use &U)> ShouldReplace)
Go through the uses list for this definition and make each use point to "V" if the callback ShouldRep...
Definition Value.cpp:561
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
constexpr bool isFixed() const
Returns true if the quantity is not scaled by vscale.
Definition TypeSize.h:171
const ParentTy * getParent() const
Definition ilist_node.h:34
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ Entry
Definition COFF.h:862
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
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.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWAdd(const LHS &L, const RHS &R)
auto m_LogicalOp()
Matches either L && R or L || R where L and R are arbitrary values.
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWSub(const LHS &L, const RHS &R)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
DisjointOr_match< LHS, RHS > m_DisjointOr(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst, true > m_c_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
Matches an ICmp with a predicate over LHS and RHS in either order.
ExtractValue_match< Ind, Val_t > m_ExtractValue(const Val_t &V)
Match a single index ExtractValue instruction.
ICmpLike_match< LHS, RHS > m_ICmpLike(CmpPredicate &Pred, const LHS &L, const RHS &R)
auto m_Value()
Match an arbitrary value and ignore it.
NoWrapTrunc_match< OpTy, TruncInst::NoSignedWrap > m_NSWTrunc(const OpTy &Op)
Matches trunc nsw.
NNegZExt_match< OpTy > m_NNegZExt(const OpTy &Op)
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoSignedWrap > m_NSWShl(const LHS &L, const RHS &R)
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWShl(const LHS &L, const RHS &R)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Mul, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWMul(const LHS &L, const RHS &R)
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.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap > m_NSWAdd(const LHS &L, const RHS &R)
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
brc_match< Cond_t, match_bind< BasicBlock >, match_bind< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Mul, OverflowingBinaryOperator::NoSignedWrap > m_NSWMul(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
bind_cst_ty m_scev_APInt(const APInt *&C)
Match an SCEV constant and bind it to an APInt.
specificloop_ty m_SpecificLoop(const Loop *L)
bool match(const SCEV *S, const Pattern &P)
SCEVAffineAddRec_match< Op0_t, Op1_t, match_isa< const Loop > > m_scev_AffineAddRec(const Op0_t &Op0, const Op1_t &Op1)
initializer< Ty > init(const Ty &Val)
@ Switch
The "resume-switch" lowering, where there are separate resume and destroy functions that are shared b...
Definition CoroShape.h:32
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
bool empty() const
Definition BasicBlock.h:101
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:315
@ Offset
Definition DWP.cpp:578
void stable_sort(R &&Range)
Definition STLExtras.h:2116
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:1765
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:2208
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:633
constexpr std::enable_if_t< std::is_signed_v< T >, std::pair< T, bool > > AddOverflow(T X, T Y)
Add two signed integers, computing the two's complement truncated result, returning a pair {result,...
Definition MathExtras.h:698
LLVM_ABI std::optional< TypeSize > getBaseObjectSize(const Value *Ptr, const DataLayout &DL, const TargetLibraryInfo *TLI, ObjectSizeOpts Opts={})
Like getObjectSize(), but only returns the size of base objects (like allocas, global variables and a...
const Value * getPointerOperand(const Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
DomTreeNodeBase< BasicBlock > DomTreeNode
Definition Dominators.h:65
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
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:1636
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
@ 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:1917
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:2019
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:1772
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:2192
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