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