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 = 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 Decomposition Result(ConstantOffset.getSExtValue(), DecompEntry(1, BasePtr));
466 for (auto [Index, Scale] : VariableOffsets) {
467 auto IdxResult = decompose(Index, Preconditions, IsSigned, DL);
468 if (IdxResult.mul(Scale.getSExtValue()))
469 return &GEP;
470 if (Result.add(IdxResult))
471 return &GEP;
472
473 if (!NW.hasNoUnsignedWrap()) {
474 // Try to prove nuw from nusw and nneg.
475 assert(NW.hasNoUnsignedSignedWrap() && "Must have nusw flag");
476 if (!isKnownNonNegative(Index, DL))
477 Preconditions.emplace_back(CmpInst::ICMP_SGE, Index,
478 ConstantInt::get(Index->getType(), 0));
479 }
480 }
481 return Result;
482}
483
484// Decomposes \p V into a constant offset + list of pairs { Coefficient,
485// Variable } where Coefficient * Variable. The sum of the constant offset and
486// pairs equals \p V.
487static Decomposition decompose(Value *V,
488 SmallVectorImpl<ConditionTy> &Preconditions,
489 bool IsSigned, const DataLayout &DL) {
490
491 auto MergeResults = [&Preconditions, IsSigned,
492 &DL](Value *A, Value *B,
493 bool IsSignedB) -> std::optional<Decomposition> {
494 auto ResA = decompose(A, Preconditions, IsSigned, DL);
495 auto ResB = decompose(B, Preconditions, IsSignedB, DL);
496 if (ResA.add(ResB))
497 return std::nullopt;
498 return ResA;
499 };
500
501 Type *Ty = V->getType()->getScalarType();
502 if (Ty->isPointerTy() && !IsSigned) {
503 if (auto *GEP = dyn_cast<GEPOperator>(V))
504 return decomposeGEP(*GEP, Preconditions, IsSigned, DL);
506 return int64_t(0);
507
508 return V;
509 }
510
511 // Don't handle integers > 64 bit. Our coefficients are 64-bit large, so
512 // coefficient add/mul may wrap, while the operation in the full bit width
513 // would not.
514 if (!Ty->isIntegerTy() || Ty->getIntegerBitWidth() > 64)
515 return V;
516
517 // Decompose \p V used with a signed predicate.
518 if (IsSigned) {
519 if (auto *CI = dyn_cast<ConstantInt>(V)) {
520 if (canUseSExt(CI))
521 return CI->getSExtValue();
522 }
523 Value *Op0;
524 Value *Op1;
525
526 if (match(V, m_SExt(m_Value(Op0))))
527 V = Op0;
528 else if (match(V, m_NNegZExt(m_Value(Op0)))) {
529 V = Op0;
530 } else if (match(V, m_NSWTrunc(m_Value(Op0)))) {
531 if (Op0->getType()->getScalarSizeInBits() <= 64)
532 V = Op0;
533 }
534
535 if (match(V, m_NSWAdd(m_Value(Op0), m_Value(Op1)))) {
536 if (auto Decomp = MergeResults(Op0, Op1, IsSigned))
537 return *Decomp;
538 return V;
539 }
540
541 if (match(V, m_NSWSub(m_Value(Op0), m_Value(Op1)))) {
542 auto ResA = decompose(Op0, Preconditions, IsSigned, DL);
543 auto ResB = decompose(Op1, Preconditions, IsSigned, DL);
544 if (!ResA.sub(ResB))
545 return ResA;
546 return V;
547 }
548
549 ConstantInt *CI;
550 if (match(V, m_NSWMul(m_Value(Op0), m_ConstantInt(CI))) && canUseSExt(CI)) {
551 auto Result = decompose(Op0, Preconditions, IsSigned, DL);
552 if (!Result.mul(CI->getSExtValue()))
553 return Result;
554 return V;
555 }
556
557 // (shl nsw x, shift) is (mul nsw x, (1<<shift)), with the exception of
558 // shift == bw-1.
559 if (match(V, m_NSWShl(m_Value(Op0), m_ConstantInt(CI)))) {
560 uint64_t Shift = CI->getValue().getLimitedValue();
561 if (Shift < Ty->getIntegerBitWidth() - 1) {
562 assert(Shift < 64 && "Would overflow");
563 auto Result = decompose(Op0, Preconditions, IsSigned, DL);
564 if (!Result.mul(int64_t(1) << Shift))
565 return Result;
566 return V;
567 }
568 }
569
570 return V;
571 }
572
573 if (auto *CI = dyn_cast<ConstantInt>(V)) {
574 if (CI->uge(MaxConstraintValue))
575 return V;
576 return int64_t(CI->getZExtValue());
577 }
578
579 Value *Op0;
580 if (match(V, m_ZExt(m_Value(Op0)))) {
581 V = Op0;
582 } else if (match(V, m_SExt(m_Value(Op0)))) {
583 V = Op0;
584 Preconditions.emplace_back(CmpInst::ICMP_SGE, Op0,
585 ConstantInt::get(Op0->getType(), 0));
586 } else if (auto *Trunc = dyn_cast<TruncInst>(V)) {
587 if (Trunc->getSrcTy()->getScalarSizeInBits() <= 64) {
588 if (Trunc->hasNoUnsignedWrap() || Trunc->hasNoSignedWrap()) {
589 V = Trunc->getOperand(0);
590 if (!Trunc->hasNoUnsignedWrap())
591 Preconditions.emplace_back(CmpInst::ICMP_SGE, V,
592 ConstantInt::get(V->getType(), 0));
593 }
594 }
595 }
596
597 Value *Op1;
598 ConstantInt *CI;
599 if (match(V, m_NUWAdd(m_Value(Op0), m_Value(Op1)))) {
600 if (auto Decomp = MergeResults(Op0, Op1, IsSigned))
601 return *Decomp;
602 return V;
603 }
604
605 if (match(V, m_Add(m_Value(Op0), m_ConstantInt(CI))) && CI->isNegative() &&
606 canUseSExt(CI)) {
607 Preconditions.emplace_back(
609 ConstantInt::get(Op0->getType(), CI->getSExtValue() * -1));
610 if (auto Decomp = MergeResults(Op0, CI, true))
611 return *Decomp;
612 return V;
613 }
614
615 if (match(V, m_NSWAdd(m_Value(Op0), m_Value(Op1)))) {
616 if (!isKnownNonNegative(Op0, DL))
617 Preconditions.emplace_back(CmpInst::ICMP_SGE, Op0,
618 ConstantInt::get(Op0->getType(), 0));
619 if (!isKnownNonNegative(Op1, DL))
620 Preconditions.emplace_back(CmpInst::ICMP_SGE, Op1,
621 ConstantInt::get(Op1->getType(), 0));
622
623 if (auto Decomp = MergeResults(Op0, Op1, IsSigned))
624 return *Decomp;
625 return V;
626 }
627
628 // Decompose or as an add if there are no common bits between the operands.
629 if (match(V, m_DisjointOr(m_Value(Op0), m_ConstantInt(CI)))) {
630 if (auto Decomp = MergeResults(Op0, CI, IsSigned))
631 return *Decomp;
632 return V;
633 }
634
635 if (match(V, m_NUWShl(m_Value(Op1), m_ConstantInt(CI))) && canUseSExt(CI)) {
636 if (CI->getSExtValue() < 0 || CI->getSExtValue() >= 64)
637 return V;
638 auto Result = decompose(Op1, Preconditions, IsSigned, DL);
639 if (!Result.mul(int64_t{1} << CI->getSExtValue()))
640 return Result;
641 return V;
642 }
643
644 if (match(V, m_NUWMul(m_Value(Op1), m_ConstantInt(CI))) && canUseSExt(CI) &&
645 (!CI->isNegative())) {
646 auto Result = decompose(Op1, Preconditions, IsSigned, DL);
647 if (!Result.mul(CI->getSExtValue()))
648 return Result;
649 return V;
650 }
651
652 if (match(V, m_NUWSub(m_Value(Op0), m_Value(Op1)))) {
653 auto ResA = decompose(Op0, Preconditions, IsSigned, DL);
654 auto ResB = decompose(Op1, Preconditions, IsSigned, DL);
655 if (!ResA.sub(ResB))
656 return ResA;
657 return V;
658 }
659
660 return V;
661}
662
663ConstraintTy
664ConstraintInfo::getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
665 SmallVectorImpl<Value *> &NewVariables,
666 bool ForceSignedSystem) const {
667 assert(NewVariables.empty() && "NewVariables must be empty when passed in");
668 assert((!ForceSignedSystem || CmpInst::isEquality(Pred)) &&
669 "signed system can only be forced on eq/ne");
670
671 bool IsEq = false;
672 bool IsNe = false;
673
674 // Try to convert Pred to one of ULE/ULT/SLE/SLT.
675 switch (Pred) {
679 case CmpInst::ICMP_SGE: {
680 Pred = CmpInst::getSwappedPredicate(Pred);
681 std::swap(Op0, Op1);
682 break;
683 }
684 case CmpInst::ICMP_EQ:
685 if (!ForceSignedSystem && match(Op1, m_Zero())) {
686 Pred = CmpInst::ICMP_ULE;
687 } else {
688 IsEq = true;
689 Pred = CmpInst::ICMP_ULE;
690 }
691 break;
692 case CmpInst::ICMP_NE:
693 if (!ForceSignedSystem && match(Op1, m_Zero())) {
695 std::swap(Op0, Op1);
696 } else {
697 IsNe = true;
698 Pred = CmpInst::ICMP_ULE;
699 }
700 break;
701 default:
702 break;
703 }
704
705 if (Pred != CmpInst::ICMP_ULE && Pred != CmpInst::ICMP_ULT &&
706 Pred != CmpInst::ICMP_SLE && Pred != CmpInst::ICMP_SLT)
707 return {};
708
709 SmallVector<ConditionTy, 4> Preconditions;
710 bool IsSigned = ForceSignedSystem || CmpInst::isSigned(Pred);
711 auto &Value2Index = getValue2Index(IsSigned);
713 Preconditions, IsSigned, DL);
715 Preconditions, IsSigned, DL);
716 int64_t Offset1 = ADec.Offset;
717 int64_t Offset2 = BDec.Offset;
718 Offset1 *= -1;
719
720 auto &VariablesA = ADec.Vars;
721 auto &VariablesB = BDec.Vars;
722
723 // First try to look up \p V in Value2Index and NewVariables. Otherwise add a
724 // new entry to NewVariables.
725 SmallDenseMap<Value *, unsigned> NewIndexMap;
726 auto GetOrAddIndex = [&Value2Index, &NewVariables,
727 &NewIndexMap](Value *V) -> unsigned {
728 auto V2I = Value2Index.find(V);
729 if (V2I != Value2Index.end())
730 return V2I->second;
731 auto [It, Inserted] = NewIndexMap.try_emplace(
732 V, Value2Index.size() + NewVariables.size() + 1);
733 if (Inserted)
734 NewVariables.push_back(V);
735 return It->second;
736 };
737
738 // Make sure all variables have entries in Value2Index or NewVariables.
739 for (const auto &KV : concat<DecompEntry>(VariablesA, VariablesB))
740 GetOrAddIndex(KV.Variable);
741
742 // Build result constraint, by first adding all coefficients from A and then
743 // subtracting all coefficients from B.
744 ConstraintTy Res(
745 SmallVector<int64_t, 8>(Value2Index.size() + NewVariables.size() + 1, 0),
746 IsSigned, IsEq, IsNe);
747 auto &R = Res.Coefficients;
748 for (const auto &KV : VariablesA)
749 R[GetOrAddIndex(KV.Variable)] += KV.Coefficient;
750
751 for (const auto &KV : VariablesB) {
752 auto &Coeff = R[GetOrAddIndex(KV.Variable)];
753 if (SubOverflow(Coeff, KV.Coefficient, Coeff))
754 return {};
755 }
756
757 int64_t OffsetSum;
758 if (AddOverflow(Offset1, Offset2, OffsetSum))
759 return {};
760 if (Pred == CmpInst::ICMP_SLT || Pred == CmpInst::ICMP_ULT)
761 if (AddOverflow(OffsetSum, int64_t(-1), OffsetSum))
762 return {};
763 R[0] = OffsetSum;
764 Res.Preconditions = std::move(Preconditions);
765
766 // Remove any (Coefficient, Variable) entry where the Coefficient is 0 for new
767 // variables.
768 while (!NewVariables.empty()) {
769 int64_t Last = R.back();
770 if (Last != 0)
771 break;
772 R.pop_back();
773 Value *RemovedV = NewVariables.pop_back_val();
774 NewIndexMap.erase(RemovedV);
775 }
776
777 return Res;
778}
779
780ConstraintTy ConstraintInfo::getConstraintForSolving(CmpInst::Predicate Pred,
781 Value *Op0,
782 Value *Op1) const {
783 Constant *NullC = Constant::getNullValue(Op0->getType());
784 // Handle trivially true compares directly to avoid adding V UGE 0 constraints
785 // for all variables in the unsigned system.
786 if ((Pred == CmpInst::ICMP_ULE && Op0 == NullC) ||
787 (Pred == CmpInst::ICMP_UGE && Op1 == NullC)) {
788 auto &Value2Index = getValue2Index(false);
789 // Return constraint that's trivially true.
790 return ConstraintTy(SmallVector<int64_t, 8>(Value2Index.size(), 0), false,
791 false, false);
792 }
793
794 // If both operands are known to be non-negative, change signed predicates to
795 // unsigned ones. This increases the reasoning effectiveness in combination
796 // with the signed <-> unsigned transfer logic.
797 if (CmpInst::isSigned(Pred) &&
798 isKnownNonNegative(Op0, DL, /*Depth=*/MaxAnalysisRecursionDepth - 1) &&
801
802 SmallVector<Value *> NewVariables;
803 ConstraintTy R = getConstraint(Pred, Op0, Op1, NewVariables);
804 if (!NewVariables.empty())
805 return {};
806 return R;
807}
808
809bool ConstraintTy::isValid(const ConstraintInfo &Info) const {
810 return Coefficients.size() > 0 &&
811 all_of(Preconditions, [&Info](const ConditionTy &C) {
812 return Info.doesHold(C.Pred, C.Op0, C.Op1);
813 });
814}
815
816std::optional<bool>
817ConstraintTy::isImpliedBy(const ConstraintSystem &CS) const {
818 bool IsConditionImplied = CS.isConditionImplied(Coefficients);
819
820 if (IsEq || IsNe) {
821 auto NegatedOrEqual = ConstraintSystem::negateOrEqual(Coefficients);
822 bool IsNegatedOrEqualImplied =
823 !NegatedOrEqual.empty() && CS.isConditionImplied(NegatedOrEqual);
824
825 // In order to check that `%a == %b` is true (equality), both conditions `%a
826 // >= %b` and `%a <= %b` must hold true. When checking for equality (`IsEq`
827 // is true), we return true if they both hold, false in the other cases.
828 if (IsConditionImplied && IsNegatedOrEqualImplied)
829 return IsEq;
830
831 auto Negated = ConstraintSystem::negate(Coefficients);
832 bool IsNegatedImplied = !Negated.empty() && CS.isConditionImplied(Negated);
833
834 auto StrictLessThan = ConstraintSystem::toStrictLessThan(Coefficients);
835 bool IsStrictLessThanImplied =
836 !StrictLessThan.empty() && CS.isConditionImplied(StrictLessThan);
837
838 // In order to check that `%a != %b` is true (non-equality), either
839 // condition `%a > %b` or `%a < %b` must hold true. When checking for
840 // non-equality (`IsNe` is true), we return true if one of the two holds,
841 // false in the other cases.
842 if (IsNegatedImplied || IsStrictLessThanImplied)
843 return IsNe;
844
845 return std::nullopt;
846 }
847
848 if (IsConditionImplied)
849 return true;
850
851 auto Negated = ConstraintSystem::negate(Coefficients);
852 auto IsNegatedImplied = !Negated.empty() && CS.isConditionImplied(Negated);
853 if (IsNegatedImplied)
854 return false;
855
856 // Neither the condition nor its negated holds, did not prove anything.
857 return std::nullopt;
858}
859
860bool ConstraintInfo::doesHold(CmpInst::Predicate Pred, Value *A,
861 Value *B) const {
862 auto R = getConstraintForSolving(Pred, A, B);
863 return R.isValid(*this) &&
864 getCS(R.IsSigned).isConditionImplied(R.Coefficients);
865}
866
867void ConstraintInfo::transferToOtherSystem(
868 CmpInst::Predicate Pred, Value *A, Value *B, unsigned NumIn,
869 unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack) {
870 auto IsKnownNonNegative = [this](Value *V) {
871 return doesHold(CmpInst::ICMP_SGE, V, ConstantInt::get(V->getType(), 0)) ||
873 };
874 // Check if we can combine facts from the signed and unsigned systems to
875 // derive additional facts.
876 if (!A->getType()->isIntegerTy())
877 return;
878 // FIXME: This currently depends on the order we add facts. Ideally we
879 // would first add all known facts and only then try to add additional
880 // facts.
881 switch (Pred) {
882 default:
883 break;
886 // If B is a signed positive constant, then A >=s 0 and A <s (or <=s) B.
887 if (IsKnownNonNegative(B)) {
888 addFact(CmpInst::ICMP_SGE, A, ConstantInt::get(B->getType(), 0), NumIn,
889 NumOut, DFSInStack);
890 addFact(ICmpInst::getSignedPredicate(Pred), A, B, NumIn, NumOut,
891 DFSInStack);
892 }
893 break;
896 // If A is a signed positive constant, then B >=s 0 and A >s (or >=s) B.
897 if (IsKnownNonNegative(A)) {
898 addFact(CmpInst::ICMP_SGE, B, ConstantInt::get(B->getType(), 0), NumIn,
899 NumOut, DFSInStack);
900 addFact(ICmpInst::getSignedPredicate(Pred), A, B, NumIn, NumOut,
901 DFSInStack);
902 }
903 break;
905 if (IsKnownNonNegative(A))
906 addFact(CmpInst::ICMP_ULT, A, B, NumIn, NumOut, DFSInStack);
907 break;
908 case CmpInst::ICMP_SGT: {
909 if (doesHold(CmpInst::ICMP_SGE, B, Constant::getAllOnesValue(B->getType())))
910 addFact(CmpInst::ICMP_UGE, A, ConstantInt::get(B->getType(), 0), NumIn,
911 NumOut, DFSInStack);
912 if (IsKnownNonNegative(B))
913 addFact(CmpInst::ICMP_UGT, A, B, NumIn, NumOut, DFSInStack);
914
915 break;
916 }
918 if (IsKnownNonNegative(B))
919 addFact(CmpInst::ICMP_UGE, A, B, NumIn, NumOut, DFSInStack);
920 break;
921 }
922}
923
924#ifndef NDEBUG
925
927 const DenseMap<Value *, unsigned> &Value2Index) {
928 ConstraintSystem CS(Value2Index);
930 CS.dump();
931}
932#endif
933
934void State::addInfoForInductions(BasicBlock &BB) {
935 auto *L = LI.getLoopFor(&BB);
936 if (!L || L->getHeader() != &BB)
937 return;
938
939 Value *A;
940 Value *B;
941 CmpPredicate Pred;
942
943 if (!match(BB.getTerminator(),
944 m_Br(m_ICmp(Pred, m_Value(A), m_Value(B)), m_Value(), m_Value())))
945 return;
946 PHINode *PN = dyn_cast<PHINode>(A);
947 if (!PN) {
948 Pred = CmpInst::getSwappedPredicate(Pred);
949 std::swap(A, B);
950 PN = dyn_cast<PHINode>(A);
951 }
952
953 if (!PN || PN->getParent() != &BB || PN->getNumIncomingValues() != 2 ||
954 !SE.isSCEVable(PN->getType()))
955 return;
956
957 BasicBlock *InLoopSucc = nullptr;
958 if (Pred == CmpInst::ICMP_NE)
959 InLoopSucc = cast<BranchInst>(BB.getTerminator())->getSuccessor(0);
960 else if (Pred == CmpInst::ICMP_EQ)
961 InLoopSucc = cast<BranchInst>(BB.getTerminator())->getSuccessor(1);
962 else
963 return;
964
965 if (!L->contains(InLoopSucc) || !L->isLoopExiting(&BB) || InLoopSucc == &BB)
966 return;
967
968 auto *AR = dyn_cast_or_null<SCEVAddRecExpr>(SE.getSCEV(PN));
969 BasicBlock *LoopPred = L->getLoopPredecessor();
970 if (!AR || AR->getLoop() != L || !LoopPred)
971 return;
972
973 const SCEV *StartSCEV = AR->getStart();
974 Value *StartValue = nullptr;
975 if (auto *C = dyn_cast<SCEVConstant>(StartSCEV)) {
976 StartValue = C->getValue();
977 } else {
978 StartValue = PN->getIncomingValueForBlock(LoopPred);
979 assert(SE.getSCEV(StartValue) == StartSCEV && "inconsistent start value");
980 }
981
982 DomTreeNode *DTN = DT.getNode(InLoopSucc);
983 auto IncUnsigned = SE.getMonotonicPredicateType(AR, CmpInst::ICMP_UGT);
984 auto IncSigned = SE.getMonotonicPredicateType(AR, CmpInst::ICMP_SGT);
985 bool MonotonicallyIncreasingUnsigned =
987 bool MonotonicallyIncreasingSigned =
989 // If SCEV guarantees that AR does not wrap, PN >= StartValue can be added
990 // unconditionally.
991 if (MonotonicallyIncreasingUnsigned)
992 WorkList.push_back(
993 FactOrCheck::getConditionFact(DTN, CmpInst::ICMP_UGE, PN, StartValue));
994 if (MonotonicallyIncreasingSigned)
995 WorkList.push_back(
996 FactOrCheck::getConditionFact(DTN, CmpInst::ICMP_SGE, PN, StartValue));
997
998 APInt StepOffset;
999 if (auto *C = dyn_cast<SCEVConstant>(AR->getStepRecurrence(SE)))
1000 StepOffset = C->getAPInt();
1001 else
1002 return;
1003
1004 // Make sure the bound B is loop-invariant.
1005 if (!L->isLoopInvariant(B))
1006 return;
1007
1008 // Handle negative steps.
1009 if (StepOffset.isNegative()) {
1010 // TODO: Extend to allow steps > -1.
1011 if (!(-StepOffset).isOne())
1012 return;
1013
1014 // AR may wrap.
1015 // Add StartValue >= PN conditional on B <= StartValue which guarantees that
1016 // the loop exits before wrapping with a step of -1.
1017 WorkList.push_back(FactOrCheck::getConditionFact(
1018 DTN, CmpInst::ICMP_UGE, StartValue, PN,
1019 ConditionTy(CmpInst::ICMP_ULE, B, StartValue)));
1020 WorkList.push_back(FactOrCheck::getConditionFact(
1021 DTN, CmpInst::ICMP_SGE, StartValue, PN,
1022 ConditionTy(CmpInst::ICMP_SLE, B, StartValue)));
1023 // Add PN > B conditional on B <= StartValue which guarantees that the loop
1024 // exits when reaching B with a step of -1.
1025 WorkList.push_back(FactOrCheck::getConditionFact(
1026 DTN, CmpInst::ICMP_UGT, PN, B,
1027 ConditionTy(CmpInst::ICMP_ULE, B, StartValue)));
1028 WorkList.push_back(FactOrCheck::getConditionFact(
1029 DTN, CmpInst::ICMP_SGT, PN, B,
1030 ConditionTy(CmpInst::ICMP_SLE, B, StartValue)));
1031 return;
1032 }
1033
1034 // Make sure AR either steps by 1 or that the value we compare against is a
1035 // GEP based on the same start value and all offsets are a multiple of the
1036 // step size, to guarantee that the induction will reach the value.
1037 if (StepOffset.isZero() || StepOffset.isNegative())
1038 return;
1039
1040 if (!StepOffset.isOne()) {
1041 // Check whether B-Start is known to be a multiple of StepOffset.
1042 const SCEV *BMinusStart = SE.getMinusSCEV(SE.getSCEV(B), StartSCEV);
1043 if (isa<SCEVCouldNotCompute>(BMinusStart) ||
1044 !SE.getConstantMultiple(BMinusStart).urem(StepOffset).isZero())
1045 return;
1046 }
1047
1048 // AR may wrap. Add PN >= StartValue conditional on StartValue <= B which
1049 // guarantees that the loop exits before wrapping in combination with the
1050 // restrictions on B and the step above.
1051 if (!MonotonicallyIncreasingUnsigned)
1052 WorkList.push_back(FactOrCheck::getConditionFact(
1053 DTN, CmpInst::ICMP_UGE, PN, StartValue,
1054 ConditionTy(CmpInst::ICMP_ULE, StartValue, B)));
1055 if (!MonotonicallyIncreasingSigned)
1056 WorkList.push_back(FactOrCheck::getConditionFact(
1057 DTN, CmpInst::ICMP_SGE, PN, StartValue,
1058 ConditionTy(CmpInst::ICMP_SLE, StartValue, B)));
1059
1060 WorkList.push_back(FactOrCheck::getConditionFact(
1061 DTN, CmpInst::ICMP_ULT, PN, B,
1062 ConditionTy(CmpInst::ICMP_ULE, StartValue, B)));
1063 WorkList.push_back(FactOrCheck::getConditionFact(
1064 DTN, CmpInst::ICMP_SLT, PN, B,
1065 ConditionTy(CmpInst::ICMP_SLE, StartValue, B)));
1066
1067 // Try to add condition from header to the dedicated exit blocks. When exiting
1068 // either with EQ or NE in the header, we know that the induction value must
1069 // be u<= B, as other exits may only exit earlier.
1070 assert(!StepOffset.isNegative() && "induction must be increasing");
1071 assert((Pred == CmpInst::ICMP_EQ || Pred == CmpInst::ICMP_NE) &&
1072 "unsupported predicate");
1073 ConditionTy Precond = {CmpInst::ICMP_ULE, StartValue, B};
1075 L->getExitBlocks(ExitBBs);
1076 for (BasicBlock *EB : ExitBBs) {
1077 // Bail out on non-dedicated exits.
1078 if (DT.dominates(&BB, EB)) {
1079 WorkList.emplace_back(FactOrCheck::getConditionFact(
1080 DT.getNode(EB), CmpInst::ICMP_ULE, A, B, Precond));
1081 }
1082 }
1083}
1084
1086 uint64_t AccessSize,
1087 CmpPredicate &Pred, Value *&A,
1088 Value *&B, const DataLayout &DL,
1089 const TargetLibraryInfo &TLI) {
1091 if (!Offset.NW.hasNoUnsignedWrap())
1092 return false;
1093
1094 if (Offset.VariableOffsets.size() != 1)
1095 return false;
1096
1097 uint64_t BitWidth = Offset.ConstantOffset.getBitWidth();
1098 auto &[Index, Scale] = Offset.VariableOffsets.front();
1099 // Bail out on non-canonical GEPs.
1100 if (Index->getType()->getScalarSizeInBits() != BitWidth)
1101 return false;
1102
1103 ObjectSizeOpts Opts;
1104 // Workaround for gep inbounds, ptr null, idx.
1105 Opts.NullIsUnknownSize = true;
1106 // Be conservative since we are not clear on whether an out of bounds access
1107 // to the padding is UB or not.
1108 Opts.RoundToAlign = true;
1109 std::optional<TypeSize> Size =
1110 getBaseObjectSize(Offset.BasePtr, DL, &TLI, Opts);
1111 if (!Size || Size->isScalable())
1112 return false;
1113
1114 // Index * Scale + ConstOffset + AccessSize <= AllocSize
1115 // With nuw flag, we know that the index addition doesn't have unsigned wrap.
1116 // If (AllocSize - (ConstOffset + AccessSize)) wraps around, there is no valid
1117 // value for Index.
1118 APInt MaxIndex = (APInt(BitWidth, Size->getFixedValue() - AccessSize,
1119 /*isSigned=*/false, /*implicitTrunc=*/true) -
1120 Offset.ConstantOffset)
1121 .udiv(Scale);
1122 Pred = ICmpInst::ICMP_ULE;
1123 A = Index;
1124 B = ConstantInt::get(Index->getType(), MaxIndex);
1125 return true;
1126}
1127
1128void State::addInfoFor(BasicBlock &BB) {
1129 addInfoForInductions(BB);
1130 auto &DL = BB.getDataLayout();
1131
1132 // True as long as the current instruction is guaranteed to execute.
1133 bool GuaranteedToExecute = true;
1134 // Queue conditions and assumes.
1135 for (Instruction &I : BB) {
1136 if (auto *Cmp = dyn_cast<ICmpInst>(&I)) {
1137 for (Use &U : Cmp->uses()) {
1138 auto *UserI = getContextInstForUse(U);
1139 auto *DTN = DT.getNode(UserI->getParent());
1140 if (!DTN)
1141 continue;
1142 WorkList.push_back(FactOrCheck::getCheck(DTN, &U));
1143 }
1144 continue;
1145 }
1146
1147 auto AddFactFromMemoryAccess = [&](Value *Ptr, Type *AccessType) {
1148 auto *GEP = dyn_cast<GetElementPtrInst>(Ptr);
1149 if (!GEP)
1150 return;
1151 TypeSize AccessSize = DL.getTypeStoreSize(AccessType);
1152 if (!AccessSize.isFixed())
1153 return;
1154 if (GuaranteedToExecute) {
1155 CmpPredicate Pred;
1156 Value *A, *B;
1158 Pred, A, B, DL, TLI)) {
1159 // The memory access is guaranteed to execute when BB is entered,
1160 // hence the constraint holds on entry to BB.
1161 WorkList.emplace_back(FactOrCheck::getConditionFact(
1162 DT.getNode(I.getParent()), Pred, A, B));
1163 }
1164 } else {
1165 WorkList.emplace_back(
1166 FactOrCheck::getInstFact(DT.getNode(I.getParent()), &I));
1167 }
1168 };
1169
1170 if (auto *LI = dyn_cast<LoadInst>(&I)) {
1171 if (!LI->isVolatile())
1172 AddFactFromMemoryAccess(LI->getPointerOperand(), LI->getAccessType());
1173 }
1174 if (auto *SI = dyn_cast<StoreInst>(&I)) {
1175 if (!SI->isVolatile())
1176 AddFactFromMemoryAccess(SI->getPointerOperand(), SI->getAccessType());
1177 }
1178
1179 auto *II = dyn_cast<IntrinsicInst>(&I);
1180 Intrinsic::ID ID = II ? II->getIntrinsicID() : Intrinsic::not_intrinsic;
1181 switch (ID) {
1182 case Intrinsic::assume: {
1183 Value *A, *B;
1184 CmpPredicate Pred;
1185 if (!match(I.getOperand(0), m_ICmp(Pred, m_Value(A), m_Value(B))))
1186 break;
1187 if (GuaranteedToExecute) {
1188 // The assume is guaranteed to execute when BB is entered, hence Cond
1189 // holds on entry to BB.
1190 WorkList.emplace_back(FactOrCheck::getConditionFact(
1191 DT.getNode(I.getParent()), Pred, A, B));
1192 } else {
1193 WorkList.emplace_back(
1194 FactOrCheck::getInstFact(DT.getNode(I.getParent()), &I));
1195 }
1196 break;
1197 }
1198 // Enqueue ssub_with_overflow for simplification.
1199 case Intrinsic::ssub_with_overflow:
1200 case Intrinsic::ucmp:
1201 case Intrinsic::scmp:
1202 WorkList.push_back(
1203 FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
1204 break;
1205 // Enqueue the intrinsics to add extra info.
1206 case Intrinsic::umin:
1207 case Intrinsic::umax:
1208 case Intrinsic::smin:
1209 case Intrinsic::smax:
1210 // TODO: handle llvm.abs as well
1211 WorkList.push_back(
1212 FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
1213 [[fallthrough]];
1214 case Intrinsic::uadd_sat:
1215 case Intrinsic::usub_sat:
1216 // TODO: Check if it is possible to instead only added the min/max facts
1217 // when simplifying uses of the min/max intrinsics.
1219 break;
1220 [[fallthrough]];
1221 case Intrinsic::abs:
1222 WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I));
1223 break;
1224 }
1225
1226 // Add facts from unsigned division and remainder.
1227 // urem x, n: result < n and result <= x
1228 // udiv x, n: result <= x
1229 if (auto *BO = dyn_cast<BinaryOperator>(&I)) {
1230 if ((BO->getOpcode() == Instruction::URem ||
1231 BO->getOpcode() == Instruction::UDiv) &&
1233 WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), BO));
1234 }
1235
1236 GuaranteedToExecute &= isGuaranteedToTransferExecutionToSuccessor(&I);
1237 }
1238
1239 if (auto *Switch = dyn_cast<SwitchInst>(BB.getTerminator())) {
1240 for (auto &Case : Switch->cases()) {
1241 BasicBlock *Succ = Case.getCaseSuccessor();
1242 Value *V = Case.getCaseValue();
1243 if (!canAddSuccessor(BB, Succ))
1244 continue;
1245 WorkList.emplace_back(FactOrCheck::getConditionFact(
1246 DT.getNode(Succ), CmpInst::ICMP_EQ, Switch->getCondition(), V));
1247 }
1248 return;
1249 }
1250
1251 auto *Br = dyn_cast<BranchInst>(BB.getTerminator());
1252 if (!Br || !Br->isConditional())
1253 return;
1254
1255 Value *Cond = Br->getCondition();
1256
1257 // If the condition is a chain of ORs/AND and the successor only has the
1258 // current block as predecessor, queue conditions for the successor.
1259 Value *Op0, *Op1;
1260 if (match(Cond, m_LogicalOr(m_Value(Op0), m_Value(Op1))) ||
1261 match(Cond, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) {
1262 bool IsOr = match(Cond, m_LogicalOr());
1263 bool IsAnd = match(Cond, m_LogicalAnd());
1264 // If there's a select that matches both AND and OR, we need to commit to
1265 // one of the options. Arbitrarily pick OR.
1266 if (IsOr && IsAnd)
1267 IsAnd = false;
1268
1269 BasicBlock *Successor = Br->getSuccessor(IsOr ? 1 : 0);
1270 if (canAddSuccessor(BB, Successor)) {
1271 SmallVector<Value *> CondWorkList;
1272 SmallPtrSet<Value *, 8> SeenCond;
1273 auto QueueValue = [&CondWorkList, &SeenCond](Value *V) {
1274 if (SeenCond.insert(V).second)
1275 CondWorkList.push_back(V);
1276 };
1277 QueueValue(Op1);
1278 QueueValue(Op0);
1279 while (!CondWorkList.empty()) {
1280 Value *Cur = CondWorkList.pop_back_val();
1281 if (auto *Cmp = dyn_cast<ICmpInst>(Cur)) {
1282 WorkList.emplace_back(FactOrCheck::getConditionFact(
1283 DT.getNode(Successor),
1284 IsOr ? Cmp->getInverseCmpPredicate() : Cmp->getCmpPredicate(),
1285 Cmp->getOperand(0), Cmp->getOperand(1)));
1286 continue;
1287 }
1288 if (IsOr && match(Cur, m_LogicalOr(m_Value(Op0), m_Value(Op1)))) {
1289 QueueValue(Op1);
1290 QueueValue(Op0);
1291 continue;
1292 }
1293 if (IsAnd && match(Cur, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) {
1294 QueueValue(Op1);
1295 QueueValue(Op0);
1296 continue;
1297 }
1298 }
1299 }
1300 return;
1301 }
1302
1303 auto *CmpI = dyn_cast<ICmpInst>(Br->getCondition());
1304 if (!CmpI)
1305 return;
1306 if (canAddSuccessor(BB, Br->getSuccessor(0)))
1307 WorkList.emplace_back(FactOrCheck::getConditionFact(
1308 DT.getNode(Br->getSuccessor(0)), CmpI->getCmpPredicate(),
1309 CmpI->getOperand(0), CmpI->getOperand(1)));
1310 if (canAddSuccessor(BB, Br->getSuccessor(1)))
1311 WorkList.emplace_back(FactOrCheck::getConditionFact(
1312 DT.getNode(Br->getSuccessor(1)), CmpI->getInverseCmpPredicate(),
1313 CmpI->getOperand(0), CmpI->getOperand(1)));
1314}
1315
1316#ifndef NDEBUG
1318 Value *LHS, Value *RHS) {
1319 OS << "icmp " << Pred << ' ';
1320 LHS->printAsOperand(OS, /*PrintType=*/true);
1321 OS << ", ";
1322 RHS->printAsOperand(OS, /*PrintType=*/false);
1323}
1324#endif
1325
1326namespace {
1327/// Helper to keep track of a condition and if it should be treated as negated
1328/// for reproducer construction.
1329/// Pred == Predicate::BAD_ICMP_PREDICATE indicates that this entry is a
1330/// placeholder to keep the ReproducerCondStack in sync with DFSInStack.
1331struct ReproducerEntry {
1332 ICmpInst::Predicate Pred;
1333 Value *LHS;
1334 Value *RHS;
1335
1336 ReproducerEntry(ICmpInst::Predicate Pred, Value *LHS, Value *RHS)
1337 : Pred(Pred), LHS(LHS), RHS(RHS) {}
1338};
1339} // namespace
1340
1341/// Helper function to generate a reproducer function for simplifying \p Cond.
1342/// The reproducer function contains a series of @llvm.assume calls, one for
1343/// each condition in \p Stack. For each condition, the operand instruction are
1344/// cloned until we reach operands that have an entry in \p Value2Index. Those
1345/// will then be added as function arguments. \p DT is used to order cloned
1346/// instructions. The reproducer function will get added to \p M, if it is
1347/// non-null. Otherwise no reproducer function is generated.
1350 ConstraintInfo &Info, DominatorTree &DT) {
1351 if (!M)
1352 return;
1353
1354 LLVMContext &Ctx = Cond->getContext();
1355
1356 LLVM_DEBUG(dbgs() << "Creating reproducer for " << *Cond << "\n");
1357
1358 ValueToValueMapTy Old2New;
1361 // Traverse Cond and its operands recursively until we reach a value that's in
1362 // Value2Index or not an instruction, or not a operation that
1363 // ConstraintElimination can decompose. Such values will be considered as
1364 // external inputs to the reproducer, they are collected and added as function
1365 // arguments later.
1366 auto CollectArguments = [&](ArrayRef<Value *> Ops, bool IsSigned) {
1367 auto &Value2Index = Info.getValue2Index(IsSigned);
1368 SmallVector<Value *, 4> WorkList(Ops);
1369 while (!WorkList.empty()) {
1370 Value *V = WorkList.pop_back_val();
1371 if (!Seen.insert(V).second)
1372 continue;
1373 if (Old2New.find(V) != Old2New.end())
1374 continue;
1375 if (isa<Constant>(V))
1376 continue;
1377
1378 auto *I = dyn_cast<Instruction>(V);
1379 if (Value2Index.contains(V) || !I ||
1381 Old2New[V] = V;
1382 Args.push_back(V);
1383 LLVM_DEBUG(dbgs() << " found external input " << *V << "\n");
1384 } else {
1385 append_range(WorkList, I->operands());
1386 }
1387 }
1388 };
1389
1390 for (auto &Entry : Stack)
1391 if (Entry.Pred != ICmpInst::BAD_ICMP_PREDICATE)
1392 CollectArguments({Entry.LHS, Entry.RHS}, ICmpInst::isSigned(Entry.Pred));
1393 CollectArguments(Cond, ICmpInst::isSigned(Cond->getPredicate()));
1394
1395 SmallVector<Type *> ParamTys;
1396 for (auto *P : Args)
1397 ParamTys.push_back(P->getType());
1398
1399 FunctionType *FTy = FunctionType::get(Cond->getType(), ParamTys,
1400 /*isVarArg=*/false);
1402 Cond->getModule()->getName() +
1403 Cond->getFunction()->getName() + "repro",
1404 M);
1405 // Add arguments to the reproducer function for each external value collected.
1406 for (unsigned I = 0; I < Args.size(); ++I) {
1407 F->getArg(I)->setName(Args[I]->getName());
1408 Old2New[Args[I]] = F->getArg(I);
1409 }
1410
1411 BasicBlock *Entry = BasicBlock::Create(Ctx, "entry", F);
1412 IRBuilder<> Builder(Entry);
1413 Builder.CreateRet(Builder.getTrue());
1414 Builder.SetInsertPoint(Entry->getTerminator());
1415
1416 // Clone instructions in \p Ops and their operands recursively until reaching
1417 // an value in Value2Index (external input to the reproducer). Update Old2New
1418 // mapping for the original and cloned instructions. Sort instructions to
1419 // clone by dominance, then insert the cloned instructions in the function.
1420 auto CloneInstructions = [&](ArrayRef<Value *> Ops, bool IsSigned) {
1421 SmallVector<Value *, 4> WorkList(Ops);
1423 auto &Value2Index = Info.getValue2Index(IsSigned);
1424 while (!WorkList.empty()) {
1425 Value *V = WorkList.pop_back_val();
1426 if (Old2New.find(V) != Old2New.end())
1427 continue;
1428
1429 auto *I = dyn_cast<Instruction>(V);
1430 if (!Value2Index.contains(V) && I) {
1431 Old2New[V] = nullptr;
1432 ToClone.push_back(I);
1433 append_range(WorkList, I->operands());
1434 }
1435 }
1436
1437 sort(ToClone,
1438 [&DT](Instruction *A, Instruction *B) { return DT.dominates(A, B); });
1439 for (Instruction *I : ToClone) {
1440 Instruction *Cloned = I->clone();
1441 Old2New[I] = Cloned;
1442 Old2New[I]->setName(I->getName());
1443 Cloned->insertBefore(Builder.GetInsertPoint());
1445 Cloned->setDebugLoc({});
1446 }
1447 };
1448
1449 // Materialize the assumptions for the reproducer using the entries in Stack.
1450 // That is, first clone the operands of the condition recursively until we
1451 // reach an external input to the reproducer and add them to the reproducer
1452 // function. Then add an ICmp for the condition (with the inverse predicate if
1453 // the entry is negated) and an assert using the ICmp.
1454 for (auto &Entry : Stack) {
1455 if (Entry.Pred == ICmpInst::BAD_ICMP_PREDICATE)
1456 continue;
1457
1458 LLVM_DEBUG(dbgs() << " Materializing assumption ";
1459 dumpUnpackedICmp(dbgs(), Entry.Pred, Entry.LHS, Entry.RHS);
1460 dbgs() << "\n");
1461 CloneInstructions({Entry.LHS, Entry.RHS}, CmpInst::isSigned(Entry.Pred));
1462
1463 auto *Cmp = Builder.CreateICmp(Entry.Pred, Entry.LHS, Entry.RHS);
1464 Builder.CreateAssumption(Cmp);
1465 }
1466
1467 // Finally, clone the condition to reproduce and remap instruction operands in
1468 // the reproducer using Old2New.
1469 CloneInstructions(Cond, CmpInst::isSigned(Cond->getPredicate()));
1470 Entry->getTerminator()->setOperand(0, Cond);
1471 remapInstructionsInBlocks({Entry}, Old2New);
1472
1473 assert(!verifyFunction(*F, &dbgs()));
1474}
1475
1476static std::optional<bool> checkCondition(CmpInst::Predicate Pred, Value *A,
1477 Value *B, Instruction *CheckInst,
1478 ConstraintInfo &Info) {
1479 LLVM_DEBUG(dbgs() << "Checking " << *CheckInst << "\n");
1480
1481 auto R = Info.getConstraintForSolving(Pred, A, B);
1482 if (R.empty() || !R.isValid(Info)) {
1483 LLVM_DEBUG(dbgs() << " failed to decompose condition\n");
1484 return std::nullopt;
1485 }
1486
1487 auto &CSToUse = Info.getCS(R.IsSigned);
1488 if (auto ImpliedCondition = R.isImpliedBy(CSToUse)) {
1489 if (!DebugCounter::shouldExecute(EliminatedCounter))
1490 return std::nullopt;
1491
1492 LLVM_DEBUG({
1493 dbgs() << "Condition ";
1495 dbgs(), *ImpliedCondition ? Pred : CmpInst::getInversePredicate(Pred),
1496 A, B);
1497 dbgs() << " implied by dominating constraints\n";
1498 CSToUse.dump();
1499 });
1500 return ImpliedCondition;
1501 }
1502
1503 return std::nullopt;
1504}
1505
1507 ICmpInst *Cmp, ConstraintInfo &Info, unsigned NumIn, unsigned NumOut,
1508 Instruction *ContextInst, Module *ReproducerModule,
1509 ArrayRef<ReproducerEntry> ReproducerCondStack, DominatorTree &DT,
1511 auto ReplaceCmpWithConstant = [&](CmpInst *Cmp, bool IsTrue) {
1512 generateReproducer(Cmp, ReproducerModule, ReproducerCondStack, Info, DT);
1513 Constant *ConstantC = ConstantInt::getBool(
1514 CmpInst::makeCmpResultType(Cmp->getType()), IsTrue);
1515 bool Changed = Cmp->replaceUsesWithIf(ConstantC, [&](Use &U) {
1516 auto *UserI = getContextInstForUse(U);
1517 auto *DTN = DT.getNode(UserI->getParent());
1518 if (!DTN || DTN->getDFSNumIn() < NumIn || DTN->getDFSNumOut() > NumOut)
1519 return false;
1520 if (UserI->getParent() == ContextInst->getParent() &&
1521 UserI->comesBefore(ContextInst))
1522 return false;
1523
1524 // Conditions in an assume trivially simplify to true. Skip uses
1525 // in assume calls to not destroy the available information.
1526 auto *II = dyn_cast<IntrinsicInst>(U.getUser());
1527 return !II || II->getIntrinsicID() != Intrinsic::assume;
1528 });
1529 NumCondsRemoved++;
1530
1531 // Update the debug value records that satisfy the same condition used
1532 // in replaceUsesWithIf.
1534 findDbgUsers(Cmp, DVRUsers);
1535
1536 for (auto *DVR : DVRUsers) {
1537 auto *DTN = DT.getNode(DVR->getParent());
1538 if (!DTN || DTN->getDFSNumIn() < NumIn || DTN->getDFSNumOut() > NumOut)
1539 continue;
1540
1541 auto *MarkedI = DVR->getInstruction();
1542 if (MarkedI->getParent() == ContextInst->getParent() &&
1543 MarkedI->comesBefore(ContextInst))
1544 continue;
1545
1546 DVR->replaceVariableLocationOp(Cmp, ConstantC);
1547 }
1548
1549 if (Cmp->use_empty())
1550 ToRemove.push_back(Cmp);
1551
1552 return Changed;
1553 };
1554
1555 if (auto ImpliedCondition =
1556 checkCondition(Cmp->getPredicate(), Cmp->getOperand(0),
1557 Cmp->getOperand(1), Cmp, Info))
1558 return ReplaceCmpWithConstant(Cmp, *ImpliedCondition);
1559
1560 // When the predicate is samesign and unsigned, we can also make use of the
1561 // signed predicate information.
1562 if (Cmp->hasSameSign() && Cmp->isUnsigned())
1563 if (auto ImpliedCondition =
1564 checkCondition(Cmp->getSignedPredicate(), Cmp->getOperand(0),
1565 Cmp->getOperand(1), Cmp, Info))
1566 return ReplaceCmpWithConstant(Cmp, *ImpliedCondition);
1567
1568 return false;
1569}
1570
1571static bool checkAndReplaceMinMax(MinMaxIntrinsic *MinMax, ConstraintInfo &Info,
1573 auto ReplaceMinMaxWithOperand = [&](MinMaxIntrinsic *MinMax, bool UseLHS) {
1574 // TODO: generate reproducer for min/max.
1575 MinMax->replaceAllUsesWith(MinMax->getOperand(UseLHS ? 0 : 1));
1576 ToRemove.push_back(MinMax);
1577 return true;
1578 };
1579
1580 ICmpInst::Predicate Pred =
1581 ICmpInst::getNonStrictPredicate(MinMax->getPredicate());
1582 if (auto ImpliedCondition = checkCondition(
1583 Pred, MinMax->getOperand(0), MinMax->getOperand(1), MinMax, Info))
1584 return ReplaceMinMaxWithOperand(MinMax, *ImpliedCondition);
1585 if (auto ImpliedCondition = checkCondition(
1586 Pred, MinMax->getOperand(1), MinMax->getOperand(0), MinMax, Info))
1587 return ReplaceMinMaxWithOperand(MinMax, !*ImpliedCondition);
1588 return false;
1589}
1590
1591static bool checkAndReplaceCmp(CmpIntrinsic *I, ConstraintInfo &Info,
1593 Value *LHS = I->getOperand(0);
1594 Value *RHS = I->getOperand(1);
1595 if (checkCondition(I->getGTPredicate(), LHS, RHS, I, Info).value_or(false)) {
1596 I->replaceAllUsesWith(ConstantInt::get(I->getType(), 1));
1597 ToRemove.push_back(I);
1598 return true;
1599 }
1600 if (checkCondition(I->getLTPredicate(), LHS, RHS, I, Info).value_or(false)) {
1601 I->replaceAllUsesWith(ConstantInt::getSigned(I->getType(), -1));
1602 ToRemove.push_back(I);
1603 return true;
1604 }
1605 if (checkCondition(ICmpInst::ICMP_EQ, LHS, RHS, I, Info).value_or(false)) {
1606 I->replaceAllUsesWith(ConstantInt::get(I->getType(), 0));
1607 ToRemove.push_back(I);
1608 return true;
1609 }
1610 return false;
1611}
1612
1613static void
1614removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info,
1615 Module *ReproducerModule,
1616 SmallVectorImpl<ReproducerEntry> &ReproducerCondStack,
1617 SmallVectorImpl<StackEntry> &DFSInStack) {
1618 Info.popLastConstraint(E.IsSigned);
1619 // Remove variables in the system that went out of scope.
1620 auto &Mapping = Info.getValue2Index(E.IsSigned);
1621 for (Value *V : E.ValuesToRelease)
1622 Mapping.erase(V);
1623 Info.popLastNVariables(E.IsSigned, E.ValuesToRelease.size());
1624 DFSInStack.pop_back();
1625 if (ReproducerModule)
1626 ReproducerCondStack.pop_back();
1627}
1628
1629/// Check if either the first condition of an AND or OR is implied by the
1630/// (negated in case of OR) second condition or vice versa.
1632 FactOrCheck &CB, ConstraintInfo &Info, Module *ReproducerModule,
1633 SmallVectorImpl<ReproducerEntry> &ReproducerCondStack,
1634 SmallVectorImpl<StackEntry> &DFSInStack,
1636 Instruction *JoinOp = CB.getContextInst();
1637 if (JoinOp->use_empty())
1638 return false;
1639
1640 CmpInst *CmpToCheck = cast<CmpInst>(CB.getInstructionToSimplify());
1641 unsigned OtherOpIdx = JoinOp->getOperand(0) == CmpToCheck ? 1 : 0;
1642
1643 // Don't try to simplify the first condition of a select by the second, as
1644 // this may make the select more poisonous than the original one.
1645 // TODO: check if the first operand may be poison.
1646 if (OtherOpIdx != 0 && isa<SelectInst>(JoinOp))
1647 return false;
1648
1649 unsigned OldSize = DFSInStack.size();
1650 llvm::scope_exit InfoRestorer([&]() {
1651 // Remove entries again.
1652 while (OldSize < DFSInStack.size()) {
1653 StackEntry E = DFSInStack.back();
1654 removeEntryFromStack(E, Info, ReproducerModule, ReproducerCondStack,
1655 DFSInStack);
1656 }
1657 });
1658 bool IsOr = match(JoinOp, m_LogicalOr());
1659 SmallVector<Value *, 4> Worklist({JoinOp->getOperand(OtherOpIdx)});
1660 // Do a traversal of the AND/OR tree to add facts from leaf compares.
1661 while (!Worklist.empty()) {
1662 Value *Val = Worklist.pop_back_val();
1663 Value *LHS, *RHS;
1664 CmpPredicate Pred;
1665 if (match(Val, m_ICmp(Pred, m_Value(LHS), m_Value(RHS)))) {
1666 // For OR, check if the negated condition implies CmpToCheck.
1667 if (IsOr)
1668 Pred = CmpInst::getInversePredicate(Pred);
1669 // Optimistically add fact from the other compares in the AND/OR.
1670 Info.addFact(Pred, LHS, RHS, CB.NumIn, CB.NumOut, DFSInStack);
1671 continue;
1672 }
1673 if (IsOr ? match(Val, m_LogicalOr(m_Value(LHS), m_Value(RHS)))
1674 : match(Val, m_LogicalAnd(m_Value(LHS), m_Value(RHS)))) {
1675 Worklist.push_back(LHS);
1676 Worklist.push_back(RHS);
1677 }
1678 }
1679 if (OldSize == DFSInStack.size())
1680 return false;
1681
1682 // Check if the second condition can be simplified now.
1683 if (auto ImpliedCondition =
1684 checkCondition(CmpToCheck->getPredicate(), CmpToCheck->getOperand(0),
1685 CmpToCheck->getOperand(1), CmpToCheck, Info)) {
1686 if (IsOr == *ImpliedCondition)
1687 JoinOp->replaceAllUsesWith(
1688 ConstantInt::getBool(JoinOp->getType(), *ImpliedCondition));
1689 else
1690 JoinOp->replaceAllUsesWith(JoinOp->getOperand(OtherOpIdx));
1691 ToRemove.push_back(JoinOp);
1692 return true;
1693 }
1694
1695 return false;
1696}
1697
1698void ConstraintInfo::addFact(CmpInst::Predicate Pred, Value *A, Value *B,
1699 unsigned NumIn, unsigned NumOut,
1700 SmallVectorImpl<StackEntry> &DFSInStack) {
1701 addFactImpl(Pred, A, B, NumIn, NumOut, DFSInStack, false);
1702 // If the Pred is eq/ne, also add the fact to signed system.
1703 if (CmpInst::isEquality(Pred))
1704 addFactImpl(Pred, A, B, NumIn, NumOut, DFSInStack, true);
1705}
1706
1707void ConstraintInfo::addFactImpl(CmpInst::Predicate Pred, Value *A, Value *B,
1708 unsigned NumIn, unsigned NumOut,
1709 SmallVectorImpl<StackEntry> &DFSInStack,
1710 bool ForceSignedSystem) {
1711 // If the constraint has a pre-condition, skip the constraint if it does not
1712 // hold.
1713 SmallVector<Value *> NewVariables;
1714 auto R = getConstraint(Pred, A, B, NewVariables, ForceSignedSystem);
1715
1716 // TODO: Support non-equality for facts as well.
1717 if (!R.isValid(*this) || R.isNe())
1718 return;
1719
1720 LLVM_DEBUG(dbgs() << "Adding '"; dumpUnpackedICmp(dbgs(), Pred, A, B);
1721 dbgs() << "'\n");
1722 auto &CSToUse = getCS(R.IsSigned);
1723 if (R.Coefficients.empty())
1724 return;
1725
1726 bool Added = CSToUse.addVariableRowFill(R.Coefficients);
1727 if (!Added)
1728 return;
1729
1730 // If R has been added to the system, add the new variables and queue it for
1731 // removal once it goes out-of-scope.
1732 SmallVector<Value *, 2> ValuesToRelease;
1733 auto &Value2Index = getValue2Index(R.IsSigned);
1734 for (Value *V : NewVariables) {
1735 Value2Index.try_emplace(V, Value2Index.size() + 1);
1736 ValuesToRelease.push_back(V);
1737 }
1738
1739 LLVM_DEBUG({
1740 dbgs() << " constraint: ";
1741 dumpConstraint(R.Coefficients, getValue2Index(R.IsSigned));
1742 dbgs() << "\n";
1743 });
1744
1745 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
1746 std::move(ValuesToRelease));
1747
1748 if (!R.IsSigned) {
1749 for (Value *V : NewVariables) {
1750 ConstraintTy VarPos(SmallVector<int64_t, 8>(Value2Index.size() + 1, 0),
1751 false, false, false);
1752 VarPos.Coefficients[Value2Index[V]] = -1;
1753 CSToUse.addVariableRow(VarPos.Coefficients);
1754 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
1755 SmallVector<Value *, 2>());
1756 }
1757 }
1758
1759 if (R.isEq()) {
1760 // Also add the inverted constraint for equality constraints.
1761 for (auto &Coeff : R.Coefficients)
1762 Coeff *= -1;
1763 CSToUse.addVariableRowFill(R.Coefficients);
1764
1765 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
1766 SmallVector<Value *, 2>());
1767 }
1768}
1769
1772 bool Changed = false;
1773 IRBuilder<> Builder(II->getParent(), II->getIterator());
1774 Value *Sub = nullptr;
1775 for (User *U : make_early_inc_range(II->users())) {
1776 if (match(U, m_ExtractValue<0>(m_Value()))) {
1777 if (!Sub)
1778 Sub = Builder.CreateSub(A, B);
1779 U->replaceAllUsesWith(Sub);
1780 Changed = true;
1781 } else if (match(U, m_ExtractValue<1>(m_Value()))) {
1782 U->replaceAllUsesWith(Builder.getFalse());
1783 Changed = true;
1784 } else
1785 continue;
1786
1787 if (U->use_empty()) {
1788 auto *I = cast<Instruction>(U);
1789 ToRemove.push_back(I);
1790 I->setOperand(0, PoisonValue::get(II->getType()));
1791 Changed = true;
1792 }
1793 }
1794
1795 if (II->use_empty()) {
1796 II->eraseFromParent();
1797 Changed = true;
1798 }
1799 return Changed;
1800}
1801
1802static bool
1805 auto DoesConditionHold = [](CmpInst::Predicate Pred, Value *A, Value *B,
1806 ConstraintInfo &Info) {
1807 auto R = Info.getConstraintForSolving(Pred, A, B);
1808 if (R.size() < 2 || !R.isValid(Info))
1809 return false;
1810
1811 auto &CSToUse = Info.getCS(R.IsSigned);
1812 return CSToUse.isConditionImplied(R.Coefficients);
1813 };
1814
1815 bool Changed = false;
1816 if (II->getIntrinsicID() == Intrinsic::ssub_with_overflow) {
1817 // If A s>= B && B s>= 0, ssub.with.overflow(a, b) should not overflow and
1818 // can be simplified to a regular sub.
1819 Value *A = II->getArgOperand(0);
1820 Value *B = II->getArgOperand(1);
1821 if (!DoesConditionHold(CmpInst::ICMP_SGE, A, B, Info) ||
1822 !DoesConditionHold(CmpInst::ICMP_SGE, B,
1823 ConstantInt::get(A->getType(), 0), Info))
1824 return false;
1826 }
1827 return Changed;
1828}
1829
1831 ScalarEvolution &SE,
1833 TargetLibraryInfo &TLI) {
1834 bool Changed = false;
1835 DT.updateDFSNumbers();
1836 SmallVector<Value *> FunctionArgs(llvm::make_pointer_range(F.args()));
1837 ConstraintInfo Info(F.getDataLayout(), FunctionArgs);
1838 State S(DT, LI, SE, TLI);
1839 std::unique_ptr<Module> ReproducerModule(
1840 DumpReproducers ? new Module(F.getName(), F.getContext()) : nullptr);
1841
1842 // First, collect conditions implied by branches and blocks with their
1843 // Dominator DFS in and out numbers.
1844 for (BasicBlock &BB : F) {
1845 if (!DT.getNode(&BB))
1846 continue;
1847 S.addInfoFor(BB);
1848 }
1849
1850 // Next, sort worklist by dominance, so that dominating conditions to check
1851 // and facts come before conditions and facts dominated by them. If a
1852 // condition to check and a fact have the same numbers, conditional facts come
1853 // first. Assume facts and checks are ordered according to their relative
1854 // order in the containing basic block. Also make sure conditions with
1855 // constant operands come before conditions without constant operands. This
1856 // increases the effectiveness of the current signed <-> unsigned fact
1857 // transfer logic.
1858 stable_sort(S.WorkList, [](const FactOrCheck &A, const FactOrCheck &B) {
1859 auto HasNoConstOp = [](const FactOrCheck &B) {
1860 Value *V0 = B.isConditionFact() ? B.Cond.Op0 : B.Inst->getOperand(0);
1861 Value *V1 = B.isConditionFact() ? B.Cond.Op1 : B.Inst->getOperand(1);
1862 return !isa<ConstantInt>(V0) && !isa<ConstantInt>(V1);
1863 };
1864 // If both entries have the same In numbers, conditional facts come first.
1865 // Otherwise use the relative order in the basic block.
1866 if (A.NumIn == B.NumIn) {
1867 if (A.isConditionFact() && B.isConditionFact()) {
1868 bool NoConstOpA = HasNoConstOp(A);
1869 bool NoConstOpB = HasNoConstOp(B);
1870 return NoConstOpA < NoConstOpB;
1871 }
1872 if (A.isConditionFact())
1873 return true;
1874 if (B.isConditionFact())
1875 return false;
1876 auto *InstA = A.getContextInst();
1877 auto *InstB = B.getContextInst();
1878 return InstA->comesBefore(InstB);
1879 }
1880 return A.NumIn < B.NumIn;
1881 });
1882
1884
1885 // Finally, process ordered worklist and eliminate implied conditions.
1886 SmallVector<StackEntry, 16> DFSInStack;
1887 SmallVector<ReproducerEntry> ReproducerCondStack;
1888 for (FactOrCheck &CB : S.WorkList) {
1889 // First, pop entries from the stack that are out-of-scope for CB. Remove
1890 // the corresponding entry from the constraint system.
1891 while (!DFSInStack.empty()) {
1892 auto &E = DFSInStack.back();
1893 LLVM_DEBUG(dbgs() << "Top of stack : " << E.NumIn << " " << E.NumOut
1894 << "\n");
1895 LLVM_DEBUG(dbgs() << "CB: " << CB.NumIn << " " << CB.NumOut << "\n");
1896 assert(E.NumIn <= CB.NumIn);
1897 if (CB.NumOut <= E.NumOut)
1898 break;
1899 LLVM_DEBUG({
1900 dbgs() << "Removing ";
1901 dumpConstraint(Info.getCS(E.IsSigned).getLastConstraint(),
1902 Info.getValue2Index(E.IsSigned));
1903 dbgs() << "\n";
1904 });
1905 removeEntryFromStack(E, Info, ReproducerModule.get(), ReproducerCondStack,
1906 DFSInStack);
1907 }
1908
1909 // For a block, check if any CmpInsts become known based on the current set
1910 // of constraints.
1911 if (CB.isCheck()) {
1912 Instruction *Inst = CB.getInstructionToSimplify();
1913 if (!Inst)
1914 continue;
1915 LLVM_DEBUG(dbgs() << "Processing condition to simplify: " << *Inst
1916 << "\n");
1917 if (auto *II = dyn_cast<WithOverflowInst>(Inst)) {
1919 } else if (auto *Cmp = dyn_cast<ICmpInst>(Inst)) {
1921 Cmp, Info, CB.NumIn, CB.NumOut, CB.getContextInst(),
1922 ReproducerModule.get(), ReproducerCondStack, S.DT, ToRemove);
1923 if (!Simplified &&
1924 match(CB.getContextInst(), m_LogicalOp(m_Value(), m_Value()))) {
1926 CB, Info, ReproducerModule.get(), ReproducerCondStack, DFSInStack,
1927 ToRemove);
1928 }
1930 } else if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(Inst)) {
1931 Changed |= checkAndReplaceMinMax(MinMax, Info, ToRemove);
1932 } else if (auto *CmpIntr = dyn_cast<CmpIntrinsic>(Inst)) {
1933 Changed |= checkAndReplaceCmp(CmpIntr, Info, ToRemove);
1934 }
1935 continue;
1936 }
1937
1938 auto AddFact = [&](CmpPredicate Pred, Value *A, Value *B) {
1939 LLVM_DEBUG(dbgs() << "Processing fact to add to the system: ";
1940 dumpUnpackedICmp(dbgs(), Pred, A, B); dbgs() << "\n");
1941 if (Info.getCS(CmpInst::isSigned(Pred)).size() > MaxRows) {
1942 LLVM_DEBUG(
1943 dbgs()
1944 << "Skip adding constraint because system has too many rows.\n");
1945 return;
1946 }
1947
1948 Info.addFact(Pred, A, B, CB.NumIn, CB.NumOut, DFSInStack);
1949 if (ReproducerModule && DFSInStack.size() > ReproducerCondStack.size())
1950 ReproducerCondStack.emplace_back(Pred, A, B);
1951
1952 if (ICmpInst::isRelational(Pred)) {
1953 // If samesign is present on the ICmp, simply flip the sign of the
1954 // predicate, transferring the information from the signed system to the
1955 // unsigned system, and viceversa.
1956 if (Pred.hasSameSign())
1958 CB.NumIn, CB.NumOut, DFSInStack);
1959 else
1960 Info.transferToOtherSystem(Pred, A, B, CB.NumIn, CB.NumOut,
1961 DFSInStack);
1962 }
1963
1964 if (ReproducerModule && DFSInStack.size() > ReproducerCondStack.size()) {
1965 // Add dummy entries to ReproducerCondStack to keep it in sync with
1966 // DFSInStack.
1967 for (unsigned I = 0,
1968 E = (DFSInStack.size() - ReproducerCondStack.size());
1969 I < E; ++I) {
1970 ReproducerCondStack.emplace_back(ICmpInst::BAD_ICMP_PREDICATE,
1971 nullptr, nullptr);
1972 }
1973 }
1974 };
1975
1976 CmpPredicate Pred;
1977 if (!CB.isConditionFact()) {
1978 Value *X;
1979 if (match(CB.Inst, m_Intrinsic<Intrinsic::abs>(m_Value(X)))) {
1980 // If is_int_min_poison is true then we may assume llvm.abs >= 0.
1981 if (cast<ConstantInt>(CB.Inst->getOperand(1))->isOne())
1982 AddFact(CmpInst::ICMP_SGE, CB.Inst,
1983 ConstantInt::get(CB.Inst->getType(), 0));
1984 AddFact(CmpInst::ICMP_SGE, CB.Inst, X);
1985 continue;
1986 }
1987
1988 if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(CB.Inst)) {
1989 Pred = ICmpInst::getNonStrictPredicate(MinMax->getPredicate());
1990 AddFact(Pred, MinMax, MinMax->getLHS());
1991 AddFact(Pred, MinMax, MinMax->getRHS());
1992 continue;
1993 }
1994 if (auto *USatI = dyn_cast<SaturatingInst>(CB.Inst)) {
1995 switch (USatI->getIntrinsicID()) {
1996 default:
1997 llvm_unreachable("Unexpected intrinsic.");
1998 case Intrinsic::uadd_sat:
1999 AddFact(ICmpInst::ICMP_UGE, USatI, USatI->getLHS());
2000 AddFact(ICmpInst::ICMP_UGE, USatI, USatI->getRHS());
2001 break;
2002 case Intrinsic::usub_sat:
2003 AddFact(ICmpInst::ICMP_ULE, USatI, USatI->getLHS());
2004 break;
2005 }
2006 continue;
2007 }
2008
2009 if (auto *BO = dyn_cast<BinaryOperator>(CB.Inst)) {
2010 if (BO->getOpcode() == Instruction::URem) {
2011 // urem x, n: result < n (remainder is always less than divisor)
2012 AddFact(CmpInst::ICMP_ULT, BO, BO->getOperand(1));
2013 // urem x, n: result <= x (remainder is at most the dividend)
2014 AddFact(CmpInst::ICMP_ULE, BO, BO->getOperand(0));
2015 continue;
2016 }
2017 if (BO->getOpcode() == Instruction::UDiv) {
2018 // udiv x, n: result <= x (quotient is at most the dividend)
2019 AddFact(CmpInst::ICMP_ULE, BO, BO->getOperand(0));
2020 continue;
2021 }
2022 }
2023
2024 auto &DL = F.getDataLayout();
2025 auto AddFactsAboutIndices = [&](Value *Ptr, Type *AccessType) {
2026 CmpPredicate Pred;
2027 Value *A, *B;
2030 DL.getTypeStoreSize(AccessType).getFixedValue(), Pred, A, B, DL,
2031 TLI))
2032 AddFact(Pred, A, B);
2033 };
2034
2035 if (auto *LI = dyn_cast<LoadInst>(CB.Inst)) {
2036 AddFactsAboutIndices(LI->getPointerOperand(), LI->getAccessType());
2037 continue;
2038 }
2039 if (auto *SI = dyn_cast<StoreInst>(CB.Inst)) {
2040 AddFactsAboutIndices(SI->getPointerOperand(), SI->getAccessType());
2041 continue;
2042 }
2043 }
2044
2045 Value *A = nullptr, *B = nullptr;
2046 if (CB.isConditionFact()) {
2047 Pred = CB.Cond.Pred;
2048 A = CB.Cond.Op0;
2049 B = CB.Cond.Op1;
2050 if (CB.DoesHold.Pred != CmpInst::BAD_ICMP_PREDICATE &&
2051 !Info.doesHold(CB.DoesHold.Pred, CB.DoesHold.Op0, CB.DoesHold.Op1)) {
2052 LLVM_DEBUG({
2053 dbgs() << "Not adding fact ";
2054 dumpUnpackedICmp(dbgs(), Pred, A, B);
2055 dbgs() << " because precondition ";
2056 dumpUnpackedICmp(dbgs(), CB.DoesHold.Pred, CB.DoesHold.Op0,
2057 CB.DoesHold.Op1);
2058 dbgs() << " does not hold.\n";
2059 });
2060 continue;
2061 }
2062 } else {
2063 bool Matched = match(CB.Inst, m_Intrinsic<Intrinsic::assume>(
2064 m_ICmp(Pred, m_Value(A), m_Value(B))));
2065 (void)Matched;
2066 assert(Matched && "Must have an assume intrinsic with a icmp 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
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:114
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
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:1677
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.
ArrayRef - 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 if the block is well formed or null if the block is not well forme...
Definition BasicBlock.h:233
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:664
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Definition InstrTypes.h:982
bool isEquality() const
Determine if this is an equals/not equals predicate.
Definition InstrTypes.h:915
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:676
@ ICMP_SLT
signed less than
Definition InstrTypes.h:705
@ ICMP_SLE
signed less or equal
Definition InstrTypes.h:706
@ ICMP_UGE
unsigned greater or equal
Definition InstrTypes.h:700
@ ICMP_UGT
unsigned greater than
Definition InstrTypes.h:699
@ ICMP_SGT
signed greater than
Definition InstrTypes.h:703
@ ICMP_ULT
unsigned less than
Definition InstrTypes.h:701
@ ICMP_NE
not equal
Definition InstrTypes.h:698
@ ICMP_SGE
signed greater or equal
Definition InstrTypes.h:704
@ ICMP_ULE
unsigned less or equal
Definition InstrTypes.h:702
bool isSigned() const
Definition InstrTypes.h:930
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Definition InstrTypes.h:827
Predicate getNonStrictPredicate() const
For example, SGT -> SGE, SLT -> SLE, ULT -> ULE, UGT -> UGE.
Definition InstrTypes.h:871
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Definition InstrTypes.h:789
Predicate getPredicate() const
Return the predicate for this instruction.
Definition InstrTypes.h:765
This class represents a ucmp/scmp intrinsic.
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
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.
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:256
bool erase(const KeyT &Val)
Definition DenseMap.h:330
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:283
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:164
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:2788
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:569
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
size_type size() const
Definition MapVector.h:56
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 bool isSCEVable(Type *Ty) const
Test if values of the given type are analyzable within the SCEV framework.
LLVM_ABI const SCEV * getMinusSCEV(const SCEV *LHS, const SCEV *RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Return LHS-RHS.
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:45
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:352
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:230
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:256
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:347
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)
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
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.
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)
brc_match< Cond_t, bind_ty< BasicBlock >, bind_ty< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Sub, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWSub(const LHS &L, const RHS &R)
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
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.
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)
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.
Definition Types.h:26
@ Offset
Definition DWP.cpp:532
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:2116
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1739
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1669
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI bool verifyFunction(const Function &F, raw_ostream *OS=nullptr)
Check a function for errors, useful for use when debugging a pass.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2208
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:634
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:1152
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:1636
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
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:1917
LLVM_ABI bool isGuaranteedToTransferExecutionToSuccessor(const Instruction *I)
Return true if this function can prove that the instruction I will always transfer execution to one o...
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
Definition STLExtras.h:2019
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition iterator.h:368
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:872
#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:276