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