LLVM 24.0.0git
ConstraintElimination.cpp
Go to the documentation of this file.
1//===-- ConstraintElimination.cpp - Eliminate conds using constraints. ----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Eliminate conditions based on constraints collected from dominating
10// conditions.
11//
12//===----------------------------------------------------------------------===//
13
15#include "llvm/ADT/STLExtras.h"
16#include "llvm/ADT/ScopeExit.h"
18#include "llvm/ADT/Statistic.h"
29#include "llvm/IR/DataLayout.h"
30#include "llvm/IR/DebugInfo.h"
31#include "llvm/IR/Dominators.h"
32#include "llvm/IR/Function.h"
33#include "llvm/IR/IRBuilder.h"
34#include "llvm/IR/InstrTypes.h"
36#include "llvm/IR/Module.h"
38#include "llvm/IR/Verifier.h"
39#include "llvm/Pass.h"
41#include "llvm/Support/Debug.h"
46
47#include <optional>
48#include <string>
49
50using namespace llvm;
51using namespace PatternMatch;
52using namespace SCEVPatternMatch;
53
54#define DEBUG_TYPE "constraint-elimination"
55
56STATISTIC(NumCondsRemoved, "Number of instructions removed");
57DEBUG_COUNTER(EliminatedCounter, "conds-eliminated",
58 "Controls which conditions are eliminated");
59
61 MaxRows("constraint-elimination-max-rows", cl::init(500), cl::Hidden,
62 cl::desc("Maximum number of rows to keep in constraint system"));
63
65 "constraint-elimination-dump-reproducers", cl::init(false), cl::Hidden,
66 cl::desc("Dump IR to reproduce successful transformations."));
67
68static int64_t MaxConstraintValue = std::numeric_limits<int64_t>::max();
69static int64_t MinSignedConstraintValue = std::numeric_limits<int64_t>::min();
70
72 Instruction *UserI = cast<Instruction>(U.getUser());
73 if (auto *Phi = dyn_cast<PHINode>(UserI))
74 UserI = Phi->getIncomingBlock(U)->getTerminator();
75 return UserI;
76}
77
78namespace {
79using Entry = ConstraintSystem::Entry;
80using RowTy = ConstraintSystem::RowTy;
81
82/// Struct to express a condition of the form %Op0 Pred %Op1.
83struct ConditionTy {
84 CmpPredicate Pred;
85 Value *Op0 = nullptr;
86 Value *Op1 = nullptr;
87
88 ConditionTy() = default;
89 ConditionTy(CmpPredicate Pred, Value *Op0, Value *Op1)
90 : Pred(Pred), Op0(Op0), Op1(Op1) {}
91};
92
93/// Represents either
94/// * a condition that holds on entry to a block (=condition fact)
95/// * an assume (=assume fact)
96/// * a use of a compare instruction to simplify.
97/// It also tracks the Dominator DFS in and out numbers for each entry.
98struct FactOrCheck {
99 enum class EntryTy {
100 ConditionFact, /// A condition that holds on entry to a block.
101 InstFact, /// A fact that holds after Inst executed (e.g. an assume or
102 /// min/mix intrinsic.
103 InstCheck, /// An instruction to simplify (e.g. an overflow math
104 /// intrinsics) or whose flags may be strengthened.
105 UseCheck /// An use of a compare instruction to simplify.
106 };
107
108 union {
109 Instruction *Inst;
110 Use *U;
112 };
113
114 /// A pre-condition that must hold for the current fact to be added to the
115 /// system.
116 ConditionTy DoesHold;
117
118 unsigned NumIn;
119 unsigned NumOut;
120 EntryTy Ty;
121
122 FactOrCheck(EntryTy Ty, DomTreeNode *DTN, Instruction *Inst)
123 : Inst(Inst), NumIn(DTN->getDFSNumIn()), NumOut(DTN->getDFSNumOut()),
124 Ty(Ty) {}
125
126 FactOrCheck(DomTreeNode *DTN, Use *U)
127 : U(U), NumIn(DTN->getDFSNumIn()), NumOut(DTN->getDFSNumOut()),
128 Ty(EntryTy::UseCheck) {}
129
130 FactOrCheck(DomTreeNode *DTN, CmpPredicate Pred, Value *Op0, Value *Op1,
131 ConditionTy Precond = {})
132 : Cond(Pred, Op0, Op1), DoesHold(Precond), NumIn(DTN->getDFSNumIn()),
133 NumOut(DTN->getDFSNumOut()), Ty(EntryTy::ConditionFact) {}
134
135 static FactOrCheck getConditionFact(DomTreeNode *DTN, CmpPredicate Pred,
136 Value *Op0, Value *Op1,
137 ConditionTy Precond = {}) {
138 return FactOrCheck(DTN, Pred, Op0, Op1, Precond);
139 }
140
141 static FactOrCheck getInstFact(DomTreeNode *DTN, Instruction *Inst) {
142 return FactOrCheck(EntryTy::InstFact, DTN, Inst);
143 }
144
145 static FactOrCheck getCheck(DomTreeNode *DTN, Use *U) {
146 return FactOrCheck(DTN, U);
147 }
148
149 static FactOrCheck getCheck(DomTreeNode *DTN, Instruction *I) {
150 return FactOrCheck(EntryTy::InstCheck, DTN, I);
151 }
152
153 bool isCheck() const {
154 return Ty == EntryTy::InstCheck || Ty == EntryTy::UseCheck;
155 }
156
157 Instruction *getContextInst() const {
158 assert(!isConditionFact());
159 if (Ty == EntryTy::UseCheck)
160 return getContextInstForUse(*U);
161 return Inst;
162 }
163
164 Instruction *getInstructionToSimplify() const {
165 assert(isCheck());
166 if (Ty == EntryTy::InstCheck)
167 return Inst;
168 // The use may have been simplified to a constant already.
169 return dyn_cast<Instruction>(*U);
170 }
171
172 bool isConditionFact() const { return Ty == EntryTy::ConditionFact; }
173};
174
175/// The senses in which an induction phi is monotonic, together with the
176/// direction it moves in.
177struct MonotonicInfo {
178 /// True if the phi steps by a negative constant.
179 bool Decreasing = false;
180 /// True if the phi is monotonic in the unsigned sense.
181 bool Unsigned = false;
182 /// True if the phi is monotonic in the signed sense.
183 bool Signed = false;
184};
185
186/// Keep state required to build worklist.
187struct State {
188 DominatorTree &DT;
189 LoopInfo &LI;
190 ScalarEvolution &SE;
191 TargetLibraryInfo &TLI;
193
194 State(DominatorTree &DT, LoopInfo &LI, ScalarEvolution &SE,
195 TargetLibraryInfo &TLI)
196 : DT(DT), LI(LI), SE(SE), TLI(TLI) {}
197
198 /// Process block \p BB and add known facts to work-list.
199 void addInfoFor(BasicBlock &BB);
200
201 /// If \p BB is a loop header, bound each induction phi in it by its start
202 /// value.
203 void addBoundsForHeaderInductions(BasicBlock &BB);
204
205 /// Try to add facts for loop inductions (AddRecs) in EQ/NE compares
206 /// controlling the loop header.
207 void addInfoForInductions(BasicBlock &BB);
208
209 /// Returns the direction the induction phi \p PN with backedge value \p Step
210 /// moves in, and the senses in which it is monotonic in that direction.
211 MonotonicInfo getMonotonicityInfo(PHINode &PN, Value *Step);
212
213 /// Returns true if we can add a known condition from BB to its successor
214 /// block Succ.
215 bool canAddSuccessor(BasicBlock &BB, BasicBlock *Succ) const {
216 return DT.dominates(BasicBlockEdge(&BB, Succ), Succ);
217 }
218};
219
220class ConstraintInfo;
221
222struct StackEntry {
223 unsigned NumIn;
224 unsigned NumOut;
225 bool IsSigned = false;
226 /// Variables that can be removed from the system once the stack entry gets
227 /// removed.
228 SmallVector<Value *, 2> ValuesToRelease;
229
230 StackEntry(unsigned NumIn, unsigned NumOut, bool IsSigned,
231 SmallVector<Value *, 2> ValuesToRelease)
232 : NumIn(NumIn), NumOut(NumOut), IsSigned(IsSigned),
233 ValuesToRelease(std::move(ValuesToRelease)) {}
234};
235
236struct ConstraintTy {
237 RowTy Coefficients;
238
239 /// Number of variables the constraint is defined over.
240 unsigned NumVars = 0;
241
242 bool IsSigned = false;
243
244 ConstraintTy() = default;
245
246 ConstraintTy(RowTy Coefficients, unsigned NumVars, bool IsSigned, bool IsEq,
247 bool IsNe)
248 : Coefficients(std::move(Coefficients)), NumVars(NumVars),
249 IsSigned(IsSigned), IsEq(IsEq), IsNe(IsNe) {}
250
251 bool empty() const { return Coefficients.empty(); }
252
253 /// Returns true if the constraint does not reference any variable, i.e. it is
254 /// of the form 'c >= 0'.
255 bool isConstantOnly() const { return Coefficients.size() < 2; }
256
257 bool isEq() const { return IsEq; }
258
259 bool isNe() const { return IsNe; }
260
261 /// Check if the current constraint is implied by the given ConstraintSystem.
262 ///
263 /// \return true or false if the constraint is proven to be respectively true,
264 /// or false. When the constraint cannot be proven to be either true or false,
265 /// std::nullopt is returned.
266 std::optional<bool> isImpliedBy(const ConstraintSystem &CS) const;
267
268private:
269 bool IsEq = false;
270 bool IsNe = false;
271};
272
273/// Wrapper encapsulating separate constraint systems and corresponding value
274/// mappings for both unsigned and signed information. Facts are added to and
275/// conditions are checked against the corresponding system depending on the
276/// signed-ness of their predicates. While the information is kept separate
277/// based on signed-ness, certain conditions can be transferred between the two
278/// systems.
279class ConstraintInfo {
280
281 ConstraintSystem UnsignedCS;
282 ConstraintSystem SignedCS;
283
284 const DataLayout &DL;
285
286public:
287 ConstraintInfo(const DataLayout &DL, ArrayRef<Value *> FunctionArgs)
288 : UnsignedCS(FunctionArgs), SignedCS(FunctionArgs), DL(DL) {
289 auto &Value2Index = getValue2Index(false);
290 // Add Arg > -1 constraints to unsigned system for all function arguments.
291 for (Value *Arg : FunctionArgs)
292 UnsignedCS.addRow({Entry(0, 0), Entry(-1, Value2Index.at(Arg))},
293 Value2Index.size());
294 }
295
296 DenseMap<Value *, unsigned> &getValue2Index(bool Signed) {
297 return Signed ? SignedCS.getValue2Index() : UnsignedCS.getValue2Index();
298 }
299 const DenseMap<Value *, unsigned> &getValue2Index(bool Signed) const {
300 return Signed ? SignedCS.getValue2Index() : UnsignedCS.getValue2Index();
301 }
302
303 ConstraintSystem &getCS(bool Signed) {
304 return Signed ? SignedCS : UnsignedCS;
305 }
306 const ConstraintSystem &getCS(bool Signed) const {
307 return Signed ? SignedCS : UnsignedCS;
308 }
309
310 void popLastConstraint(bool Signed) { getCS(Signed).popLastConstraint(); }
311 void popLastNVariables(bool Signed, unsigned N) {
312 getCS(Signed).popLastNVariables(N);
313 }
314
315 bool doesHold(CmpInst::Predicate Pred, Value *A, Value *B) const;
316
317 /// Returns true if \p V is known to be non-negative, either because the
318 /// signed system implies it or because ValueTracking can prove it.
319 bool isKnownNonNegative(Value *V) const;
320
321 void addFact(CmpInst::Predicate Pred, Value *A, Value *B, unsigned NumIn,
322 unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack);
323
324 /// Turn a comparison of the form \p Op0 \p Pred \p Op1 into a vector of
325 /// constraints, using indices from the corresponding constraint system.
326 /// New variables that need to be added to the system are collected in
327 /// \p NewVariables.
328 ConstraintTy getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
329 SmallVectorImpl<Value *> &NewVariables,
330 bool ForceSignedSystem = false) const;
331
332 /// Turns a comparison of the form \p Op0 \p Pred \p Op1 into a vector of
333 /// constraints using getConstraint. Returns an empty constraint if the result
334 /// cannot be used to query the existing constraint system, e.g. because it
335 /// would require adding new variables. Also tries to convert signed
336 /// predicates to unsigned ones if possible to allow using the unsigned system
337 /// which increases the effectiveness of the signed <-> unsigned transfer
338 /// logic.
339 ConstraintTy getConstraintForSolving(CmpInst::Predicate Pred, Value *Op0,
340 Value *Op1) const;
341
342 /// Try to add information from \p A \p Pred \p B to the unsigned/signed
343 /// system if \p Pred is signed/unsigned.
344 void transferToOtherSystem(CmpInst::Predicate Pred, Value *A, Value *B,
345 unsigned NumIn, unsigned NumOut,
346 SmallVectorImpl<StackEntry> &DFSInStack);
347
348private:
349 /// Adds facts into constraint system. \p ForceSignedSystem can be set when
350 /// the \p Pred is eq/ne, and signed constraint system is used when it's
351 /// specified.
352 void addFactImpl(CmpInst::Predicate Pred, Value *A, Value *B, unsigned NumIn,
353 unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack,
354 bool ForceSignedSystem);
355
356 /// Try to use the inequality \p A != \p B to tighten a non-strict bound the
357 /// system already implies to the corresponding strict bound.
358 void tightenBoundUsingNe(Value *A, Value *B, unsigned NumIn, unsigned NumOut,
359 SmallVectorImpl<StackEntry> &DFSInStack);
360};
361
362/// Represents a (Coefficient * Variable) entry after IR decomposition.
363struct DecompEntry {
364 int64_t Coefficient;
365 Value *Variable;
366
367 DecompEntry(int64_t Coefficient, Value *Variable)
368 : Coefficient(Coefficient), Variable(Variable) {}
369};
370
371/// Represents an Offset + Coefficient1 * Variable1 + ... decomposition.
372struct Decomposition {
373 int64_t Offset = 0;
375
376 Decomposition(int64_t Offset) : Offset(Offset) {}
377 Decomposition(Value *V) { Vars.emplace_back(1, V); }
378 Decomposition(int64_t Offset, ArrayRef<DecompEntry> Vars)
379 : Offset(Offset), Vars(Vars) {}
380
381 /// Add \p OtherOffset and return true if the operation overflows, i.e. the
382 /// new decomposition is invalid.
383 [[nodiscard]] bool add(int64_t OtherOffset) {
384 return AddOverflow(Offset, OtherOffset, Offset);
385 }
386
387 /// Add \p Other and return true if the operation overflows, i.e. the new
388 /// decomposition is invalid.
389 [[nodiscard]] bool add(const Decomposition &Other) {
390 if (add(Other.Offset))
391 return true;
392 append_range(Vars, Other.Vars);
393 return false;
394 }
395
396 /// Subtract \p Other and return true if the operation overflows, i.e. the new
397 /// decomposition is invalid.
398 [[nodiscard]] bool sub(const Decomposition &Other) {
399 Decomposition Tmp = Other;
400 if (Tmp.mul(-1))
401 return true;
402 if (add(Tmp.Offset))
403 return true;
404 append_range(Vars, Tmp.Vars);
405 return false;
406 }
407
408 /// Multiply all coefficients by \p Factor and return true if the operation
409 /// overflows, i.e. the new decomposition is invalid.
410 [[nodiscard]] bool mul(int64_t Factor) {
411 if (MulOverflow(Offset, Factor, Offset))
412 return true;
413 for (auto &Var : Vars)
414 if (MulOverflow(Var.Coefficient, Factor, Var.Coefficient))
415 return true;
416 return false;
417 }
418};
419
420// Variable and constant offsets for a chain of GEPs, with base pointer BasePtr.
421struct OffsetResult {
422 Value *BasePtr;
423 APInt ConstantOffset;
424 SmallMapVector<Value *, APInt, 4> VariableOffsets;
425 GEPNoWrapFlags NW;
426
427 OffsetResult() : BasePtr(nullptr), ConstantOffset(0, uint64_t(0)) {}
428
429 OffsetResult(GEPOperator &GEP, const DataLayout &DL)
430 : BasePtr(GEP.getPointerOperand()), NW(GEP.getNoWrapFlags()) {
431 ConstantOffset = APInt(DL.getIndexTypeSizeInBits(BasePtr->getType()), 0);
432 }
433};
434} // namespace
435
436// Try to collect variable and constant offsets for \p GEP, partly traversing
437// nested GEPs. Returns an OffsetResult with nullptr as BasePtr of collecting
438// the offset fails.
440 OffsetResult Result(GEP, DL);
441 unsigned BitWidth = Result.ConstantOffset.getBitWidth();
442 if (!GEP.collectOffset(DL, BitWidth, Result.VariableOffsets,
443 Result.ConstantOffset))
444 return {};
445
446 // If we have a nested GEP, check if we can combine the constant offset of the
447 // inner GEP with the outer GEP.
448 if (auto *InnerGEP = dyn_cast<GetElementPtrInst>(Result.BasePtr)) {
449 SmallMapVector<Value *, APInt, 4> VariableOffsets2;
450 APInt ConstantOffset2(BitWidth, 0);
451 bool CanCollectInner = InnerGEP->collectOffset(
452 DL, BitWidth, VariableOffsets2, ConstantOffset2);
453 // TODO: Support cases with more than 1 variable offset.
454 if (!CanCollectInner || Result.VariableOffsets.size() > 1 ||
455 VariableOffsets2.size() > 1 ||
456 (Result.VariableOffsets.size() >= 1 && VariableOffsets2.size() >= 1)) {
457 // More than 1 variable index, use outer result.
458 return Result;
459 }
460 Result.BasePtr = InnerGEP->getPointerOperand();
461 Result.ConstantOffset += ConstantOffset2;
462 if (Result.VariableOffsets.size() == 0 && VariableOffsets2.size() == 1)
463 Result.VariableOffsets = std::move(VariableOffsets2);
464 Result.NW &= InnerGEP->getNoWrapFlags();
465 }
466 return Result;
467}
468
469static Decomposition decompose(Value *V, const ConstraintInfo &Info,
470 bool IsSigned, const DataLayout &DL);
471
472static bool canUseSExt(ConstantInt *CI) {
473 const APInt &Val = CI->getValue();
475}
476
477/// Returns true if the pre-condition \p Op \p Pred \p RHS, required to look
478/// through an expression while decomposing it, is known to hold given \p Info.
479static bool preconditionHolds(const ConstraintInfo &Info,
480 CmpInst::Predicate Pred, Value *Op, int64_t RHS) {
481 return Info.doesHold(Pred, Op, ConstantInt::get(Op->getType(), RHS));
482}
483
484static Decomposition decomposeGEP(GEPOperator &GEP, const ConstraintInfo &Info,
485 bool IsSigned, const DataLayout &DL) {
486 // Do not reason about pointers where the index size is larger than 64 bits,
487 // as the coefficients used to encode constraints are 64 bit integers.
488 if (DL.getIndexTypeSizeInBits(GEP.getPointerOperand()->getType()) > 64)
489 return &GEP;
490
491 assert(!IsSigned && "The logic below only supports decomposition for "
492 "unsigned predicates at the moment.");
493 const auto &[BasePtr, ConstantOffset, VariableOffsets, NW] =
495 // We support either plain gep nuw, or gep nusw with non-negative offset,
496 // which implies gep nuw.
497 if (!BasePtr || NW == GEPNoWrapFlags::none())
498 return &GEP;
499
500 // For a nuw-only GEP (nuw without nusw/inbounds), the offset must be
501 // interpreted as unsigned.
502 if (!NW.hasNoUnsignedSignedWrap() && ConstantOffset.isNegative())
503 return &GEP;
504
505 Decomposition Result(ConstantOffset.getSExtValue(), DecompEntry(1, BasePtr));
506 for (auto [Index, Scale] : VariableOffsets) {
507 if (!NW.hasNoUnsignedWrap()) {
508 // Try to prove nuw from nusw and nneg. If the index cannot be proven
509 // non-negative, keep the GEP as-is instead of decomposing it.
510 assert(NW.hasNoUnsignedSignedWrap() && "Must have nusw flag");
511 if (!isKnownNonNegative(Index, DL) &&
512 !preconditionHolds(Info, CmpInst::ICMP_SGE, Index, 0))
513 return &GEP;
514 }
515
516 auto IdxResult = decompose(Index, Info, IsSigned, DL);
517 if (IdxResult.mul(Scale.getSExtValue()))
518 return &GEP;
519 if (Result.add(IdxResult))
520 return &GEP;
521 }
522 return Result;
523}
524
525// Decomposes \p V into a constant offset + list of pairs { Coefficient,
526// Variable } where Coefficient * Variable. The sum of the constant offset and
527// pairs equals \p V.
528//
529// Looking through certain expressions is only valid if a pre-condition holds.
530// Pre-conditions are checked against \p Info as needed.
531static Decomposition decompose(Value *V, const ConstraintInfo &Info,
532 bool IsSigned, const DataLayout &DL) {
533 auto MergeResults = [&Info, IsSigned,
534 &DL](Value *A, Value *B,
535 bool IsSignedB) -> std::optional<Decomposition> {
536 auto ResA = decompose(A, Info, IsSigned, DL);
537 auto ResB = decompose(B, Info, IsSignedB, DL);
538 if (ResA.add(ResB))
539 return std::nullopt;
540 return ResA;
541 };
542
543 Type *Ty = V->getType()->getScalarType();
544 if (Ty->isPointerTy() && !IsSigned) {
545 if (auto *GEP = dyn_cast<GEPOperator>(V))
546 return decomposeGEP(*GEP, Info, IsSigned, DL);
548 return int64_t(0);
549
550 return V;
551 }
552
553 // Don't handle integers > 64 bit. Our coefficients are 64-bit large, so
554 // coefficient add/mul may wrap, while the operation in the full bit width
555 // would not.
556 if (!Ty->isIntegerTy() || Ty->getIntegerBitWidth() > 64)
557 return V;
558
559 // Decompose \p V used with a signed predicate.
560 if (IsSigned) {
561 if (auto *CI = dyn_cast<ConstantInt>(V)) {
562 if (canUseSExt(CI))
563 return CI->getSExtValue();
564 }
565 Value *Op0;
566 Value *Op1;
567
568 if (match(V, m_SExt(m_Value(Op0))))
569 V = Op0;
570 else if (match(V, m_NNegZExt(m_Value(Op0)))) {
571 V = Op0;
572 } else if (match(V, m_NSWTrunc(m_Value(Op0)))) {
573 if (Op0->getType()->getScalarSizeInBits() <= 64)
574 V = Op0;
575 }
576
577 if (match(V, m_NSWAdd(m_Value(Op0), m_Value(Op1)))) {
578 if (auto Decomp = MergeResults(Op0, Op1, IsSigned))
579 return *Decomp;
580 return V;
581 }
582
583 // `xor %x, -1` is equivalent to `sub nsw -1, %x`.
584 if (match(V, m_Not(m_Value(Op0)))) {
585 Decomposition Result(-1);
586 if (!Result.sub(decompose(Op0, Info, IsSigned, DL)))
587 return Result;
588 return V;
589 }
590
591 if (match(V, m_NSWSub(m_Value(Op0), m_Value(Op1)))) {
592 auto ResA = decompose(Op0, Info, IsSigned, DL);
593 auto ResB = decompose(Op1, Info, IsSigned, DL);
594 if (!ResA.sub(ResB))
595 return ResA;
596 return V;
597 }
598
599 ConstantInt *CI;
600 if (match(V, m_NSWMul(m_Value(Op0), m_ConstantInt(CI))) && canUseSExt(CI)) {
601 auto Result = decompose(Op0, Info, IsSigned, DL);
602 if (!Result.mul(CI->getSExtValue()))
603 return Result;
604 return V;
605 }
606
607 // (shl nsw x, shift) is (mul nsw x, (1<<shift)), with the exception of
608 // shift == bw-1.
609 if (match(V, m_NSWShl(m_Value(Op0), m_ConstantInt(CI)))) {
610 uint64_t Shift = CI->getValue().getLimitedValue();
611 if (Shift < Ty->getIntegerBitWidth() - 1) {
612 assert(Shift < 64 && "Would overflow");
613 auto Result = decompose(Op0, Info, IsSigned, DL);
614 if (!Result.mul(int64_t(1) << Shift))
615 return Result;
616 return V;
617 }
618 }
619
620 return V;
621 }
622
623 if (auto *CI = dyn_cast<ConstantInt>(V)) {
624 if (CI->uge(MaxConstraintValue))
625 return V;
626 return int64_t(CI->getZExtValue());
627 }
628
629 Value *Op0;
630 if (match(V, m_ZExt(m_Value(Op0)))) {
631 V = Op0;
632 } else if (match(V, m_SExt(m_Value(Op0)))) {
633 // Looking through the sext is only valid if the operand is non-negative.
634 if (!preconditionHolds(Info, CmpInst::ICMP_SGE, Op0, 0))
635 return V;
636 V = Op0;
637 } else if (auto *Trunc = dyn_cast<TruncInst>(V)) {
638 if (Trunc->getSrcTy()->getScalarSizeInBits() <= 64 &&
639 (Trunc->hasNoUnsignedWrap() || Trunc->hasNoSignedWrap())) {
640 Value *Src = Trunc->getOperand(0);
641 // A trunc nsw only truncates without unsigned wrap if its operand is
642 // non-negative.
643 if (!Trunc->hasNoUnsignedWrap() &&
644 !preconditionHolds(Info, CmpInst::ICMP_SGE, Src, 0))
645 return V;
646 V = Src;
647 }
648 }
649
650 Value *Op1;
651 ConstantInt *CI;
652 if (match(V, m_NUWAdd(m_Value(Op0), m_Value(Op1)))) {
653 if (auto Decomp = MergeResults(Op0, Op1, IsSigned))
654 return *Decomp;
655 return V;
656 }
657
658 if (match(V, m_Add(m_Value(Op0), m_ConstantInt(CI))) && CI->isNegative() &&
659 canUseSExt(CI)) {
660 // Adding a negative constant only wraps if Op0 is smaller than it.
661 if (!preconditionHolds(Info, CmpInst::ICMP_UGE, Op0,
662 CI->getSExtValue() * -1))
663 return V;
664 if (auto Decomp = MergeResults(Op0, CI, true))
665 return *Decomp;
666 return V;
667 }
668
669 if (match(V, m_NSWAdd(m_Value(Op0), m_Value(Op1)))) {
670 // An add nsw only adds without unsigned wrap if both operands are
671 // non-negative.
672 if ((!isKnownNonNegative(Op0, DL) &&
673 !preconditionHolds(Info, CmpInst::ICMP_SGE, Op0, 0)) ||
674 (!isKnownNonNegative(Op1, DL) &&
675 !preconditionHolds(Info, CmpInst::ICMP_SGE, Op1, 0)))
676 return V;
677
678 if (auto Decomp = MergeResults(Op0, Op1, IsSigned))
679 return *Decomp;
680 return V;
681 }
682
683 // Decompose or as an add if there are no common bits between the operands.
684 if (match(V, m_DisjointOr(m_Value(Op0), m_ConstantInt(CI)))) {
685 if (auto Decomp = MergeResults(Op0, CI, IsSigned))
686 return *Decomp;
687 return V;
688 }
689
690 if (match(V, m_NUWShl(m_Value(Op1), m_ConstantInt(CI))) && canUseSExt(CI)) {
691 // The scale 1 << shift must fit in the signed coefficient, so reject a
692 // shift of 63, for which int64_t{1} << 63 is INT64_MIN.
693 if (CI->getSExtValue() < 0 || CI->getSExtValue() >= 63)
694 return V;
695 auto Result = decompose(Op1, Info, IsSigned, DL);
696 if (!Result.mul(int64_t{1} << CI->getSExtValue()))
697 return Result;
698 return V;
699 }
700
701 if (match(V, m_NUWMul(m_Value(Op1), m_ConstantInt(CI))) && canUseSExt(CI) &&
702 (!CI->isNegative())) {
703 auto Result = decompose(Op1, Info, IsSigned, DL);
704 if (!Result.mul(CI->getSExtValue()))
705 return Result;
706 return V;
707 }
708
709 if (match(V, m_Sub(m_Value(Op0), m_Value(Op1)))) {
710 // a - b can be decomposed when there is no unsigned wrap (either known via
711 // flag or proven as precondition).
713 !Info.doesHold(CmpInst::ICMP_ULE, Op1, Op0))
714 return V;
715 auto ResA = decompose(Op0, Info, IsSigned, DL);
716 auto ResB = decompose(Op1, Info, IsSigned, DL);
717 if (!ResA.sub(ResB))
718 return ResA;
719 return V;
720 }
721
722 return V;
723}
724
725ConstraintTy
726ConstraintInfo::getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
727 SmallVectorImpl<Value *> &NewVariables,
728 bool ForceSignedSystem) const {
729 assert(NewVariables.empty() && "NewVariables must be empty when passed in");
730 assert((!ForceSignedSystem || CmpInst::isEquality(Pred)) &&
731 "signed system can only be forced on eq/ne");
732
733 bool IsEq = false;
734 bool IsNe = false;
735
736 // Try to convert Pred to one of ULE/ULT/SLE/SLT.
737 switch (Pred) {
741 case CmpInst::ICMP_SGE: {
742 Pred = CmpInst::getSwappedPredicate(Pred);
743 std::swap(Op0, Op1);
744 break;
745 }
746 case CmpInst::ICMP_EQ:
747 if (!ForceSignedSystem && match(Op1, m_Zero())) {
748 Pred = CmpInst::ICMP_ULE;
749 } else {
750 IsEq = true;
751 Pred = CmpInst::ICMP_ULE;
752 }
753 break;
754 case CmpInst::ICMP_NE:
755 if (!ForceSignedSystem && match(Op1, m_Zero())) {
757 std::swap(Op0, Op1);
758 } else {
759 IsNe = true;
760 Pred = CmpInst::ICMP_ULE;
761 }
762 break;
763 default:
764 break;
765 }
766
767 if (Pred != CmpInst::ICMP_ULE && Pred != CmpInst::ICMP_ULT &&
768 Pred != CmpInst::ICMP_SLE && Pred != CmpInst::ICMP_SLT)
769 return {};
770
771 bool IsSigned = ForceSignedSystem || CmpInst::isSigned(Pred);
772 auto &Value2Index = getValue2Index(IsSigned);
773 auto ADec = decompose(Op0->stripPointerCastsSameRepresentation(), *this,
774 IsSigned, DL);
775 auto BDec = decompose(Op1->stripPointerCastsSameRepresentation(), *this,
776 IsSigned, DL);
777 int64_t Offset1 = ADec.Offset;
778 int64_t Offset2 = BDec.Offset;
779 if (MulOverflow(Offset1, int64_t(-1), Offset1))
780 return {};
781
782 auto &VariablesA = ADec.Vars;
783 auto &VariablesB = BDec.Vars;
784
785 // First try to look up \p V in Value2Index and NewVariables. Otherwise add a
786 // new entry to NewVariables.
787 auto GetOrAddIndex = [&Value2Index, &NewVariables](Value *V) -> unsigned {
788 auto V2I = Value2Index.find(V);
789 if (V2I != Value2Index.end())
790 return V2I->second;
791 unsigned Idx = find(NewVariables, V) - NewVariables.begin();
792 if (Idx == NewVariables.size())
793 NewVariables.push_back(V);
794 return Value2Index.size() + Idx + 1;
795 };
796
797 // Build result constraint, by first adding all coefficients from A and then
798 // subtracting all coefficients from B.
799 RowTy R(1, Entry(0, 0));
800 auto GetCoefficient = [&R](unsigned Idx) -> int64_t & {
801 // The entry for Idx, or the place to insert it at, is the first entry with
802 // an index >= Idx.
803 Entry *I =
804 find_if(drop_begin(R), [Idx](const Entry &E) { return E.Id >= Idx; });
805 if (I == R.end() || I->Id != Idx)
806 I = R.insert(I, Entry(0, Idx));
807 return I->Coefficient;
808 };
809 for (const auto &KV : VariablesA)
810 GetCoefficient(GetOrAddIndex(KV.Variable)) += KV.Coefficient;
811
812 for (const auto &KV : VariablesB) {
813 auto &Coeff = GetCoefficient(GetOrAddIndex(KV.Variable));
814 if (SubOverflow(Coeff, KV.Coefficient, Coeff))
815 return {};
816 }
817
818 int64_t OffsetSum;
819 if (AddOverflow(Offset1, Offset2, OffsetSum))
820 return {};
821 if (Pred == CmpInst::ICMP_SLT || Pred == CmpInst::ICMP_ULT)
822 if (AddOverflow(OffsetSum, int64_t(-1), OffsetSum))
823 return {};
824 R[0].Coefficient = OffsetSum;
825
826 // Drop coefficients that cancelled out.
827 erase_if(R, [](const Entry &E) { return E.Id != 0 && E.Coefficient == 0; });
828
829 // Remove any new variable without a coefficient in the row.
830 unsigned NumV2I = Value2Index.size();
831 NewVariables.truncate(R.back().Id > NumV2I ? R.back().Id - NumV2I : 0);
832
833 return ConstraintTy(std::move(R), Value2Index.size() + NewVariables.size(),
834 IsSigned, IsEq, IsNe);
835}
836
837ConstraintTy ConstraintInfo::getConstraintForSolving(CmpInst::Predicate Pred,
838 Value *Op0,
839 Value *Op1) const {
840 Constant *NullC = Constant::getNullValue(Op0->getType());
841 // Handle trivially true compares directly to avoid adding V UGE 0 constraints
842 // for all variables in the unsigned system.
843 if ((Pred == CmpInst::ICMP_ULE && Op0 == NullC) ||
844 (Pred == CmpInst::ICMP_UGE && Op1 == NullC)) {
845 // Return constraint that's trivially true.
846 return ConstraintTy(RowTy(1, Entry(0, 0)), /*NumVars=*/0,
847 /*IsSigned=*/false, /*IsEq=*/false, /*IsNe=*/false);
848 }
849
850 // If both operands are known to be non-negative, change signed predicates to
851 // unsigned ones. This increases the reasoning effectiveness in combination
852 // with the signed <-> unsigned transfer logic.
853 if (CmpInst::isSigned(Pred) &&
857
858 SmallVector<Value *> NewVariables;
859 ConstraintTy R = getConstraint(Pred, Op0, Op1, NewVariables);
860 if (!NewVariables.empty())
861 return {};
862 return R;
863}
864
865std::optional<bool>
866ConstraintTy::isImpliedBy(const ConstraintSystem &CS) const {
867 const auto &[SubCS, NewCoefficients] = CS.getSubSystem(Coefficients);
868 bool IsConditionImplied = SubCS.isConditionImplied(NewCoefficients);
869
870 if (IsEq || IsNe) {
871 auto NegatedOrEqual = ConstraintSystem::negateOrEqual(NewCoefficients);
872 bool IsNegatedOrEqualImplied =
873 !NegatedOrEqual.empty() && SubCS.isConditionImplied(NegatedOrEqual);
874
875 // In order to check that `%a == %b` is true (equality), both conditions `%a
876 // >= %b` and `%a <= %b` must hold true. When checking for equality (`IsEq`
877 // is true), we return true if they both hold, false in the other cases.
878 if (IsConditionImplied && IsNegatedOrEqualImplied)
879 return IsEq;
880
881 auto Negated = ConstraintSystem::negate(NewCoefficients);
882 bool IsNegatedImplied =
883 !Negated.empty() && SubCS.isConditionImplied(Negated);
884
885 auto StrictLessThan = ConstraintSystem::toStrictLessThan(NewCoefficients);
886 bool IsStrictLessThanImplied =
887 !StrictLessThan.empty() && SubCS.isConditionImplied(StrictLessThan);
888
889 // In order to check that `%a != %b` is true (non-equality), either
890 // condition `%a > %b` or `%a < %b` must hold true. When checking for
891 // non-equality (`IsNe` is true), we return true if one of the two holds,
892 // false in the other cases.
893 if (IsNegatedImplied || IsStrictLessThanImplied)
894 return IsNe;
895
896 return std::nullopt;
897 }
898
899 if (IsConditionImplied)
900 return true;
901
902 auto Negated = ConstraintSystem::negate(NewCoefficients);
903 auto IsNegatedImplied = !Negated.empty() && SubCS.isConditionImplied(Negated);
904 if (IsNegatedImplied)
905 return false;
906
907 // Neither the condition nor its negated holds, did not prove anything.
908 return std::nullopt;
909}
910
911bool ConstraintInfo::doesHold(CmpInst::Predicate Pred, Value *A,
912 Value *B) const {
913 auto R = getConstraintForSolving(Pred, A, B);
914 return !R.empty() &&
915 getCS(R.IsSigned).isConditionImpliedInSubSystem(R.Coefficients);
916}
917
918bool ConstraintInfo::isKnownNonNegative(Value *V) const {
919 return doesHold(CmpInst::ICMP_SGE, V, ConstantInt::get(V->getType(), 0)) ||
921}
922
923void ConstraintInfo::transferToOtherSystem(
924 CmpInst::Predicate Pred, Value *A, Value *B, unsigned NumIn,
925 unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack) {
926 // Check if we can combine facts from the signed and unsigned systems to
927 // derive additional facts.
928 if (!A->getType()->isIntegerTy())
929 return;
930 // FIXME: This currently depends on the order we add facts. Ideally we
931 // would first add all known facts and only then try to add additional
932 // facts.
933 switch (Pred) {
934 default:
935 break;
938 // If B is a signed positive constant, then A >=s 0 and A <s (or <=s) B.
939 if (isKnownNonNegative(B)) {
940 addFact(CmpInst::ICMP_SGE, A, ConstantInt::get(B->getType(), 0), NumIn,
941 NumOut, DFSInStack);
942 addFact(ICmpInst::getSignedPredicate(Pred), A, B, NumIn, NumOut,
943 DFSInStack);
944 }
945 break;
948 // If A is a signed positive constant, then B >=s 0 and A >s (or >=s) B.
949 if (isKnownNonNegative(A)) {
950 addFact(CmpInst::ICMP_SGE, B, ConstantInt::get(B->getType(), 0), NumIn,
951 NumOut, DFSInStack);
952 addFact(ICmpInst::getSignedPredicate(Pred), A, B, NumIn, NumOut,
953 DFSInStack);
954 }
955 break;
959 addFact(ICmpInst::getUnsignedPredicate(Pred), A, B, NumIn, NumOut,
960 DFSInStack);
961 break;
962 case CmpInst::ICMP_SGT: {
963 if (doesHold(CmpInst::ICMP_SGE, B, Constant::getAllOnesValue(B->getType())))
964 addFact(CmpInst::ICMP_UGE, A, ConstantInt::get(B->getType(), 0), NumIn,
965 NumOut, DFSInStack);
967 addFact(CmpInst::ICMP_UGT, A, B, NumIn, NumOut, DFSInStack);
968
969 break;
970 }
973 addFact(CmpInst::ICMP_UGE, A, B, NumIn, NumOut, DFSInStack);
974 break;
975 }
976}
977
978#ifndef NDEBUG
979
981 const DenseMap<Value *, unsigned> &Value2Index) {
982 ConstraintSystem CS(Value2Index);
983 CS.addRow(C, Value2Index.size());
984 CS.dump();
985}
986#endif
987
988/// Splits the induction phi \p PN into the start value, coming from the loop
989/// predecessor \p LoopPred, and the backedge value, coming from inside the
990/// loop. Returns {nullptr, nullptr} if \p PN has other incoming values.
991static std::pair<Value *, Value *>
992getStartAndBackedgeValue(const PHINode &PN, const BasicBlock *LoopPred) {
993 assert(PN.getBasicBlockIndex(LoopPred) >= 0 &&
994 "LoopPred must be a predecessor of the phi's block");
995 if (PN.getNumIncomingValues() != 2)
996 return {nullptr, nullptr};
997 unsigned StartIdx = PN.getIncomingBlock(0) == LoopPred ? 0 : 1;
998 return {PN.getIncomingValue(StartIdx), PN.getIncomingValue(1 - StartIdx)};
999}
1000
1001MonotonicInfo State::getMonotonicityInfo(PHINode &PN, Value *Step) {
1002 MonotonicInfo Info;
1003 const APInt *StepOffset = nullptr;
1004 if (match(Step, m_c_Add(m_Specific(&PN), m_APInt(StepOffset)))) {
1005 Info.Decreasing = StepOffset->isNegative();
1006 const auto *Add = cast<OverflowingBinaryOperator>(Step);
1007 Info.Unsigned = !Info.Decreasing && Add->hasNoUnsignedWrap();
1008 Info.Signed = Add->hasNoSignedWrap();
1009 } else if (const auto *GEP = dyn_cast<GEPOperator>(Step)) {
1010 // TODO: Handle the non-increasing direction, which needs a nusw GEP with a
1011 // negative constant offset.
1012 const DataLayout &DL = PN.getDataLayout();
1013 APInt GEPOffset(DL.getIndexTypeSizeInBits(GEP->getType()), 0);
1014 Info.Unsigned = GEP->getPointerOperand() == &PN &&
1015 (GEP->hasNoUnsignedWrap() ||
1016 ((GEP->hasNoUnsignedSignedWrap() &&
1017 GEP->accumulateConstantOffset(DL, GEPOffset) &&
1018 !GEPOffset.isNegative())));
1019 }
1020
1021 // Forming the SCEV of a phi is expensive, so only consult it for a PN + C
1022 // step whose no-wrap flags prove nothing.
1023 if (Info.Unsigned || Info.Signed || !StepOffset)
1024 return Info;
1025
1026 const auto *AR = dyn_cast<SCEVAddRecExpr>(SE.getSCEV(&PN));
1027 if (!AR)
1028 return Info;
1032 auto IsMonotonic = [&](CmpInst::Predicate Pred) {
1033 return SE.getMonotonicPredicateType(AR, Pred) == Expected;
1034 };
1035 Info.Signed = IsMonotonic(CmpInst::ICMP_SGT);
1036 Info.Unsigned = !Info.Decreasing && IsMonotonic(CmpInst::ICMP_UGT);
1037 return Info;
1038}
1039
1040void State::addBoundsForHeaderInductions(BasicBlock &BB) {
1041 Loop *L = LI.getLoopFor(&BB);
1042 if (!L || L->getHeader() != &BB)
1043 return;
1044 BasicBlock *LoopPred = L->getLoopPredecessor();
1045 if (!LoopPred)
1046 return;
1047
1048 DomTreeNode *DTN = DT.getNode(&BB);
1049 for (PHINode &PN : BB.phis()) {
1050 if (!PN.getType()->isIntegerTy() && !PN.getType()->isPointerTy())
1051 continue;
1052
1053 auto [Start, Step] = getStartAndBackedgeValue(PN, LoopPred);
1054 if (!Start)
1055 continue;
1056
1057 MonotonicInfo Info = getMonotonicityInfo(PN, Step);
1058 // Every variable in the unsigned system already has a `V >= 0` row, so a
1059 // zero start value would just duplicate it.
1060 if (match(Start, m_Zero()))
1061 Info.Unsigned = false;
1062 if (!Info.Unsigned && !Info.Signed)
1063 continue;
1064
1065 // A non-decreasing induction cannot step below its start value, and a
1066 // non-increasing one cannot step above it.
1067 Value *LHS = &PN, *RHS = Start;
1068 if (Info.Decreasing)
1069 std::swap(LHS, RHS);
1070 CmpPredicate Pred(Info.Unsigned ? CmpInst::ICMP_UGE : CmpInst::ICMP_SGE,
1071 /*HasSameSign=*/Info.Unsigned && Info.Signed);
1072 WorkList.push_back(FactOrCheck::getConditionFact(DTN, Pred, LHS, RHS));
1073 }
1074}
1075
1076void State::addInfoForInductions(BasicBlock &BB) {
1077 auto *L = LI.getLoopFor(&BB);
1078 if (!L)
1079 return;
1080
1081 BasicBlock *Header = L->getHeader();
1082 BasicBlock *Latch = L->getLoopLatch();
1083 if (Header != &BB && Latch != &BB)
1084 return;
1085
1086 // A is either a phi or a post-increment PN + C with constant step. For the
1087 // latter, extract the constant IncStep.
1088 Value *A;
1089 Value *B;
1090 PHINode *PN = nullptr;
1091 const APInt *IncStep = nullptr;
1092 CmpPredicate Pred;
1093 auto IndValue =
1094 m_Value(A, m_CombineOr(m_Phi(PN), m_c_Add(m_Phi(PN), m_APInt(IncStep))));
1095
1096 if (!match(BB.getTerminator(),
1097 m_Br(m_c_ICmp(Pred, IndValue, m_Value(B)), m_Value(), m_Value())))
1098 return;
1099 if (PN->getParent() != Header || PN->getNumIncomingValues() != 2 ||
1100 !SE.isSCEVable(PN->getType()))
1101 return;
1102
1103 // For latch conditions, we need to inject the condition that holds for the
1104 // next iteration into the header. We limit to post-inc conditions, for which
1105 // an original PN + Step != B condition results in a PN < B constraint in the
1106 // header, which also holds for the next loop iteration. This would no longer
1107 // be correct if the post-inc handling would inject a more precise PN + Step <
1108 // B constraint instead.
1109 if (&BB == Latch && !IncStep)
1110 return;
1111
1112 BasicBlock *InLoopSucc = nullptr;
1113 if (Pred == CmpInst::ICMP_NE)
1114 InLoopSucc = cast<CondBrInst>(BB.getTerminator())->getSuccessor(0);
1115 else if (Pred == CmpInst::ICMP_EQ)
1116 InLoopSucc = cast<CondBrInst>(BB.getTerminator())->getSuccessor(1);
1117 else
1118 return;
1119
1120 if (!L->contains(InLoopSucc) || !L->isLoopExiting(&BB) || InLoopSucc == &BB)
1121 return;
1122
1123 BasicBlock *LoopPred = L->getLoopPredecessor();
1124 if (!LoopPred || !L->isLoopInvariant(B))
1125 return;
1126
1127 auto [StartValue, Backedge] = getStartAndBackedgeValue(*PN, LoopPred);
1128 const APInt *StepOffset = nullptr;
1129 const SCEV *StartSCEV = nullptr;
1130 if (match(Backedge, m_c_Add(m_Specific(PN), m_APInt(StepOffset)))) {
1131 if (StepOffset->isZero())
1132 return;
1133 } else {
1134 const SCEV *Expr = SE.getSCEV(PN);
1135 if (!match(Expr,
1136 m_scev_AffineAddRec(m_SCEV(StartSCEV), m_scev_APInt(StepOffset),
1137 m_SpecificLoop(L))))
1138 return;
1139 }
1140
1141 DomTreeNode *DTN = DT.getNode(InLoopSucc);
1142
1143 // If we looked through `PN + C`, only derive facts when that add is
1144 // really the induction's post-increment or post-decrement.
1145 if (IncStep && *IncStep != *StepOffset)
1146 return;
1147
1148 MonotonicInfo Info = getMonotonicityInfo(*PN, Backedge);
1149
1150 // Handle negative steps.
1151 if (StepOffset->isNegative()) {
1152 // TODO: Extend to allow steps > -1.
1153 if (!(-*StepOffset).isOne())
1154 return;
1155
1156 // AR may wrap.
1157 // The loop exits once the compared value reaches B, that is at PN == B when
1158 // comparing the phi, and at PN == B + 1 for a post-decrement. Use
1159 // non-strict predicate for the former, and a strict one for the latter to
1160 // ensure the loop exits before wrapping.
1161 CmpInst::Predicate UPrecond =
1163 ConditionTy BBeforeStartUnsigned = {UPrecond, B, StartValue};
1164 ConditionTy BBeforeStartSigned = {ICmpInst::getSignedPredicate(UPrecond), B,
1165 StartValue};
1166
1167 // AR may wrap, so both facts are conditional on B being below StartValue.
1168 // Add StartValue >= PN, which holds as the loop exits before wrapping.
1169 WorkList.push_back(FactOrCheck::getConditionFact(
1170 DTN, CmpInst::ICMP_UGE, StartValue, PN, BBeforeStartUnsigned));
1171 if (!(Info.Decreasing && Info.Signed))
1172 WorkList.push_back(FactOrCheck::getConditionFact(
1173 DTN, CmpInst::ICMP_SGE, StartValue, PN, BBeforeStartSigned));
1174 // Add PN > B, which holds as the loop exits when reaching B.
1175 WorkList.push_back(FactOrCheck::getConditionFact(DTN, CmpInst::ICMP_UGT, PN,
1176 B, BBeforeStartUnsigned));
1177 WorkList.push_back(FactOrCheck::getConditionFact(DTN, CmpInst::ICMP_SGT, PN,
1178 B, BBeforeStartSigned));
1179 return;
1180 }
1181
1182 // Make sure AR either steps by 1 or that the value we compare against is a
1183 // GEP based on the same start value and all offsets are a multiple of the
1184 // step size, to guarantee that the induction will reach the value.
1185 if (StepOffset->isZero() || StepOffset->isNegative())
1186 return;
1187
1188 if (!StepOffset->isOne()) {
1189 // Check whether B-Start is known to be a multiple of StepOffset.
1190 if (!StartSCEV)
1191 StartSCEV = SE.getSCEV(StartValue);
1192 const SCEV *BMinusStart = SE.getMinusSCEV(SE.getSCEV(B), StartSCEV);
1193 if (isa<SCEVCouldNotCompute>(BMinusStart) ||
1194 !SE.getConstantMultiple(BMinusStart).urem(*StepOffset).isZero())
1195 return;
1196 }
1197
1198 Value *LowerBound = StartValue;
1199 bool LowerBoundNUW = true, LowerBoundNSW = true;
1200 if (IncStep) {
1201 auto *StartC = dyn_cast<ConstantInt>(StartValue);
1202 if (!StartC)
1203 return;
1204 bool UOverflow = false, SOverflow = false;
1205 APInt Sum = StartC->getValue().uadd_ov(*StepOffset, UOverflow);
1206 (void)StartC->getValue().sadd_ov(*StepOffset, SOverflow);
1207 LowerBound = ConstantInt::get(StartValue->getType(), Sum);
1208 LowerBoundNUW = !UOverflow;
1209 LowerBoundNSW = !SOverflow;
1210 }
1211
1212 // AR may wrap. Add PN >= StartValue conditional on LowerBound <= B, which
1213 // guarantees that the loop exits before wrapping in combination with the
1214 // restrictions on B and the step above.
1215 ConditionTy StartBeforeBoundULE = {CmpInst::ICMP_ULE, LowerBound, B};
1216 ConditionTy StartBeforeBoundSLE = {CmpInst::ICMP_SLE, LowerBound, B};
1217 if (!Info.Unsigned && LowerBoundNUW)
1218 WorkList.push_back(FactOrCheck::getConditionFact(
1219 DTN, CmpInst::ICMP_UGE, PN, StartValue, StartBeforeBoundULE));
1220 if (!Info.Signed && LowerBoundNSW)
1221 WorkList.push_back(FactOrCheck::getConditionFact(
1222 DTN, CmpInst::ICMP_SGE, PN, StartValue, StartBeforeBoundSLE));
1223
1224 if (LowerBoundNSW)
1225 WorkList.push_back(FactOrCheck::getConditionFact(DTN, CmpInst::ICMP_SLT, PN,
1226 B, StartBeforeBoundSLE));
1227
1228 if (!LowerBoundNUW)
1229 return;
1230
1231 WorkList.push_back(FactOrCheck::getConditionFact(DTN, CmpInst::ICMP_ULT, PN,
1232 B, StartBeforeBoundULE));
1233
1234 // Try to add condition from the header or latch to the dedicated exit
1235 // blocks. When exiting either with EQ or NE, we know that the induction value
1236 // must be u<= B, as other exits may only exit earlier.
1237 assert(!StepOffset->isNegative() && "induction must be increasing");
1238 assert((Pred == CmpInst::ICMP_EQ || Pred == CmpInst::ICMP_NE) &&
1239 "unsupported predicate");
1241 L->getExitBlocks(ExitBBs);
1242 for (BasicBlock *EB : ExitBBs) {
1243 // Bail out on non-dedicated exits.
1244 if (DT.dominates(&BB, EB)) {
1245 WorkList.emplace_back(FactOrCheck::getConditionFact(
1246 DT.getNode(EB), CmpInst::ICMP_ULE, A, B, StartBeforeBoundULE));
1247 }
1248 }
1249}
1250
1252 uint64_t AccessSize,
1253 CmpPredicate &Pred, Value *&A,
1254 Value *&B, const DataLayout &DL,
1255 const TargetLibraryInfo &TLI) {
1257 if (!Offset.NW.hasNoUnsignedWrap())
1258 return false;
1259
1260 if (Offset.VariableOffsets.size() != 1)
1261 return false;
1262
1263 uint64_t BitWidth = Offset.ConstantOffset.getBitWidth();
1264 auto &[Index, Scale] = Offset.VariableOffsets.front();
1265 // Bail out on non-canonical GEPs.
1266 if (Index->getType()->getScalarSizeInBits() != BitWidth)
1267 return false;
1268
1269 ObjectSizeOpts Opts;
1270 // Workaround for gep inbounds, ptr null, idx.
1271 Opts.NullIsUnknownSize = true;
1272 // Be conservative since we are not clear on whether an out of bounds access
1273 // to the padding is UB or not.
1274 Opts.RoundToAlign = true;
1275 std::optional<TypeSize> Size =
1276 getBaseObjectSize(Offset.BasePtr, DL, &TLI, Opts);
1277 if (!Size || Size->isScalable())
1278 return false;
1279
1280 // Index * Scale + ConstOffset + AccessSize <= AllocSize
1281 // With nuw flag, we know that the index addition doesn't have unsigned wrap.
1282 // If (AllocSize - (ConstOffset + AccessSize)) wraps around, there is no valid
1283 // value for Index.
1284 APInt MaxIndex = (APInt(BitWidth, Size->getFixedValue() - AccessSize,
1285 /*isSigned=*/false, /*implicitTrunc=*/true) -
1286 Offset.ConstantOffset)
1287 .udiv(Scale);
1288 Pred = ICmpInst::ICMP_ULE;
1289 A = Index;
1290 B = ConstantInt::get(Index->getType(), MaxIndex);
1291 return true;
1292}
1293
1294/// Returns true if \p I is a candidate whose poison-generating flags may be
1295/// strengthened using the constraint systems.
1297 switch (I->getOpcode()) {
1298 case Instruction::Sub:
1299 // A - B does not wrap unsigned, if A >=u B. Subs with constant operands get
1300 // canonicalized to Add.
1301 return I->getType()->isIntegerTy() && !I->hasNoUnsignedWrap() &&
1302 !isa<Constant>(I->getOperand(1));
1303 default:
1304 return false;
1305 }
1306}
1307
1308/// Try to strengthen \p I's poison generating flags using \p Info. Returns
1309/// true if \p I was modified.
1310static bool tryToStrengthenFlags(Instruction *I, ConstraintInfo &Info,
1312 assert(canStrengthenFlags(I) && "not a candidate for flag strengthening");
1313
1314 switch (I->getOpcode()) {
1315 case Instruction::Sub: {
1316 // Op0 - Op1 does not wrap unsigned, if Op0 >=u Op1.
1317 if (!Info.doesHold(CmpInst::ICMP_UGE, I->getOperand(0), I->getOperand(1)))
1318 return false;
1319 LLVM_DEBUG(dbgs() << "Adding nuw to " << *I << "\n");
1320 I->setHasNoUnsignedWrap();
1321 return true;
1322 }
1323 default:
1324 return false;
1325 }
1326}
1327
1328void State::addInfoFor(BasicBlock &BB) {
1329 addBoundsForHeaderInductions(BB);
1330 addInfoForInductions(BB);
1331 auto &DL = BB.getDataLayout();
1332
1333 Value *A, *B;
1334 CmpPredicate Pred;
1335 // True as long as the current instruction is guaranteed to execute.
1336 bool GuaranteedToExecute = true;
1337 // Queue conditions and assumes.
1338 for (Instruction &I : BB) {
1339 if (match(&I, m_ICmpLike(Pred, m_Value(), m_Value()))) {
1340 for (Use &U : I.uses()) {
1341 auto *UserI = getContextInstForUse(U);
1342 auto *DTN = DT.getNode(UserI->getParent());
1343 if (!DTN)
1344 continue;
1345 WorkList.push_back(FactOrCheck::getCheck(DTN, &U));
1346 }
1347 continue;
1348 }
1349
1350 auto AddFactFromMemoryAccess = [&](Value *Ptr, Type *AccessType) {
1351 auto *GEP = dyn_cast<GetElementPtrInst>(Ptr);
1352 if (!GEP)
1353 return;
1354 TypeSize AccessSize = DL.getTypeStoreSize(AccessType);
1355 if (!AccessSize.isFixed())
1356 return;
1357 if (GuaranteedToExecute) {
1359 Pred, A, B, DL, TLI)) {
1360 // The memory access is guaranteed to execute when BB is entered,
1361 // hence the constraint holds on entry to BB.
1362 WorkList.emplace_back(FactOrCheck::getConditionFact(
1363 DT.getNode(I.getParent()), Pred, A, B));
1364 }
1365 } else {
1366 WorkList.emplace_back(
1367 FactOrCheck::getInstFact(DT.getNode(I.getParent()), &I));
1368 }
1369 };
1370
1371 if (auto *LI = dyn_cast<LoadInst>(&I)) {
1372 if (!LI->isVolatile())
1373 AddFactFromMemoryAccess(LI->getPointerOperand(), LI->getAccessType());
1374 }
1375 if (auto *SI = dyn_cast<StoreInst>(&I)) {
1376 if (!SI->isVolatile())
1377 AddFactFromMemoryAccess(SI->getPointerOperand(), SI->getAccessType());
1378 }
1379
1380 auto *II = dyn_cast<IntrinsicInst>(&I);
1381 Intrinsic::ID ID = II ? II->getIntrinsicID() : Intrinsic::not_intrinsic;
1382 switch (ID) {
1383 case Intrinsic::assume: {
1384 if (!match(I.getOperand(0), m_ICmpLike(Pred, m_Value(A), m_Value(B))))
1385 break;
1386 if (GuaranteedToExecute) {
1387 // The assume is guaranteed to execute when BB is entered, hence Cond
1388 // holds on entry to BB.
1389 WorkList.emplace_back(FactOrCheck::getConditionFact(
1390 DT.getNode(I.getParent()), Pred, A, B));
1391 } else {
1392 WorkList.emplace_back(
1393 FactOrCheck::getInstFact(DT.getNode(I.getParent()), &I));
1394 }
1395 break;
1396 }
1397 // Enqueue ssub_with_overflow for simplification.
1398 case Intrinsic::ssub_with_overflow:
1399 case Intrinsic::ucmp:
1400 case Intrinsic::scmp:
1401 WorkList.push_back(
1402 FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
1403 break;
1404 // Enqueue the intrinsics to add extra info.
1405 case Intrinsic::umin:
1406 case Intrinsic::umax:
1407 case Intrinsic::smin:
1408 case Intrinsic::smax:
1409 // TODO: handle llvm.abs as well
1410 WorkList.push_back(
1411 FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
1412 [[fallthrough]];
1413 case Intrinsic::uadd_sat:
1414 case Intrinsic::usub_sat:
1415 // TODO: Check if it is possible to instead only added the min/max facts
1416 // when simplifying uses of the min/max intrinsics.
1418 break;
1419 [[fallthrough]];
1420 case Intrinsic::abs:
1421 WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I));
1422 break;
1423 }
1424
1425 // Add facts from unsigned division, remainder and logical shift right, and
1426 // from signed remainder.
1427 // urem x, n: result < n and result <= x
1428 // udiv x, n: result <= x
1429 // lshr x, n: result <= x
1430 // srem x, n: result >= 0 and result <= x, if x >= 0
1431 // result < n, if n > 0
1432 if (auto *BO = dyn_cast<BinaryOperator>(&I)) {
1433 if ((BO->getOpcode() == Instruction::URem ||
1434 BO->getOpcode() == Instruction::UDiv ||
1435 BO->getOpcode() == Instruction::LShr ||
1436 BO->getOpcode() == Instruction::SRem) &&
1438 WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), BO));
1439 }
1440
1441 // Queue instructions whose flags may be strengthened based on the facts
1442 // that hold on entry to BB.
1443 if (canStrengthenFlags(&I))
1444 WorkList.push_back(FactOrCheck::getCheck(DT.getNode(&BB), &I));
1445
1446 GuaranteedToExecute &= isGuaranteedToTransferExecutionToSuccessor(&I);
1447 }
1448
1449 if (auto *Switch = dyn_cast<SwitchInst>(BB.getTerminator())) {
1450 for (auto &Case : Switch->cases()) {
1451 BasicBlock *Succ = Case.getCaseSuccessor();
1452 Value *V = Case.getCaseValue();
1453 if (!canAddSuccessor(BB, Succ))
1454 continue;
1455 WorkList.emplace_back(FactOrCheck::getConditionFact(
1456 DT.getNode(Succ), CmpInst::ICMP_EQ, Switch->getCondition(), V));
1457 }
1458 return;
1459 }
1460
1461 auto *Br = dyn_cast<CondBrInst>(BB.getTerminator());
1462 if (!Br)
1463 return;
1464
1465 Value *Cond = Br->getCondition();
1466
1467 // If the condition is a chain of ORs/AND and the successor only has the
1468 // current block as predecessor, queue conditions for the successor.
1469 Value *Op0, *Op1;
1470 if (match(Cond, m_LogicalOr(m_Value(Op0), m_Value(Op1))) ||
1471 match(Cond, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) {
1472 bool IsOr = match(Cond, m_LogicalOr());
1473 bool IsAnd = match(Cond, m_LogicalAnd());
1474 // If there's a select that matches both AND and OR, we need to commit to
1475 // one of the options. Arbitrarily pick OR.
1476 if (IsOr && IsAnd)
1477 IsAnd = false;
1478
1479 BasicBlock *Successor = Br->getSuccessor(IsOr ? 1 : 0);
1480 if (canAddSuccessor(BB, Successor)) {
1481 SmallVector<Value *> CondWorkList;
1482 SmallPtrSet<Value *, 8> SeenCond;
1483 auto QueueValue = [&CondWorkList, &SeenCond](Value *V) {
1484 if (SeenCond.insert(V).second)
1485 CondWorkList.push_back(V);
1486 };
1487 QueueValue(Op1);
1488 QueueValue(Op0);
1489 while (!CondWorkList.empty()) {
1490 Value *Cur = CondWorkList.pop_back_val();
1491 if (match(Cur, m_ICmpLike(Pred, m_Value(A), m_Value(B)))) {
1492 WorkList.emplace_back(FactOrCheck::getConditionFact(
1493 DT.getNode(Successor),
1494 IsOr ? CmpPredicate::getInverse(Pred) : Pred, A, B));
1495 continue;
1496 }
1497 if (IsOr && match(Cur, m_LogicalOr(m_Value(Op0), m_Value(Op1)))) {
1498 QueueValue(Op1);
1499 QueueValue(Op0);
1500 continue;
1501 }
1502 if (IsAnd && match(Cur, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) {
1503 QueueValue(Op1);
1504 QueueValue(Op0);
1505 continue;
1506 }
1507 }
1508 }
1509 return;
1510 }
1511
1512 if (!match(Br->getCondition(), m_ICmpLike(Pred, m_Value(A), m_Value(B))))
1513 return;
1514 if (canAddSuccessor(BB, Br->getSuccessor(0)))
1515 WorkList.emplace_back(FactOrCheck::getConditionFact(
1516 DT.getNode(Br->getSuccessor(0)), Pred, A, B));
1517 if (canAddSuccessor(BB, Br->getSuccessor(1)))
1518 WorkList.emplace_back(FactOrCheck::getConditionFact(
1519 DT.getNode(Br->getSuccessor(1)), CmpPredicate::getInverse(Pred), A, B));
1520}
1521
1522#ifndef NDEBUG
1524 Value *LHS, Value *RHS) {
1525 OS << "icmp " << Pred << ' ';
1526 LHS->printAsOperand(OS, /*PrintType=*/true);
1527 OS << ", ";
1528 RHS->printAsOperand(OS, /*PrintType=*/false);
1529}
1530#endif
1531
1532namespace {
1533/// Helper to keep track of a condition and if it should be treated as negated
1534/// for reproducer construction.
1535/// Pred == Predicate::BAD_ICMP_PREDICATE indicates that this entry is a
1536/// placeholder to keep the ReproducerCondStack in sync with DFSInStack.
1537struct ReproducerEntry {
1538 ICmpInst::Predicate Pred;
1539 Value *LHS;
1540 Value *RHS;
1541
1542 ReproducerEntry(ICmpInst::Predicate Pred, Value *LHS, Value *RHS)
1543 : Pred(Pred), LHS(LHS), RHS(RHS) {}
1544};
1545} // namespace
1546
1547/// Helper function to generate a reproducer function for simplifying \p Cond.
1548/// The reproducer function contains a series of @llvm.assume calls, one for
1549/// each condition in \p Stack. For each condition, the operand instruction are
1550/// cloned until we reach operands that have an entry in \p Value2Index. Those
1551/// will then be added as function arguments. \p DT is used to order cloned
1552/// instructions. The reproducer function will get added to \p M, if it is
1553/// non-null. Otherwise no reproducer function is generated.
1554static void generateReproducer(Instruction *Cond, bool IsSigned, Module *M,
1556 ConstraintInfo &Info, DominatorTree &DT) {
1557 if (!M)
1558 return;
1559
1560 LLVMContext &Ctx = Cond->getContext();
1561
1562 LLVM_DEBUG(dbgs() << "Creating reproducer for " << *Cond << "\n");
1563
1564 ValueToValueMapTy Old2New;
1567 // Traverse Cond and its operands recursively until we reach a value that's in
1568 // Value2Index or not an instruction, or not a operation that
1569 // ConstraintElimination can decompose. Such values will be considered as
1570 // external inputs to the reproducer, they are collected and added as function
1571 // arguments later.
1572 auto CollectArguments = [&](ArrayRef<Value *> Ops, bool IsSigned) {
1573 auto &Value2Index = Info.getValue2Index(IsSigned);
1574 SmallVector<Value *, 4> WorkList(Ops);
1575 while (!WorkList.empty()) {
1576 Value *V = WorkList.pop_back_val();
1577 if (!Seen.insert(V).second)
1578 continue;
1579 if (Old2New.find(V) != Old2New.end())
1580 continue;
1581 if (isa<Constant>(V))
1582 continue;
1583
1584 auto *I = dyn_cast<Instruction>(V);
1585 if (Value2Index.contains(V) || !I ||
1587 Old2New[V] = V;
1588 Args.push_back(V);
1589 LLVM_DEBUG(dbgs() << " found external input " << *V << "\n");
1590 } else {
1591 append_range(WorkList, I->operands());
1592 }
1593 }
1594 };
1595
1596 for (auto &Entry : Stack)
1597 if (Entry.Pred != ICmpInst::BAD_ICMP_PREDICATE)
1598 CollectArguments({Entry.LHS, Entry.RHS}, ICmpInst::isSigned(Entry.Pred));
1599 CollectArguments(Cond, IsSigned);
1600
1601 SmallVector<Type *> ParamTys;
1602 for (auto *P : Args)
1603 ParamTys.push_back(P->getType());
1604
1605 FunctionType *FTy = FunctionType::get(Cond->getType(), ParamTys,
1606 /*isVarArg=*/false);
1608 Cond->getModule()->getName() +
1609 Cond->getFunction()->getName() + "repro",
1610 M);
1611 // Add arguments to the reproducer function for each external value collected.
1612 for (unsigned I = 0; I < Args.size(); ++I) {
1613 F->getArg(I)->setName(Args[I]->getName());
1614 Old2New[Args[I]] = F->getArg(I);
1615 }
1616
1617 BasicBlock *Entry = BasicBlock::Create(Ctx, "entry", F);
1618 IRBuilder<> Builder(Entry);
1619 Builder.CreateRet(Builder.getTrue());
1620 Builder.SetInsertPoint(Entry->getTerminator());
1621
1622 // Clone instructions in \p Ops and their operands recursively until reaching
1623 // an value in Value2Index (external input to the reproducer). Update Old2New
1624 // mapping for the original and cloned instructions. Sort instructions to
1625 // clone by dominance, then insert the cloned instructions in the function.
1626 auto CloneInstructions = [&](ArrayRef<Value *> Ops, bool IsSigned) {
1627 SmallVector<Value *, 4> WorkList(Ops);
1629 auto &Value2Index = Info.getValue2Index(IsSigned);
1630 while (!WorkList.empty()) {
1631 Value *V = WorkList.pop_back_val();
1632 if (Old2New.find(V) != Old2New.end())
1633 continue;
1634
1635 auto *I = dyn_cast<Instruction>(V);
1636 if (!Value2Index.contains(V) && I) {
1637 Old2New[V] = nullptr;
1638 ToClone.push_back(I);
1639 append_range(WorkList, I->operands());
1640 }
1641 }
1642
1643 sort(ToClone,
1644 [&DT](Instruction *A, Instruction *B) { return DT.dominates(A, B); });
1645 for (Instruction *I : ToClone) {
1646 Instruction *Cloned = I->clone();
1647 Old2New[I] = Cloned;
1648 Old2New[I]->setName(I->getName());
1649 Cloned->insertBefore(Builder.GetInsertPoint());
1651 Cloned->setDebugLoc({});
1652 }
1653 };
1654
1655 // Materialize the assumptions for the reproducer using the entries in Stack.
1656 // That is, first clone the operands of the condition recursively until we
1657 // reach an external input to the reproducer and add them to the reproducer
1658 // function. Then add an ICmp for the condition (with the inverse predicate if
1659 // the entry is negated) and an assert using the ICmp.
1660 for (auto &Entry : Stack) {
1661 if (Entry.Pred == ICmpInst::BAD_ICMP_PREDICATE)
1662 continue;
1663
1664 LLVM_DEBUG(dbgs() << " Materializing assumption ";
1665 dumpUnpackedICmp(dbgs(), Entry.Pred, Entry.LHS, Entry.RHS);
1666 dbgs() << "\n");
1667 CloneInstructions({Entry.LHS, Entry.RHS}, CmpInst::isSigned(Entry.Pred));
1668
1669 auto *Cmp = Builder.CreateICmp(Entry.Pred, Entry.LHS, Entry.RHS);
1670 Builder.CreateAssumption(Cmp);
1671 }
1672
1673 // Finally, clone the condition to reproduce and remap instruction operands in
1674 // the reproducer using Old2New.
1675 CloneInstructions(Cond, IsSigned);
1676 Entry->getTerminator()->setOperand(0, Cond);
1677 remapInstructionsInBlocks({Entry}, Old2New);
1678
1679 assert(!verifyFunction(*F, &dbgs()));
1680}
1681
1682static std::optional<bool> checkCondition(CmpInst::Predicate Pred, Value *A,
1683 Value *B, Instruction *CheckInst,
1684 ConstraintInfo &Info) {
1685 LLVM_DEBUG(dbgs() << "Checking " << *CheckInst << "\n");
1686
1687 auto TryWithConstraint = [&](const ConstraintTy &R) -> std::optional<bool> {
1688 if (R.empty()) {
1689 LLVM_DEBUG(dbgs() << " failed to decompose condition\n");
1690 return std::nullopt;
1691 }
1692
1693 auto &CSToUse = Info.getCS(R.IsSigned);
1694 if (auto ImpliedCondition = R.isImpliedBy(CSToUse)) {
1695 if (!DebugCounter::shouldExecute(EliminatedCounter))
1696 return std::nullopt;
1697 LLVM_DEBUG({
1698 dbgs() << "Condition ";
1700 *ImpliedCondition ? Pred
1702 A, B);
1703 dbgs() << " implied by dominating constraints\n";
1704 CSToUse.dump();
1705 });
1706 return ImpliedCondition;
1707 }
1708 return std::nullopt;
1709 };
1710
1711 auto R = Info.getConstraintForSolving(Pred, A, B);
1712 if (auto ImpliedCondition = TryWithConstraint(R))
1713 return ImpliedCondition;
1714
1715 // For non-negative operands unsigned queries can also be checked against the
1716 // signed system.
1717 if (CmpInst::isUnsigned(Pred) && A->getType()->isIntegerTy()) {
1718 SmallVector<Value *> NewVariables;
1719 auto SR = Info.getConstraint(ICmpInst::getSignedPredicate(Pred), A, B,
1720 NewVariables);
1721 if (NewVariables.empty() && !SR.empty() && Info.isKnownNonNegative(A) &&
1722 Info.isKnownNonNegative(B))
1723 if (auto ImpliedCondition = TryWithConstraint(SR))
1724 return ImpliedCondition;
1725 }
1726
1727 // Additionally, query the signed system for eq/ne predicates if we know about
1728 // A or B.
1729 if (CmpInst::isEquality(Pred)) {
1730 const auto &Value2Index = Info.getValue2Index(/*Signed=*/true);
1731 if (!Value2Index.contains(A) && !Value2Index.contains(B))
1732 return std::nullopt;
1733
1734 SmallVector<Value *> NewVariables;
1735 auto SR = Info.getConstraint(Pred, A, B, NewVariables,
1736 /*ForceSignedSystem=*/true);
1737 if (NewVariables.empty())
1738 if (auto ImpliedCondition = TryWithConstraint(SR))
1739 return ImpliedCondition;
1740 }
1741 return std::nullopt;
1742}
1743
1745 CmpPredicate Pred, Value *A, Value *B, Instruction *CheckInst,
1746 ConstraintInfo &Info, unsigned NumIn, unsigned NumOut,
1747 Instruction *ContextInst, Module *ReproducerModule,
1748 ArrayRef<ReproducerEntry> ReproducerCondStack, DominatorTree &DT,
1750 auto ReplaceCmpWithConstant = [&](Instruction *CheckInst, bool IsTrue) {
1751 generateReproducer(CheckInst, ICmpInst::isSigned(Pred), ReproducerModule,
1752 ReproducerCondStack, Info, DT);
1753 Constant *ConstantC = ConstantInt::getBool(
1754 CmpInst::makeCmpResultType(CheckInst->getType()), IsTrue);
1755 bool Changed = CheckInst->replaceUsesWithIf(ConstantC, [&](Use &U) {
1756 auto *UserI = getContextInstForUse(U);
1757 auto *DTN = DT.getNode(UserI->getParent());
1758 if (!DTN || DTN->getDFSNumIn() < NumIn || DTN->getDFSNumOut() > NumOut)
1759 return false;
1760 if (UserI->getParent() == ContextInst->getParent() &&
1761 UserI->comesBefore(ContextInst))
1762 return false;
1763
1764 // Conditions in an assume trivially simplify to true. Skip uses
1765 // in assume calls to not destroy the available information.
1766 auto *II = dyn_cast<IntrinsicInst>(U.getUser());
1767 return !II || II->getIntrinsicID() != Intrinsic::assume;
1768 });
1769 NumCondsRemoved++;
1770
1771 // Update the debug value records that satisfy the same condition used
1772 // in replaceUsesWithIf.
1774 findDbgUsers(CheckInst, DVRUsers);
1775
1776 for (auto *DVR : DVRUsers) {
1777 auto *DTN = DT.getNode(DVR->getParent());
1778 if (!DTN || DTN->getDFSNumIn() < NumIn || DTN->getDFSNumOut() > NumOut)
1779 continue;
1780
1781 auto *MarkedI = DVR->getInstruction();
1782 if (MarkedI->getParent() == ContextInst->getParent() &&
1783 MarkedI->comesBefore(ContextInst))
1784 continue;
1785
1786 DVR->replaceVariableLocationOp(CheckInst, ConstantC);
1787 }
1788
1789 if (CheckInst->use_empty())
1790 ToRemove.push_back(CheckInst);
1791
1792 return Changed;
1793 };
1794
1795 if (auto ImpliedCondition = checkCondition(Pred, A, B, CheckInst, Info))
1796 return ReplaceCmpWithConstant(CheckInst, *ImpliedCondition);
1797
1798 // When the predicate is samesign and unsigned, we can also make use of the
1799 // signed predicate information.
1800 if (Pred.hasSameSign() && ICmpInst::isUnsigned(Pred))
1801 if (auto ImpliedCondition = checkCondition(
1802 ICmpInst::getSignedPredicate(Pred), A, B, CheckInst, Info))
1803 return ReplaceCmpWithConstant(CheckInst, *ImpliedCondition);
1804
1805 return false;
1806}
1807
1808static bool checkAndReplaceMinMax(MinMaxIntrinsic *MinMax, ConstraintInfo &Info,
1810 auto ReplaceMinMaxWithOperand = [&](MinMaxIntrinsic *MinMax, bool UseLHS) {
1811 // TODO: generate reproducer for min/max.
1812 MinMax->replaceAllUsesWith(MinMax->getOperand(UseLHS ? 0 : 1));
1813 ToRemove.push_back(MinMax);
1814 return true;
1815 };
1816
1817 ICmpInst::Predicate Pred =
1818 ICmpInst::getNonStrictPredicate(MinMax->getPredicate());
1819 if (auto ImpliedCondition = checkCondition(
1820 Pred, MinMax->getOperand(0), MinMax->getOperand(1), MinMax, Info))
1821 return ReplaceMinMaxWithOperand(MinMax, *ImpliedCondition);
1822 if (auto ImpliedCondition = checkCondition(
1823 Pred, MinMax->getOperand(1), MinMax->getOperand(0), MinMax, Info))
1824 return ReplaceMinMaxWithOperand(MinMax, !*ImpliedCondition);
1825 return false;
1826}
1827
1828static bool checkAndReplaceCmp(CmpIntrinsic *I, ConstraintInfo &Info,
1830 Value *LHS = I->getOperand(0);
1831 Value *RHS = I->getOperand(1);
1832 if (checkCondition(I->getGTPredicate(), LHS, RHS, I, Info).value_or(false)) {
1833 I->replaceAllUsesWith(ConstantInt::get(I->getType(), 1));
1834 ToRemove.push_back(I);
1835 return true;
1836 }
1837 if (checkCondition(I->getLTPredicate(), LHS, RHS, I, Info).value_or(false)) {
1838 I->replaceAllUsesWith(ConstantInt::getSigned(I->getType(), -1));
1839 ToRemove.push_back(I);
1840 return true;
1841 }
1842 if (checkCondition(ICmpInst::ICMP_EQ, LHS, RHS, I, Info).value_or(false)) {
1843 I->replaceAllUsesWith(ConstantInt::get(I->getType(), 0));
1844 ToRemove.push_back(I);
1845 return true;
1846 }
1847 return false;
1848}
1849
1850static void
1851removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info,
1852 Module *ReproducerModule,
1853 SmallVectorImpl<ReproducerEntry> &ReproducerCondStack,
1854 SmallVectorImpl<StackEntry> &DFSInStack) {
1855 Info.popLastConstraint(E.IsSigned);
1856 // Remove variables in the system that went out of scope.
1857 auto &Mapping = Info.getValue2Index(E.IsSigned);
1858 for (Value *V : E.ValuesToRelease)
1859 Mapping.erase(V);
1860 Info.popLastNVariables(E.IsSigned, E.ValuesToRelease.size());
1861 DFSInStack.pop_back();
1862 if (ReproducerModule)
1863 ReproducerCondStack.pop_back();
1864}
1865
1866/// Check if either the first condition of an AND or OR is implied by the
1867/// (negated in case of OR) second condition or vice versa.
1869 FactOrCheck &CB, ConstraintInfo &Info, Module *ReproducerModule,
1870 SmallVectorImpl<ReproducerEntry> &ReproducerCondStack,
1871 SmallVectorImpl<StackEntry> &DFSInStack,
1873 Instruction *JoinOp = CB.getContextInst();
1874 if (JoinOp->use_empty())
1875 return false;
1876
1877 Instruction *CmpToCheck = cast<Instruction>(CB.getInstructionToSimplify());
1878 unsigned OtherOpIdx = JoinOp->getOperand(0) == CmpToCheck ? 1 : 0;
1879
1880 // Don't try to simplify the first condition of a select by the second, as
1881 // this may make the select more poisonous than the original one.
1882 // TODO: check if the first operand may be poison.
1883 if (OtherOpIdx != 0 && isa<SelectInst>(JoinOp))
1884 return false;
1885
1886 unsigned OldSize = DFSInStack.size();
1887 llvm::scope_exit InfoRestorer([&]() {
1888 // Remove entries again.
1889 while (OldSize < DFSInStack.size()) {
1890 StackEntry E = DFSInStack.back();
1891 removeEntryFromStack(E, Info, ReproducerModule, ReproducerCondStack,
1892 DFSInStack);
1893 }
1894 });
1895 bool IsOr = match(JoinOp, m_LogicalOr());
1896 SmallVector<Value *, 4> Worklist({JoinOp->getOperand(OtherOpIdx)});
1897 // Do a traversal of the AND/OR tree to add facts from leaf compares.
1898 while (!Worklist.empty()) {
1899 Value *Val = Worklist.pop_back_val();
1900 Value *LHS, *RHS;
1901 CmpPredicate Pred;
1902 if (match(Val, m_ICmpLike(Pred, m_Value(LHS), m_Value(RHS)))) {
1903 // For OR, check if the negated condition implies CmpToCheck.
1904 if (IsOr)
1905 Pred = CmpInst::getInversePredicate(Pred);
1906 // Optimistically add fact from the other compares in the AND/OR.
1907 Info.addFact(Pred, LHS, RHS, CB.NumIn, CB.NumOut, DFSInStack);
1908 continue;
1909 }
1910 if (IsOr ? match(Val, m_LogicalOr(m_Value(LHS), m_Value(RHS)))
1911 : match(Val, m_LogicalAnd(m_Value(LHS), m_Value(RHS)))) {
1912 Worklist.push_back(LHS);
1913 Worklist.push_back(RHS);
1914 }
1915 }
1916 if (OldSize == DFSInStack.size())
1917 return false;
1918
1919 Value *A, *B;
1920 CmpPredicate Pred;
1921 [[maybe_unused]] bool Matched =
1922 match(CmpToCheck, m_ICmpLike(Pred, m_Value(A), m_Value(B)));
1923 assert(Matched && "expected icmp-like match");
1924 // Check if the second condition can be simplified now.
1925 if (auto ImpliedCondition = checkCondition(Pred, A, B, CmpToCheck, Info)) {
1926 if (IsOr == *ImpliedCondition)
1927 JoinOp->replaceAllUsesWith(
1928 ConstantInt::getBool(JoinOp->getType(), *ImpliedCondition));
1929 else
1930 JoinOp->replaceAllUsesWith(JoinOp->getOperand(OtherOpIdx));
1931 ToRemove.push_back(JoinOp);
1932 return true;
1933 }
1934
1935 return false;
1936}
1937
1938void ConstraintInfo::addFact(CmpInst::Predicate Pred, Value *A, Value *B,
1939 unsigned NumIn, unsigned NumOut,
1940 SmallVectorImpl<StackEntry> &DFSInStack) {
1941 addFactImpl(Pred, A, B, NumIn, NumOut, DFSInStack, false);
1942 // If the Pred is eq/ne, also add the fact to signed system.
1943 if (CmpInst::isEquality(Pred))
1944 addFactImpl(Pred, A, B, NumIn, NumOut, DFSInStack, true);
1945 if (Pred == CmpInst::ICMP_NE)
1946 tightenBoundUsingNe(A, B, NumIn, NumOut, DFSInStack);
1947}
1948
1949void ConstraintInfo::tightenBoundUsingNe(
1950 Value *A, Value *B, unsigned NumIn, unsigned NumOut,
1951 SmallVectorImpl<StackEntry> &DFSInStack) {
1952 if (!A->getType()->isIntegerTy())
1953 return;
1954
1955 for (bool IsSigned : {false, true}) {
1956 // In the unsigned system `A u>= 0` holds for every A, so getConstraint
1957 // already turned `A != 0` into `A u> 0`.
1958 if (!IsSigned && match(B, m_Zero()))
1959 continue;
1960
1961 // Skip if there are any unknown variables.
1962 const auto &Value2Index = getValue2Index(IsSigned);
1963 if (any_of(decompose(A, *this, IsSigned, DL).Vars,
1964 [&Value2Index](const DecompEntry &E) {
1965 return !Value2Index.contains(E.Variable);
1966 }))
1967 continue;
1968
1969 // If the system implies `A >= B` then together with `A != B` we get the
1970 // strict `A > B`; symmetrically `A <= B` becomes `A < B`.
1971 CmpInst::Predicate GEPred =
1973 CmpInst::Predicate LEPred =
1975 for (CmpInst::Predicate NonStrict : {GEPred, LEPred}) {
1976 if (!doesHold(NonStrict, A, B))
1977 continue;
1979 LLVM_DEBUG(dbgs() << "Tightening '";
1980 dumpUnpackedICmp(dbgs(), NonStrict, A, B); dbgs() << "' to '";
1982 dbgs() << "' using inequality\n");
1983 addFactImpl(Strict, A, B, NumIn, NumOut, DFSInStack,
1984 /*ForceSignedSystem=*/false);
1985 break;
1986 }
1987 }
1988}
1989
1990void ConstraintInfo::addFactImpl(CmpInst::Predicate Pred, Value *A, Value *B,
1991 unsigned NumIn, unsigned NumOut,
1992 SmallVectorImpl<StackEntry> &DFSInStack,
1993 bool ForceSignedSystem) {
1994 SmallVector<Value *> NewVariables;
1995 auto R = getConstraint(Pred, A, B, NewVariables, ForceSignedSystem);
1996
1997 // TODO: Support non-equality for facts as well.
1998 if (R.empty() || R.isNe())
1999 return;
2000
2001 LLVM_DEBUG(dbgs() << "Adding '"; dumpUnpackedICmp(dbgs(), Pred, A, B);
2002 dbgs() << "'\n");
2003 auto &CSToUse = getCS(R.IsSigned);
2004 bool Added = CSToUse.addRow(R.Coefficients, R.NumVars);
2005 if (!Added)
2006 return;
2007
2008 // If R has been added to the system, add the new variables and queue it for
2009 // removal once it goes out-of-scope.
2010 SmallVector<Value *, 2> ValuesToRelease;
2011 auto &Value2Index = getValue2Index(R.IsSigned);
2012 for (Value *V : NewVariables) {
2013 Value2Index.try_emplace(V, Value2Index.size() + 1);
2014 ValuesToRelease.push_back(V);
2015 }
2016
2017 LLVM_DEBUG({
2018 dbgs() << " constraint: ";
2019 dumpConstraint(R.Coefficients, getValue2Index(R.IsSigned));
2020 dbgs() << "\n";
2021 });
2022
2023 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
2024 std::move(ValuesToRelease));
2025
2026 if (!R.IsSigned) {
2027 for (Value *V : NewVariables) {
2028 // Add V > -1 constraints for all new variables.
2029 CSToUse.addRow({Entry(0, 0), Entry(-1, Value2Index.at(V))},
2030 Value2Index.size());
2031 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
2032 SmallVector<Value *, 2>());
2033 }
2034 }
2035
2036 if (R.isEq()) {
2037 // Also add the inverted constraint for equality constraints.
2038 for (Entry &E : R.Coefficients)
2039 if (MulOverflow(E.Coefficient, int64_t(-1), E.Coefficient))
2040 return;
2041 CSToUse.addRow(R.Coefficients, R.NumVars);
2042
2043 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
2044 SmallVector<Value *, 2>());
2045 }
2046}
2047
2050 bool Changed = false;
2051 IRBuilder<> Builder(II->getParent(), II->getIterator());
2052 Value *Sub = nullptr;
2053 for (User *U : make_early_inc_range(II->users())) {
2054 if (match(U, m_ExtractValue<0>(m_Value()))) {
2055 if (!Sub)
2056 Sub = Builder.CreateNSWSub(A, B);
2057 U->replaceAllUsesWith(Sub);
2058 Changed = true;
2059 } else if (match(U, m_ExtractValue<1>(m_Value()))) {
2060 U->replaceAllUsesWith(Builder.getFalse());
2061 Changed = true;
2062 } else
2063 continue;
2064
2065 if (U->use_empty()) {
2066 auto *I = cast<Instruction>(U);
2067 ToRemove.push_back(I);
2068 I->setOperand(0, PoisonValue::get(II->getType()));
2069 Changed = true;
2070 }
2071 }
2072
2073 if (II->use_empty()) {
2074 // Do not erase II here: the worklist may still hold Uses of II's operands.
2075 for (Use &Arg : II->args())
2076 Arg.set(PoisonValue::get(Arg->getType()));
2077 ToRemove.push_back(II);
2078 Changed = true;
2079 }
2080 return Changed;
2081}
2082
2083static bool
2086 auto DoesConditionHold = [](CmpInst::Predicate Pred, Value *A, Value *B,
2087 ConstraintInfo &Info) {
2088 auto R = Info.getConstraintForSolving(Pred, A, B);
2089 // Nothing can be proven if the constraint has no variables. This also
2090 // covers rows that could not be decomposed, which are empty.
2091 if (R.isConstantOnly())
2092 return false;
2093
2094 auto &CSToUse = Info.getCS(R.IsSigned);
2095 return CSToUse.isConditionImpliedInSubSystem(R.Coefficients);
2096 };
2097
2098 bool Changed = false;
2099 if (II->getIntrinsicID() == Intrinsic::ssub_with_overflow) {
2100 // If A s>= B && B s>= 0, ssub.with.overflow(a, b) should not overflow and
2101 // can be simplified to a regular sub.
2102 Value *A = II->getArgOperand(0);
2103 Value *B = II->getArgOperand(1);
2104 if (!DoesConditionHold(CmpInst::ICMP_SGE, A, B, Info) ||
2105 !DoesConditionHold(CmpInst::ICMP_SGE, B,
2106 ConstantInt::get(A->getType(), 0), Info))
2107 return false;
2109 }
2110 return Changed;
2111}
2112
2114 ScalarEvolution &SE,
2116 TargetLibraryInfo &TLI) {
2117 bool Changed = false;
2118 DT.updateDFSNumbers();
2119 SmallVector<Value *> FunctionArgs(llvm::make_pointer_range(F.args()));
2120 ConstraintInfo Info(F.getDataLayout(), FunctionArgs);
2121 State S(DT, LI, SE, TLI);
2122 std::unique_ptr<Module> ReproducerModule(
2123 DumpReproducers ? new Module(F.getName(), F.getContext()) : nullptr);
2124
2125 // First, collect conditions implied by branches and blocks with their
2126 // Dominator DFS in and out numbers.
2127 for (BasicBlock &BB : F) {
2128 if (!DT.getNode(&BB))
2129 continue;
2130 S.addInfoFor(BB);
2131 }
2132
2133 // Next, sort worklist by dominance, so that dominating conditions to check
2134 // and facts come before conditions and facts dominated by them. If a
2135 // condition to check and a fact have the same numbers, conditional facts come
2136 // first. Assume facts and checks are ordered according to their relative
2137 // order in the containing basic block. Also make sure conditions with
2138 // constant operands come before conditions without constant operands. This
2139 // increases the effectiveness of the current signed <-> unsigned fact
2140 // transfer logic.
2141 stable_sort(S.WorkList, [](const FactOrCheck &A, const FactOrCheck &B) {
2142 auto HasNoConstOp = [](const FactOrCheck &B) {
2143 Value *V0 = B.isConditionFact() ? B.Cond.Op0 : B.Inst->getOperand(0);
2144 Value *V1 = B.isConditionFact() ? B.Cond.Op1 : B.Inst->getOperand(1);
2145 return !isa<ConstantInt>(V0) && !isa<ConstantInt>(V1);
2146 };
2147 // If both entries have the same In numbers, conditional facts come first.
2148 // Otherwise use the relative order in the basic block.
2149 if (A.NumIn == B.NumIn) {
2150 if (A.isConditionFact() && B.isConditionFact()) {
2151 bool NoConstOpA = HasNoConstOp(A);
2152 bool NoConstOpB = HasNoConstOp(B);
2153 return NoConstOpA < NoConstOpB;
2154 }
2155 if (A.isConditionFact())
2156 return true;
2157 if (B.isConditionFact())
2158 return false;
2159 auto *InstA = A.getContextInst();
2160 auto *InstB = B.getContextInst();
2161 return InstA->comesBefore(InstB);
2162 }
2163 return A.NumIn < B.NumIn;
2164 });
2165
2166 SmallVector<Instruction *> ToRemove;
2167
2168 // Finally, process ordered worklist and eliminate implied conditions.
2169 SmallVector<StackEntry, 16> DFSInStack;
2170 SmallVector<ReproducerEntry> ReproducerCondStack;
2171 for (FactOrCheck &CB : S.WorkList) {
2172 // First, pop entries from the stack that are out-of-scope for CB. Remove
2173 // the corresponding entry from the constraint system.
2174 while (!DFSInStack.empty()) {
2175 auto &E = DFSInStack.back();
2176 LLVM_DEBUG(dbgs() << "Top of stack : " << E.NumIn << " " << E.NumOut
2177 << "\n");
2178 LLVM_DEBUG(dbgs() << "CB: " << CB.NumIn << " " << CB.NumOut << "\n");
2179 assert(E.NumIn <= CB.NumIn);
2180 if (CB.NumOut <= E.NumOut)
2181 break;
2182 LLVM_DEBUG({
2183 dbgs() << "Removing ";
2184 dumpConstraint(Info.getCS(E.IsSigned).getLastConstraint(),
2185 Info.getValue2Index(E.IsSigned));
2186 dbgs() << "\n";
2187 });
2188 removeEntryFromStack(E, Info, ReproducerModule.get(), ReproducerCondStack,
2189 DFSInStack);
2190 }
2191
2192 CmpPredicate Pred;
2193 Value *A, *B;
2194 // For a block, check if any CmpInsts become known based on the current set
2195 // of constraints.
2196 if (CB.isCheck()) {
2197 Instruction *Inst = CB.getInstructionToSimplify();
2198 if (!Inst)
2199 continue;
2200 if (canStrengthenFlags(Inst)) {
2201 Changed |= tryToStrengthenFlags(Inst, Info, ToRemove);
2202 continue;
2203 }
2204 LLVM_DEBUG(dbgs() << "Processing condition to simplify: " << *Inst
2205 << "\n");
2206 if (auto *II = dyn_cast<WithOverflowInst>(Inst)) {
2208 } else if (match(Inst, m_ICmpLike(Pred, m_Value(A), m_Value(B)))) {
2210 Pred, A, B, Inst, Info, CB.NumIn, CB.NumOut, CB.getContextInst(),
2211 ReproducerModule.get(), ReproducerCondStack, S.DT, ToRemove);
2212 if (!Simplified &&
2213 match(CB.getContextInst(), m_LogicalOp(m_Value(), m_Value()))) {
2215 CB, Info, ReproducerModule.get(), ReproducerCondStack, DFSInStack,
2216 ToRemove);
2217 }
2219 } else if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(Inst)) {
2220 Changed |= checkAndReplaceMinMax(MinMax, Info, ToRemove);
2221 } else if (auto *CmpIntr = dyn_cast<CmpIntrinsic>(Inst)) {
2222 Changed |= checkAndReplaceCmp(CmpIntr, Info, ToRemove);
2223 }
2224 continue;
2225 }
2226
2227 auto AddFact = [&](CmpPredicate Pred, Value *A, Value *B) {
2228 LLVM_DEBUG(dbgs() << "Processing fact to add to the system: ";
2229 dumpUnpackedICmp(dbgs(), Pred, A, B); dbgs() << "\n");
2230 if (Info.getCS(CmpInst::isSigned(Pred)).size() > MaxRows) {
2231 LLVM_DEBUG(
2232 dbgs()
2233 << "Skip adding constraint because system has too many rows.\n");
2234 return;
2235 }
2236
2237 Info.addFact(Pred, A, B, CB.NumIn, CB.NumOut, DFSInStack);
2238 if (ReproducerModule && DFSInStack.size() > ReproducerCondStack.size())
2239 ReproducerCondStack.emplace_back(Pred, A, B);
2240
2241 if (ICmpInst::isRelational(Pred)) {
2242 // If samesign is present on the ICmp, simply flip the sign of the
2243 // predicate, transferring the information from the signed system to the
2244 // unsigned system, and viceversa.
2245 if (Pred.hasSameSign())
2247 CB.NumIn, CB.NumOut, DFSInStack);
2248 else
2249 Info.transferToOtherSystem(Pred, A, B, CB.NumIn, CB.NumOut,
2250 DFSInStack);
2251 }
2252
2253 // (X | Y) >s -1 implies X >s -1 and Y >s -1, because the sign bit of an
2254 // OR is the OR of the operand sign bits. Similarly, (X & Y) <s 0 implies
2255 // X <s 0 and Y <s 0. Look through these canonical forms produced by
2256 // InstCombine so the sign facts on the operands are available to the
2257 // solver.
2258 if ((Pred == CmpInst::ICMP_SGT && match(B, m_AllOnes())) ||
2259 (Pred == CmpInst::ICMP_SLT && match(B, m_Zero()))) {
2260 unsigned Opc =
2261 Pred == CmpInst::ICMP_SGT ? Instruction::Or : Instruction::And;
2262 SmallVector<Value *> Worklist = {A};
2263 SmallPtrSet<Value *, 4> Seen;
2264 while (!Worklist.empty()) {
2265 Value *Cur = Worklist.pop_back_val();
2266 auto *BO = dyn_cast<BinaryOperator>(Cur);
2267 if (!BO || BO->getOpcode() != Opc)
2268 continue;
2269 for (Value *Op : {BO->getOperand(0), BO->getOperand(1)}) {
2270 if (!Seen.insert(Op).second)
2271 continue;
2272 Worklist.push_back(Op);
2273 Info.addFact(Pred, Op, B, CB.NumIn, CB.NumOut, DFSInStack);
2274 }
2275 }
2276 }
2277
2278 if (ReproducerModule && DFSInStack.size() > ReproducerCondStack.size()) {
2279 // Add dummy entries to ReproducerCondStack to keep it in sync with
2280 // DFSInStack.
2281 for (unsigned I = 0,
2282 E = (DFSInStack.size() - ReproducerCondStack.size());
2283 I < E; ++I) {
2284 ReproducerCondStack.emplace_back(ICmpInst::BAD_ICMP_PREDICATE,
2285 nullptr, nullptr);
2286 }
2287 }
2288 };
2289
2290 if (!CB.isConditionFact()) {
2291 Value *X;
2292 if (match(CB.Inst, m_Intrinsic<Intrinsic::abs>(m_Value(X)))) {
2293 // If is_int_min_poison is true then we may assume llvm.abs >= 0.
2294 if (cast<ConstantInt>(CB.Inst->getOperand(1))->isOne())
2295 AddFact(CmpInst::ICMP_SGE, CB.Inst,
2296 ConstantInt::get(CB.Inst->getType(), 0));
2297 AddFact(CmpInst::ICMP_SGE, CB.Inst, X);
2298 continue;
2299 }
2300
2301 if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(CB.Inst)) {
2302 Pred = ICmpInst::getNonStrictPredicate(MinMax->getPredicate());
2303 AddFact(Pred, MinMax, MinMax->getLHS());
2304 AddFact(Pred, MinMax, MinMax->getRHS());
2305 continue;
2306 }
2307 if (auto *USatI = dyn_cast<SaturatingInst>(CB.Inst)) {
2308 switch (USatI->getIntrinsicID()) {
2309 default:
2310 llvm_unreachable("Unexpected intrinsic.");
2311 case Intrinsic::uadd_sat:
2312 AddFact(ICmpInst::ICMP_UGE, USatI, USatI->getLHS());
2313 AddFact(ICmpInst::ICMP_UGE, USatI, USatI->getRHS());
2314 break;
2315 case Intrinsic::usub_sat:
2316 AddFact(ICmpInst::ICMP_ULE, USatI, USatI->getLHS());
2317 break;
2318 }
2319 continue;
2320 }
2321
2322 if (auto *BO = dyn_cast<BinaryOperator>(CB.Inst)) {
2323 if (BO->getOpcode() == Instruction::URem) {
2324 // urem x, n: result < n (remainder is always less than divisor)
2325 AddFact(CmpInst::ICMP_ULT, BO, BO->getOperand(1));
2326 // urem x, n: result <= x (remainder is at most the dividend)
2327 AddFact(CmpInst::ICMP_ULE, BO, BO->getOperand(0));
2328 continue;
2329 }
2330 if (BO->getOpcode() == Instruction::UDiv) {
2331 // udiv x, n: result <= x (quotient is at most the dividend)
2332 AddFact(CmpInst::ICMP_ULE, BO, BO->getOperand(0));
2333 continue;
2334 }
2335 if (BO->getOpcode() == Instruction::LShr) {
2336 // lshr x, n: result <= x (right shift cannot increase the value)
2337 AddFact(CmpInst::ICMP_ULE, BO, BO->getOperand(0));
2338 continue;
2339 }
2340 if (BO->getOpcode() == Instruction::SRem) {
2341 Value *X = BO->getOperand(0);
2342 Value *N = BO->getOperand(1);
2343 Constant *Zero = Constant::getNullValue(BO->getType());
2344 if (Info.doesHold(CmpInst::ICMP_SGE, X, Zero) ||
2345 isKnownNonNegative(X, F.getDataLayout())) {
2346 // srem x, n: result >= 0, if x >= 0 (result has the sign of x)
2347 AddFact(CmpInst::ICMP_SGE, BO, Zero);
2348 // srem x, n: result <= x, if x >= 0 (|result| <= |x| and both are
2349 // non-negative)
2350 AddFact(CmpInst::ICMP_SLE, BO, X);
2351 }
2352 if (Info.doesHold(CmpInst::ICMP_SGE, N, Zero) ||
2353 isKnownPositive(N, F.getDataLayout())) {
2354 // srem x, n: result <= n, if n >= 0 (|result| < n, so result <= n -
2355 // 1
2356 AddFact(CmpInst::ICMP_SLT, BO, N);
2357 }
2358 continue;
2359 }
2360 }
2361
2362 auto &DL = F.getDataLayout();
2363 auto AddFactsAboutIndices = [&](Value *Ptr, Type *AccessType) {
2364 CmpPredicate Pred;
2365 Value *A, *B;
2368 DL.getTypeStoreSize(AccessType).getFixedValue(), Pred, A, B, DL,
2369 TLI))
2370 AddFact(Pred, A, B);
2371 };
2372
2373 if (auto *LI = dyn_cast<LoadInst>(CB.Inst)) {
2374 AddFactsAboutIndices(LI->getPointerOperand(), LI->getAccessType());
2375 continue;
2376 }
2377 if (auto *SI = dyn_cast<StoreInst>(CB.Inst)) {
2378 AddFactsAboutIndices(SI->getPointerOperand(), SI->getAccessType());
2379 continue;
2380 }
2381 }
2382
2383 if (CB.isConditionFact()) {
2384 Pred = CB.Cond.Pred;
2385 A = CB.Cond.Op0;
2386 B = CB.Cond.Op1;
2387 if (CB.DoesHold.Pred != CmpInst::BAD_ICMP_PREDICATE &&
2388 !Info.doesHold(CB.DoesHold.Pred, CB.DoesHold.Op0, CB.DoesHold.Op1)) {
2389 LLVM_DEBUG({
2390 dbgs() << "Not adding fact ";
2391 dumpUnpackedICmp(dbgs(), Pred, A, B);
2392 dbgs() << " because precondition ";
2393 dumpUnpackedICmp(dbgs(), CB.DoesHold.Pred, CB.DoesHold.Op0,
2394 CB.DoesHold.Op1);
2395 dbgs() << " does not hold.\n";
2396 });
2397 continue;
2398 }
2399 } else {
2400 [[maybe_unused]] bool Matched =
2402 m_ICmpLike(Pred, m_Value(A), m_Value(B))));
2403 assert(Matched &&
2404 "Must have an assume intrinsic with a icmp like operand");
2405 }
2406 AddFact(Pred, A, B);
2407 }
2408
2409 if (ReproducerModule && !ReproducerModule->functions().empty()) {
2410 std::string S;
2411 raw_string_ostream StringS(S);
2412 ReproducerModule->print(StringS, nullptr);
2413 OptimizationRemark Rem(DEBUG_TYPE, "Reproducer", &F);
2414 Rem << ore::NV("module") << S;
2415 ORE.emit(Rem);
2416 }
2417
2418#ifndef NDEBUG
2419 unsigned SignedEntries =
2420 count_if(DFSInStack, [](const StackEntry &E) { return E.IsSigned; });
2421 assert(Info.getCS(false).size() - FunctionArgs.size() ==
2422 DFSInStack.size() - SignedEntries &&
2423 "updates to CS and DFSInStack are out of sync");
2424 assert(Info.getCS(true).size() == SignedEntries &&
2425 "updates to CS and DFSInStack are out of sync");
2426#endif
2427
2428 for (Instruction *I : ToRemove)
2429 I->eraseFromParent();
2430 return Changed;
2431}
2432
2435 auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
2436 auto &LI = AM.getResult<LoopAnalysis>(F);
2437 auto &SE = AM.getResult<ScalarEvolutionAnalysis>(F);
2439 auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
2440 if (!eliminateConstraints(F, DT, LI, SE, ORE, TLI))
2441 return PreservedAnalyses::all();
2442
2446 return PA;
2447}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
ReachingDefInfo InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define X(NUM, ENUM, NAME)
Definition ELF.h:857
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
std::pair< ICmpInst *, unsigned > ConditionTy
static int64_t MaxConstraintValue
static bool canStrengthenFlags(Instruction *I)
Returns true if I is a candidate whose poison-generating flags may be strengthened using the constrai...
static int64_t MinSignedConstraintValue
static Instruction * getContextInstForUse(Use &U)
static bool preconditionHolds(const ConstraintInfo &Info, CmpInst::Predicate Pred, Value *Op, int64_t RHS)
Returns true if the pre-condition Op Pred RHS, required to look through an expression while decomposi...
static bool canUseSExt(ConstantInt *CI)
static void removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info, Module *ReproducerModule, SmallVectorImpl< ReproducerEntry > &ReproducerCondStack, SmallVectorImpl< StackEntry > &DFSInStack)
static std::optional< bool > checkCondition(CmpInst::Predicate Pred, Value *A, Value *B, Instruction *CheckInst, ConstraintInfo &Info)
static cl::opt< unsigned > MaxRows("constraint-elimination-max-rows", cl::init(500), cl::Hidden, cl::desc("Maximum number of rows to keep in constraint system"))
static cl::opt< bool > DumpReproducers("constraint-elimination-dump-reproducers", cl::init(false), cl::Hidden, cl::desc("Dump IR to reproduce successful transformations."))
static bool checkOrAndOpImpliedByOther(FactOrCheck &CB, ConstraintInfo &Info, Module *ReproducerModule, SmallVectorImpl< ReproducerEntry > &ReproducerCondStack, SmallVectorImpl< StackEntry > &DFSInStack, SmallVectorImpl< Instruction * > &ToRemove)
Check if either the first condition of an AND or OR is implied by the (negated in case of OR) second ...
static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI, ScalarEvolution &SE, OptimizationRemarkEmitter &ORE, TargetLibraryInfo &TLI)
static OffsetResult collectOffsets(GEPOperator &GEP, const DataLayout &DL)
static bool checkAndReplaceMinMax(MinMaxIntrinsic *MinMax, ConstraintInfo &Info, SmallVectorImpl< Instruction * > &ToRemove)
static Decomposition decompose(Value *V, const ConstraintInfo &Info, bool IsSigned, const DataLayout &DL)
static Decomposition decomposeGEP(GEPOperator &GEP, const ConstraintInfo &Info, bool IsSigned, const DataLayout &DL)
static void dumpConstraint(ArrayRef< Entry > C, const DenseMap< Value *, unsigned > &Value2Index)
static bool getConstraintFromMemoryAccess(GetElementPtrInst &GEP, uint64_t AccessSize, CmpPredicate &Pred, Value *&A, Value *&B, const DataLayout &DL, const TargetLibraryInfo &TLI)
static void dumpUnpackedICmp(raw_ostream &OS, ICmpInst::Predicate Pred, Value *LHS, Value *RHS)
static void generateReproducer(Instruction *Cond, bool IsSigned, Module *M, ArrayRef< ReproducerEntry > Stack, ConstraintInfo &Info, DominatorTree &DT)
Helper function to generate a reproducer function for simplifying Cond.
static bool checkAndReplaceCondition(CmpPredicate Pred, Value *A, Value *B, Instruction *CheckInst, ConstraintInfo &Info, unsigned NumIn, unsigned NumOut, Instruction *ContextInst, Module *ReproducerModule, ArrayRef< ReproducerEntry > ReproducerCondStack, DominatorTree &DT, SmallVectorImpl< Instruction * > &ToRemove)
static bool replaceSubOverflowUses(IntrinsicInst *II, Value *A, Value *B, SmallVectorImpl< Instruction * > &ToRemove)
static bool tryToSimplifyOverflowMath(IntrinsicInst *II, ConstraintInfo &Info, SmallVectorImpl< Instruction * > &ToRemove)
static bool tryToStrengthenFlags(Instruction *I, ConstraintInfo &Info, SmallVectorImpl< Instruction * > &ToRemove)
Try to strengthen I's poison generating flags using Info.
static bool checkAndReplaceCmp(CmpIntrinsic *I, ConstraintInfo &Info, SmallVectorImpl< Instruction * > &ToRemove)
static std::pair< Value *, Value * > getStartAndBackedgeValue(const PHINode &PN, const BasicBlock *LoopPred)
Splits the induction phi PN into the start value, coming from the loop predecessor LoopPred,...
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
#define DEBUG_TYPE
This is the interface for a simple mod/ref and alias analysis over globals.
Hexagon Common GEP
Module.h This file contains the declarations for the Module class.
static bool hasNoUnsignedWrap(BinaryOperator &I)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Machine Check Debug Module
uint64_t IntrinsicInst * II
#define P(N)
if(PassOpts->AAPipeline)
static StringRef getName(Value *V)
const SmallVectorImpl< MachineOperand > & Cond
This file contains some templates that are useful if you are working with the STL at all.
This file defines the scope_exit class, which executes user-defined cleanup logic at scope exit.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
Value * RHS
Value * LHS
Class for arbitrary precision integers.
Definition APInt.h:78
bool sgt(const APInt &RHS) const
Signed greater than comparison.
Definition APInt.h:1206
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
Definition APInt.h:377
LLVM_ABI APInt urem(const APInt &RHS) const
Unsigned remainder operation.
Definition APInt.cpp:1693
bool isNegative() const
Determine sign of this APInt.
Definition APInt.h:326
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:472
bool slt(const APInt &RHS) const
Signed less than comparison.
Definition APInt.h:1135
bool isOne() const
Determine if this is a value of 1.
Definition APInt.h:386
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
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
Definition BasicBlock.h:515
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this basic block belongs to.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Predicate getStrictPredicate() const
For example, SGE -> SGT, SLE -> SLT, ULE -> ULT, UGE -> UGT.
Definition InstrTypes.h:921
bool isEquality() const
Determine if this is an equals/not equals predicate.
Definition InstrTypes.h:978
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ ICMP_SLT
signed less than
Definition InstrTypes.h:769
@ ICMP_SLE
signed less or equal
Definition InstrTypes.h:770
@ ICMP_UGE
unsigned greater or equal
Definition InstrTypes.h:764
@ ICMP_UGT
unsigned greater than
Definition InstrTypes.h:763
@ ICMP_SGT
signed greater than
Definition InstrTypes.h:767
@ ICMP_ULT
unsigned less than
Definition InstrTypes.h:765
@ ICMP_NE
not equal
Definition InstrTypes.h:762
@ ICMP_SGE
signed greater or equal
Definition InstrTypes.h:768
@ ICMP_ULE
unsigned less or equal
Definition InstrTypes.h:766
bool isSigned() const
Definition InstrTypes.h:993
static LLVM_ABI bool isEquality(Predicate pred)
Determine if this is an equals/not equals predicate.
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Definition InstrTypes.h:890
Predicate getNonStrictPredicate() const
For example, SGT -> SGE, SLT -> SLE, ULT -> ULE, UGT -> UGE.
Definition InstrTypes.h:934
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Definition InstrTypes.h:852
bool isUnsigned() const
Definition InstrTypes.h:999
This class represents a ucmp/scmp intrinsic.
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
static LLVM_ABI CmpPredicate getInverse(CmpPredicate P)
Get the inverse predicate of a CmpPredicate.
bool hasSameSign() const
Query samesign information, for optimizations.
This is the shared class of boolean and integer constants.
Definition Constants.h:87
bool isNegative() const
Definition Constants.h:214
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
Definition Constants.h:135
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
Definition Constants.h:174
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition Constants.h:159
static LLVM_ABI ConstantInt * getBool(LLVMContext &Context, bool V)
This is an important base class in LLVM.
Definition Constant.h:43
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &)
bool addRow(ArrayRef< Entry > R, size_t NumVars)
static RowTy negate(RowTy R)
LLVM_ABI std::pair< ConstraintSystem, RowTy > getSubSystem(ArrayRef< Entry > R) const
Build and return a sub-system of constraints connected (transitively) to query R, with variables comp...
static RowTy toStrictLessThan(RowTy R)
Converts the given row to form a strict less than inequality.
SmallVector< Entry, 8 > RowTy
A single constraint of the form 'c >= v1 * c1 + ... + vn * cn'.
static RowTy negateOrEqual(RowTy R)
Multiplies each coefficient in the given row by -1.
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)
unsigned size() const
Definition DenseMap.h:172
unsigned getDFSNumIn() const
getDFSNumIn/getDFSNumOut - These return the DFS visitation order for nodes in the dominator tree.
unsigned getDFSNumOut() const
Analysis pass which computes a DominatorTree.
Definition Dominators.h:241
void updateDFSNumbers() const
updateDFSNumbers - Assign In and Out numbers to the nodes while walking dominator tree in dfs order.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition Function.h:168
static GEPNoWrapFlags none()
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
@ ExternalLinkage
Externally visible function.
Definition GlobalValue.h:53
Predicate getFlippedSignednessPredicate() const
For example, SLT->ULT, ULT->SLT, SLE->ULE, ULE->SLE, EQ->EQ.
Predicate getSignedPredicate() const
For example, EQ->EQ, SLE->SLE, UGT->SGT, etc.
bool isRelational() const
Return true if the predicate is relational (not EQ or NE).
Predicate getUnsignedPredicate() const
For example, EQ->EQ, SLE->ULE, UGT->UGT, etc.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2903
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.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
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:594
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.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
int getBasicBlockIndex(const BasicBlock *BB) const
Return the first index of the specified basic block in the value list for this PHI.
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.
MonotonicPredicateType
A predicate is said to be monotonically increasing if may go from being false to being true as the lo...
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 truncate(size_type N)
Like resize, but requires that N is less than size().
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
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:282
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
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
Value * getOperand(unsigned i) const
Definition User.h:207
iterator find(const KeyT &Val)
Definition ValueMap.h:160
iterator end()
Definition ValueMap.h:139
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:553
LLVM_ABI const Value * stripPointerCastsSameRepresentation() const
Strip off pointer casts, all-zero GEPs and address space casts but ensures the representation of the ...
Definition Value.cpp:721
bool use_empty() const
Definition Value.h:346
LLVM_ABI bool replaceUsesWithIf(Value *New, llvm::function_ref< bool(Use &U)> ShouldReplace)
Go through the uses list for this definition and make each use point to "V" if the callback ShouldRep...
Definition Value.cpp:561
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
constexpr bool isFixed() const
Returns true if the quantity is not scaled by vscale.
Definition TypeSize.h:171
const ParentTy * getParent() const
Definition ilist_node.h:34
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ Entry
Definition COFF.h:862
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
AllOnesConstantMatch m_AllOnes()
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
match_bind< PHINode > m_Phi(PHINode *&PN)
Match a PHI node, capturing it if we match.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWAdd(const LHS &L, const RHS &R)
auto m_LogicalOp()
Matches either L && R or L || R where L and R are arbitrary values.
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWSub(const LHS &L, const RHS &R)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
DisjointOr_match< LHS, RHS > m_DisjointOr(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst, true > m_c_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
Matches an ICmp with a predicate over LHS and RHS in either order.
ExtractValue_match< Ind, Val_t > m_ExtractValue(const Val_t &V)
Match a single index ExtractValue instruction.
ICmpLike_match< LHS, RHS > m_ICmpLike(CmpPredicate &Pred, const LHS &L, const RHS &R)
auto m_Value()
Match an arbitrary value and ignore it.
NoWrapTrunc_match< OpTy, TruncInst::NoSignedWrap > m_NSWTrunc(const OpTy &Op)
Matches trunc nsw.
NNegZExt_match< OpTy > m_NNegZExt(const OpTy &Op)
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoSignedWrap > m_NSWShl(const LHS &L, const RHS &R)
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWShl(const LHS &L, const RHS &R)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Mul, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWMul(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap > m_NSWAdd(const LHS &L, const RHS &R)
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
brc_match< Cond_t, match_bind< BasicBlock >, match_bind< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Mul, OverflowingBinaryOperator::NoSignedWrap > m_NSWMul(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
bind_cst_ty m_scev_APInt(const APInt *&C)
Match an SCEV constant and bind it to an APInt.
specificloop_ty m_SpecificLoop(const Loop *L)
bool match(const SCEV *S, const Pattern &P)
SCEVAffineAddRec_match< Op0_t, Op1_t, match_isa< const Loop > > m_scev_AffineAddRec(const Op0_t &Op0, const Op1_t &Op1)
initializer< Ty > init(const Ty &Val)
@ Switch
The "resume-switch" lowering, where there are separate resume and destroy functions that are shared b...
Definition CoroShape.h:32
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
bool empty() const
Definition BasicBlock.h:101
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:315
@ Offset
Definition DWP.cpp:578
void stable_sort(R &&Range)
Definition STLExtras.h:2116
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1765
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI bool verifyFunction(const Function &F, raw_ostream *OS=nullptr)
Check a function for errors, useful for use when debugging a pass.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2208
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:633
constexpr std::enable_if_t< std::is_signed_v< T >, std::pair< T, bool > > AddOverflow(T X, T Y)
Add two signed integers, computing the two's complement truncated result, returning a pair {result,...
Definition MathExtras.h:698
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...
const Value * getPointerOperand(const Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
DomTreeNodeBase< BasicBlock > DomTreeNode
Definition Dominators.h:65
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
constexpr std::enable_if_t< std::is_signed_v< T >, std::pair< T, bool > > SubOverflow(T X, T Y)
Subtract two signed integers, computing the two's complement truncated result, returning a pair {resu...
Definition MathExtras.h:735
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.
@ Add
Sum of integers.
DWARFExpression::Operation Op
LLVM_ABI void remapInstructionsInBlocks(ArrayRef< BasicBlock * > Blocks, ValueToValueMapTy &VMap)
Remaps instructions in Blocks using the mapping in VMap.
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1917
LLVM_ABI bool isGuaranteedToTransferExecutionToSuccessor(const Instruction *I)
Return true if this function can prove that the instruction I will always transfer execution to one o...
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
Definition STLExtras.h:2019
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1772
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition STLExtras.h:2192
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition iterator.h:368
constexpr std::enable_if_t< std::is_signed_v< T >, std::pair< T, bool > > MulOverflow(T X, T Y)
Multiply two signed integers, computing the two's complement truncated result, returning a pair {resu...
Definition MathExtras.h:772
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be poison, but may be undef.
LLVM_ABI bool isKnownPositive(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the given value is known be positive (i.e.
LLVM_ABI bool isKnownNonNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the give value is known to be non-negative.
LLVM_ABI void findDbgUsers(Value *V, SmallVectorImpl< DbgVariableRecord * > &DbgVariableRecords)
Finds the debug info records describing a value.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
Various options to control the behavior of getObjectSize.
bool NullIsUnknownSize
If this is true, null pointers in address space 0 will be treated as though they can't be evaluated.
bool RoundToAlign
Whether to round the result up to the alignment of allocas, byval arguments, and global variables.
A MapVector that performs no allocations if smaller than a certain size.
Definition MapVector.h:342