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