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