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