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).
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, CallInst *CI) {
150 return FactOrCheck(EntryTy::InstCheck, DTN, CI);
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
1294void State::addInfoFor(BasicBlock &BB) {
1295 addBoundsForHeaderInductions(BB);
1296 addInfoForInductions(BB);
1297 auto &DL = BB.getDataLayout();
1298
1299 Value *A, *B;
1300 CmpPredicate Pred;
1301 // True as long as the current instruction is guaranteed to execute.
1302 bool GuaranteedToExecute = true;
1303 // Queue conditions and assumes.
1304 for (Instruction &I : BB) {
1305 if (match(&I, m_ICmpLike(Pred, m_Value(), m_Value()))) {
1306 for (Use &U : I.uses()) {
1307 auto *UserI = getContextInstForUse(U);
1308 auto *DTN = DT.getNode(UserI->getParent());
1309 if (!DTN)
1310 continue;
1311 WorkList.push_back(FactOrCheck::getCheck(DTN, &U));
1312 }
1313 continue;
1314 }
1315
1316 auto AddFactFromMemoryAccess = [&](Value *Ptr, Type *AccessType) {
1317 auto *GEP = dyn_cast<GetElementPtrInst>(Ptr);
1318 if (!GEP)
1319 return;
1320 TypeSize AccessSize = DL.getTypeStoreSize(AccessType);
1321 if (!AccessSize.isFixed())
1322 return;
1323 if (GuaranteedToExecute) {
1325 Pred, A, B, DL, TLI)) {
1326 // The memory access is guaranteed to execute when BB is entered,
1327 // hence the constraint holds on entry to BB.
1328 WorkList.emplace_back(FactOrCheck::getConditionFact(
1329 DT.getNode(I.getParent()), Pred, A, B));
1330 }
1331 } else {
1332 WorkList.emplace_back(
1333 FactOrCheck::getInstFact(DT.getNode(I.getParent()), &I));
1334 }
1335 };
1336
1337 if (auto *LI = dyn_cast<LoadInst>(&I)) {
1338 if (!LI->isVolatile())
1339 AddFactFromMemoryAccess(LI->getPointerOperand(), LI->getAccessType());
1340 }
1341 if (auto *SI = dyn_cast<StoreInst>(&I)) {
1342 if (!SI->isVolatile())
1343 AddFactFromMemoryAccess(SI->getPointerOperand(), SI->getAccessType());
1344 }
1345
1346 auto *II = dyn_cast<IntrinsicInst>(&I);
1347 Intrinsic::ID ID = II ? II->getIntrinsicID() : Intrinsic::not_intrinsic;
1348 switch (ID) {
1349 case Intrinsic::assume: {
1350 if (!match(I.getOperand(0), m_ICmpLike(Pred, m_Value(A), m_Value(B))))
1351 break;
1352 if (GuaranteedToExecute) {
1353 // The assume is guaranteed to execute when BB is entered, hence Cond
1354 // holds on entry to BB.
1355 WorkList.emplace_back(FactOrCheck::getConditionFact(
1356 DT.getNode(I.getParent()), Pred, A, B));
1357 } else {
1358 WorkList.emplace_back(
1359 FactOrCheck::getInstFact(DT.getNode(I.getParent()), &I));
1360 }
1361 break;
1362 }
1363 // Enqueue ssub_with_overflow for simplification.
1364 case Intrinsic::ssub_with_overflow:
1365 case Intrinsic::ucmp:
1366 case Intrinsic::scmp:
1367 WorkList.push_back(
1368 FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
1369 break;
1370 // Enqueue the intrinsics to add extra info.
1371 case Intrinsic::umin:
1372 case Intrinsic::umax:
1373 case Intrinsic::smin:
1374 case Intrinsic::smax:
1375 // TODO: handle llvm.abs as well
1376 WorkList.push_back(
1377 FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
1378 [[fallthrough]];
1379 case Intrinsic::uadd_sat:
1380 case Intrinsic::usub_sat:
1381 // TODO: Check if it is possible to instead only added the min/max facts
1382 // when simplifying uses of the min/max intrinsics.
1384 break;
1385 [[fallthrough]];
1386 case Intrinsic::abs:
1387 WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I));
1388 break;
1389 }
1390
1391 // Add facts from unsigned division, remainder and logical shift right, and
1392 // from signed remainder.
1393 // urem x, n: result < n and result <= x
1394 // udiv x, n: result <= x
1395 // lshr x, n: result <= x
1396 // srem x, n: result >= 0 and result <= x, if x >= 0
1397 // result < n, if n > 0
1398 if (auto *BO = dyn_cast<BinaryOperator>(&I)) {
1399 if ((BO->getOpcode() == Instruction::URem ||
1400 BO->getOpcode() == Instruction::UDiv ||
1401 BO->getOpcode() == Instruction::LShr ||
1402 BO->getOpcode() == Instruction::SRem) &&
1404 WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), BO));
1405 }
1406
1407 GuaranteedToExecute &= isGuaranteedToTransferExecutionToSuccessor(&I);
1408 }
1409
1410 if (auto *Switch = dyn_cast<SwitchInst>(BB.getTerminator())) {
1411 for (auto &Case : Switch->cases()) {
1412 BasicBlock *Succ = Case.getCaseSuccessor();
1413 Value *V = Case.getCaseValue();
1414 if (!canAddSuccessor(BB, Succ))
1415 continue;
1416 WorkList.emplace_back(FactOrCheck::getConditionFact(
1417 DT.getNode(Succ), CmpInst::ICMP_EQ, Switch->getCondition(), V));
1418 }
1419 return;
1420 }
1421
1422 auto *Br = dyn_cast<CondBrInst>(BB.getTerminator());
1423 if (!Br)
1424 return;
1425
1426 Value *Cond = Br->getCondition();
1427
1428 // If the condition is a chain of ORs/AND and the successor only has the
1429 // current block as predecessor, queue conditions for the successor.
1430 Value *Op0, *Op1;
1431 if (match(Cond, m_LogicalOr(m_Value(Op0), m_Value(Op1))) ||
1432 match(Cond, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) {
1433 bool IsOr = match(Cond, m_LogicalOr());
1434 bool IsAnd = match(Cond, m_LogicalAnd());
1435 // If there's a select that matches both AND and OR, we need to commit to
1436 // one of the options. Arbitrarily pick OR.
1437 if (IsOr && IsAnd)
1438 IsAnd = false;
1439
1440 BasicBlock *Successor = Br->getSuccessor(IsOr ? 1 : 0);
1441 if (canAddSuccessor(BB, Successor)) {
1442 SmallVector<Value *> CondWorkList;
1443 SmallPtrSet<Value *, 8> SeenCond;
1444 auto QueueValue = [&CondWorkList, &SeenCond](Value *V) {
1445 if (SeenCond.insert(V).second)
1446 CondWorkList.push_back(V);
1447 };
1448 QueueValue(Op1);
1449 QueueValue(Op0);
1450 while (!CondWorkList.empty()) {
1451 Value *Cur = CondWorkList.pop_back_val();
1452 if (match(Cur, m_ICmpLike(Pred, m_Value(A), m_Value(B)))) {
1453 WorkList.emplace_back(FactOrCheck::getConditionFact(
1454 DT.getNode(Successor),
1455 IsOr ? CmpPredicate::getInverse(Pred) : Pred, A, B));
1456 continue;
1457 }
1458 if (IsOr && match(Cur, m_LogicalOr(m_Value(Op0), m_Value(Op1)))) {
1459 QueueValue(Op1);
1460 QueueValue(Op0);
1461 continue;
1462 }
1463 if (IsAnd && match(Cur, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) {
1464 QueueValue(Op1);
1465 QueueValue(Op0);
1466 continue;
1467 }
1468 }
1469 }
1470 return;
1471 }
1472
1473 if (!match(Br->getCondition(), m_ICmpLike(Pred, m_Value(A), m_Value(B))))
1474 return;
1475 if (canAddSuccessor(BB, Br->getSuccessor(0)))
1476 WorkList.emplace_back(FactOrCheck::getConditionFact(
1477 DT.getNode(Br->getSuccessor(0)), Pred, A, B));
1478 if (canAddSuccessor(BB, Br->getSuccessor(1)))
1479 WorkList.emplace_back(FactOrCheck::getConditionFact(
1480 DT.getNode(Br->getSuccessor(1)), CmpPredicate::getInverse(Pred), A, B));
1481}
1482
1483#ifndef NDEBUG
1485 Value *LHS, Value *RHS) {
1486 OS << "icmp " << Pred << ' ';
1487 LHS->printAsOperand(OS, /*PrintType=*/true);
1488 OS << ", ";
1489 RHS->printAsOperand(OS, /*PrintType=*/false);
1490}
1491#endif
1492
1493namespace {
1494/// Helper to keep track of a condition and if it should be treated as negated
1495/// for reproducer construction.
1496/// Pred == Predicate::BAD_ICMP_PREDICATE indicates that this entry is a
1497/// placeholder to keep the ReproducerCondStack in sync with DFSInStack.
1498struct ReproducerEntry {
1499 ICmpInst::Predicate Pred;
1500 Value *LHS;
1501 Value *RHS;
1502
1503 ReproducerEntry(ICmpInst::Predicate Pred, Value *LHS, Value *RHS)
1504 : Pred(Pred), LHS(LHS), RHS(RHS) {}
1505};
1506} // namespace
1507
1508/// Helper function to generate a reproducer function for simplifying \p Cond.
1509/// The reproducer function contains a series of @llvm.assume calls, one for
1510/// each condition in \p Stack. For each condition, the operand instruction are
1511/// cloned until we reach operands that have an entry in \p Value2Index. Those
1512/// will then be added as function arguments. \p DT is used to order cloned
1513/// instructions. The reproducer function will get added to \p M, if it is
1514/// non-null. Otherwise no reproducer function is generated.
1515static void generateReproducer(Instruction *Cond, bool IsSigned, Module *M,
1517 ConstraintInfo &Info, DominatorTree &DT) {
1518 if (!M)
1519 return;
1520
1521 LLVMContext &Ctx = Cond->getContext();
1522
1523 LLVM_DEBUG(dbgs() << "Creating reproducer for " << *Cond << "\n");
1524
1525 ValueToValueMapTy Old2New;
1528 // Traverse Cond and its operands recursively until we reach a value that's in
1529 // Value2Index or not an instruction, or not a operation that
1530 // ConstraintElimination can decompose. Such values will be considered as
1531 // external inputs to the reproducer, they are collected and added as function
1532 // arguments later.
1533 auto CollectArguments = [&](ArrayRef<Value *> Ops, bool IsSigned) {
1534 auto &Value2Index = Info.getValue2Index(IsSigned);
1535 SmallVector<Value *, 4> WorkList(Ops);
1536 while (!WorkList.empty()) {
1537 Value *V = WorkList.pop_back_val();
1538 if (!Seen.insert(V).second)
1539 continue;
1540 if (Old2New.find(V) != Old2New.end())
1541 continue;
1542 if (isa<Constant>(V))
1543 continue;
1544
1545 auto *I = dyn_cast<Instruction>(V);
1546 if (Value2Index.contains(V) || !I ||
1548 Old2New[V] = V;
1549 Args.push_back(V);
1550 LLVM_DEBUG(dbgs() << " found external input " << *V << "\n");
1551 } else {
1552 append_range(WorkList, I->operands());
1553 }
1554 }
1555 };
1556
1557 for (auto &Entry : Stack)
1558 if (Entry.Pred != ICmpInst::BAD_ICMP_PREDICATE)
1559 CollectArguments({Entry.LHS, Entry.RHS}, ICmpInst::isSigned(Entry.Pred));
1560 CollectArguments(Cond, IsSigned);
1561
1562 SmallVector<Type *> ParamTys;
1563 for (auto *P : Args)
1564 ParamTys.push_back(P->getType());
1565
1566 FunctionType *FTy = FunctionType::get(Cond->getType(), ParamTys,
1567 /*isVarArg=*/false);
1569 Cond->getModule()->getName() +
1570 Cond->getFunction()->getName() + "repro",
1571 M);
1572 // Add arguments to the reproducer function for each external value collected.
1573 for (unsigned I = 0; I < Args.size(); ++I) {
1574 F->getArg(I)->setName(Args[I]->getName());
1575 Old2New[Args[I]] = F->getArg(I);
1576 }
1577
1578 BasicBlock *Entry = BasicBlock::Create(Ctx, "entry", F);
1579 IRBuilder<> Builder(Entry);
1580 Builder.CreateRet(Builder.getTrue());
1581 Builder.SetInsertPoint(Entry->getTerminator());
1582
1583 // Clone instructions in \p Ops and their operands recursively until reaching
1584 // an value in Value2Index (external input to the reproducer). Update Old2New
1585 // mapping for the original and cloned instructions. Sort instructions to
1586 // clone by dominance, then insert the cloned instructions in the function.
1587 auto CloneInstructions = [&](ArrayRef<Value *> Ops, bool IsSigned) {
1588 SmallVector<Value *, 4> WorkList(Ops);
1590 auto &Value2Index = Info.getValue2Index(IsSigned);
1591 while (!WorkList.empty()) {
1592 Value *V = WorkList.pop_back_val();
1593 if (Old2New.find(V) != Old2New.end())
1594 continue;
1595
1596 auto *I = dyn_cast<Instruction>(V);
1597 if (!Value2Index.contains(V) && I) {
1598 Old2New[V] = nullptr;
1599 ToClone.push_back(I);
1600 append_range(WorkList, I->operands());
1601 }
1602 }
1603
1604 sort(ToClone,
1605 [&DT](Instruction *A, Instruction *B) { return DT.dominates(A, B); });
1606 for (Instruction *I : ToClone) {
1607 Instruction *Cloned = I->clone();
1608 Old2New[I] = Cloned;
1609 Old2New[I]->setName(I->getName());
1610 Cloned->insertBefore(Builder.GetInsertPoint());
1612 Cloned->setDebugLoc({});
1613 }
1614 };
1615
1616 // Materialize the assumptions for the reproducer using the entries in Stack.
1617 // That is, first clone the operands of the condition recursively until we
1618 // reach an external input to the reproducer and add them to the reproducer
1619 // function. Then add an ICmp for the condition (with the inverse predicate if
1620 // the entry is negated) and an assert using the ICmp.
1621 for (auto &Entry : Stack) {
1622 if (Entry.Pred == ICmpInst::BAD_ICMP_PREDICATE)
1623 continue;
1624
1625 LLVM_DEBUG(dbgs() << " Materializing assumption ";
1626 dumpUnpackedICmp(dbgs(), Entry.Pred, Entry.LHS, Entry.RHS);
1627 dbgs() << "\n");
1628 CloneInstructions({Entry.LHS, Entry.RHS}, CmpInst::isSigned(Entry.Pred));
1629
1630 auto *Cmp = Builder.CreateICmp(Entry.Pred, Entry.LHS, Entry.RHS);
1631 Builder.CreateAssumption(Cmp);
1632 }
1633
1634 // Finally, clone the condition to reproduce and remap instruction operands in
1635 // the reproducer using Old2New.
1636 CloneInstructions(Cond, IsSigned);
1637 Entry->getTerminator()->setOperand(0, Cond);
1638 remapInstructionsInBlocks({Entry}, Old2New);
1639
1640 assert(!verifyFunction(*F, &dbgs()));
1641}
1642
1643static std::optional<bool> checkCondition(CmpInst::Predicate Pred, Value *A,
1644 Value *B, Instruction *CheckInst,
1645 ConstraintInfo &Info) {
1646 LLVM_DEBUG(dbgs() << "Checking " << *CheckInst << "\n");
1647
1648 auto TryWithConstraint = [&](const ConstraintTy &R) -> std::optional<bool> {
1649 if (R.empty()) {
1650 LLVM_DEBUG(dbgs() << " failed to decompose condition\n");
1651 return std::nullopt;
1652 }
1653
1654 auto &CSToUse = Info.getCS(R.IsSigned);
1655 if (auto ImpliedCondition = R.isImpliedBy(CSToUse)) {
1656 if (!DebugCounter::shouldExecute(EliminatedCounter))
1657 return std::nullopt;
1658 LLVM_DEBUG({
1659 dbgs() << "Condition ";
1661 *ImpliedCondition ? Pred
1663 A, B);
1664 dbgs() << " implied by dominating constraints\n";
1665 CSToUse.dump();
1666 });
1667 return ImpliedCondition;
1668 }
1669 return std::nullopt;
1670 };
1671
1672 auto R = Info.getConstraintForSolving(Pred, A, B);
1673 if (auto ImpliedCondition = TryWithConstraint(R))
1674 return ImpliedCondition;
1675
1676 // For non-negative operands unsigned queries can also be checked against the
1677 // signed system.
1678 if (CmpInst::isUnsigned(Pred) && A->getType()->isIntegerTy()) {
1679 SmallVector<Value *> NewVariables;
1680 auto SR = Info.getConstraint(ICmpInst::getSignedPredicate(Pred), A, B,
1681 NewVariables);
1682 if (NewVariables.empty() && !SR.empty() && Info.isKnownNonNegative(A) &&
1683 Info.isKnownNonNegative(B))
1684 if (auto ImpliedCondition = TryWithConstraint(SR))
1685 return ImpliedCondition;
1686 }
1687
1688 // Additionally, query the signed system for eq/ne predicates if we know about
1689 // A or B.
1690 if (CmpInst::isEquality(Pred)) {
1691 const auto &Value2Index = Info.getValue2Index(/*Signed=*/true);
1692 if (!Value2Index.contains(A) && !Value2Index.contains(B))
1693 return std::nullopt;
1694
1695 SmallVector<Value *> NewVariables;
1696 auto SR = Info.getConstraint(Pred, A, B, NewVariables,
1697 /*ForceSignedSystem=*/true);
1698 if (NewVariables.empty())
1699 if (auto ImpliedCondition = TryWithConstraint(SR))
1700 return ImpliedCondition;
1701 }
1702 return std::nullopt;
1703}
1704
1706 CmpPredicate Pred, Value *A, Value *B, Instruction *CheckInst,
1707 ConstraintInfo &Info, unsigned NumIn, unsigned NumOut,
1708 Instruction *ContextInst, Module *ReproducerModule,
1709 ArrayRef<ReproducerEntry> ReproducerCondStack, DominatorTree &DT,
1711 auto ReplaceCmpWithConstant = [&](Instruction *CheckInst, bool IsTrue) {
1712 generateReproducer(CheckInst, ICmpInst::isSigned(Pred), ReproducerModule,
1713 ReproducerCondStack, Info, DT);
1714 Constant *ConstantC = ConstantInt::getBool(
1715 CmpInst::makeCmpResultType(CheckInst->getType()), IsTrue);
1716 bool Changed = CheckInst->replaceUsesWithIf(ConstantC, [&](Use &U) {
1717 auto *UserI = getContextInstForUse(U);
1718 auto *DTN = DT.getNode(UserI->getParent());
1719 if (!DTN || DTN->getDFSNumIn() < NumIn || DTN->getDFSNumOut() > NumOut)
1720 return false;
1721 if (UserI->getParent() == ContextInst->getParent() &&
1722 UserI->comesBefore(ContextInst))
1723 return false;
1724
1725 // Conditions in an assume trivially simplify to true. Skip uses
1726 // in assume calls to not destroy the available information.
1727 auto *II = dyn_cast<IntrinsicInst>(U.getUser());
1728 return !II || II->getIntrinsicID() != Intrinsic::assume;
1729 });
1730 NumCondsRemoved++;
1731
1732 // Update the debug value records that satisfy the same condition used
1733 // in replaceUsesWithIf.
1735 findDbgUsers(CheckInst, DVRUsers);
1736
1737 for (auto *DVR : DVRUsers) {
1738 auto *DTN = DT.getNode(DVR->getParent());
1739 if (!DTN || DTN->getDFSNumIn() < NumIn || DTN->getDFSNumOut() > NumOut)
1740 continue;
1741
1742 auto *MarkedI = DVR->getInstruction();
1743 if (MarkedI->getParent() == ContextInst->getParent() &&
1744 MarkedI->comesBefore(ContextInst))
1745 continue;
1746
1747 DVR->replaceVariableLocationOp(CheckInst, ConstantC);
1748 }
1749
1750 if (CheckInst->use_empty())
1751 ToRemove.push_back(CheckInst);
1752
1753 return Changed;
1754 };
1755
1756 if (auto ImpliedCondition = checkCondition(Pred, A, B, CheckInst, Info))
1757 return ReplaceCmpWithConstant(CheckInst, *ImpliedCondition);
1758
1759 // When the predicate is samesign and unsigned, we can also make use of the
1760 // signed predicate information.
1761 if (Pred.hasSameSign() && ICmpInst::isUnsigned(Pred))
1762 if (auto ImpliedCondition = checkCondition(
1763 ICmpInst::getSignedPredicate(Pred), A, B, CheckInst, Info))
1764 return ReplaceCmpWithConstant(CheckInst, *ImpliedCondition);
1765
1766 return false;
1767}
1768
1769static bool checkAndReplaceMinMax(MinMaxIntrinsic *MinMax, ConstraintInfo &Info,
1771 auto ReplaceMinMaxWithOperand = [&](MinMaxIntrinsic *MinMax, bool UseLHS) {
1772 // TODO: generate reproducer for min/max.
1773 MinMax->replaceAllUsesWith(MinMax->getOperand(UseLHS ? 0 : 1));
1774 ToRemove.push_back(MinMax);
1775 return true;
1776 };
1777
1778 ICmpInst::Predicate Pred =
1779 ICmpInst::getNonStrictPredicate(MinMax->getPredicate());
1780 if (auto ImpliedCondition = checkCondition(
1781 Pred, MinMax->getOperand(0), MinMax->getOperand(1), MinMax, Info))
1782 return ReplaceMinMaxWithOperand(MinMax, *ImpliedCondition);
1783 if (auto ImpliedCondition = checkCondition(
1784 Pred, MinMax->getOperand(1), MinMax->getOperand(0), MinMax, Info))
1785 return ReplaceMinMaxWithOperand(MinMax, !*ImpliedCondition);
1786 return false;
1787}
1788
1789static bool checkAndReplaceCmp(CmpIntrinsic *I, ConstraintInfo &Info,
1791 Value *LHS = I->getOperand(0);
1792 Value *RHS = I->getOperand(1);
1793 if (checkCondition(I->getGTPredicate(), LHS, RHS, I, Info).value_or(false)) {
1794 I->replaceAllUsesWith(ConstantInt::get(I->getType(), 1));
1795 ToRemove.push_back(I);
1796 return true;
1797 }
1798 if (checkCondition(I->getLTPredicate(), LHS, RHS, I, Info).value_or(false)) {
1799 I->replaceAllUsesWith(ConstantInt::getSigned(I->getType(), -1));
1800 ToRemove.push_back(I);
1801 return true;
1802 }
1803 if (checkCondition(ICmpInst::ICMP_EQ, LHS, RHS, I, Info).value_or(false)) {
1804 I->replaceAllUsesWith(ConstantInt::get(I->getType(), 0));
1805 ToRemove.push_back(I);
1806 return true;
1807 }
1808 return false;
1809}
1810
1811static void
1812removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info,
1813 Module *ReproducerModule,
1814 SmallVectorImpl<ReproducerEntry> &ReproducerCondStack,
1815 SmallVectorImpl<StackEntry> &DFSInStack) {
1816 Info.popLastConstraint(E.IsSigned);
1817 // Remove variables in the system that went out of scope.
1818 auto &Mapping = Info.getValue2Index(E.IsSigned);
1819 for (Value *V : E.ValuesToRelease)
1820 Mapping.erase(V);
1821 Info.popLastNVariables(E.IsSigned, E.ValuesToRelease.size());
1822 DFSInStack.pop_back();
1823 if (ReproducerModule)
1824 ReproducerCondStack.pop_back();
1825}
1826
1827/// Check if either the first condition of an AND or OR is implied by the
1828/// (negated in case of OR) second condition or vice versa.
1830 FactOrCheck &CB, ConstraintInfo &Info, Module *ReproducerModule,
1831 SmallVectorImpl<ReproducerEntry> &ReproducerCondStack,
1832 SmallVectorImpl<StackEntry> &DFSInStack,
1834 Instruction *JoinOp = CB.getContextInst();
1835 if (JoinOp->use_empty())
1836 return false;
1837
1838 Instruction *CmpToCheck = cast<Instruction>(CB.getInstructionToSimplify());
1839 unsigned OtherOpIdx = JoinOp->getOperand(0) == CmpToCheck ? 1 : 0;
1840
1841 // Don't try to simplify the first condition of a select by the second, as
1842 // this may make the select more poisonous than the original one.
1843 // TODO: check if the first operand may be poison.
1844 if (OtherOpIdx != 0 && isa<SelectInst>(JoinOp))
1845 return false;
1846
1847 unsigned OldSize = DFSInStack.size();
1848 llvm::scope_exit InfoRestorer([&]() {
1849 // Remove entries again.
1850 while (OldSize < DFSInStack.size()) {
1851 StackEntry E = DFSInStack.back();
1852 removeEntryFromStack(E, Info, ReproducerModule, ReproducerCondStack,
1853 DFSInStack);
1854 }
1855 });
1856 bool IsOr = match(JoinOp, m_LogicalOr());
1857 SmallVector<Value *, 4> Worklist({JoinOp->getOperand(OtherOpIdx)});
1858 // Do a traversal of the AND/OR tree to add facts from leaf compares.
1859 while (!Worklist.empty()) {
1860 Value *Val = Worklist.pop_back_val();
1861 Value *LHS, *RHS;
1862 CmpPredicate Pred;
1863 if (match(Val, m_ICmpLike(Pred, m_Value(LHS), m_Value(RHS)))) {
1864 // For OR, check if the negated condition implies CmpToCheck.
1865 if (IsOr)
1866 Pred = CmpInst::getInversePredicate(Pred);
1867 // Optimistically add fact from the other compares in the AND/OR.
1868 Info.addFact(Pred, LHS, RHS, CB.NumIn, CB.NumOut, DFSInStack);
1869 continue;
1870 }
1871 if (IsOr ? match(Val, m_LogicalOr(m_Value(LHS), m_Value(RHS)))
1872 : match(Val, m_LogicalAnd(m_Value(LHS), m_Value(RHS)))) {
1873 Worklist.push_back(LHS);
1874 Worklist.push_back(RHS);
1875 }
1876 }
1877 if (OldSize == DFSInStack.size())
1878 return false;
1879
1880 Value *A, *B;
1881 CmpPredicate Pred;
1882 [[maybe_unused]] bool Matched =
1883 match(CmpToCheck, m_ICmpLike(Pred, m_Value(A), m_Value(B)));
1884 assert(Matched && "expected icmp-like match");
1885 // Check if the second condition can be simplified now.
1886 if (auto ImpliedCondition = checkCondition(Pred, A, B, CmpToCheck, Info)) {
1887 if (IsOr == *ImpliedCondition)
1888 JoinOp->replaceAllUsesWith(
1889 ConstantInt::getBool(JoinOp->getType(), *ImpliedCondition));
1890 else
1891 JoinOp->replaceAllUsesWith(JoinOp->getOperand(OtherOpIdx));
1892 ToRemove.push_back(JoinOp);
1893 return true;
1894 }
1895
1896 return false;
1897}
1898
1899void ConstraintInfo::addFact(CmpInst::Predicate Pred, Value *A, Value *B,
1900 unsigned NumIn, unsigned NumOut,
1901 SmallVectorImpl<StackEntry> &DFSInStack) {
1902 addFactImpl(Pred, A, B, NumIn, NumOut, DFSInStack, false);
1903 // If the Pred is eq/ne, also add the fact to signed system.
1904 if (CmpInst::isEquality(Pred))
1905 addFactImpl(Pred, A, B, NumIn, NumOut, DFSInStack, true);
1906 if (Pred == CmpInst::ICMP_NE)
1907 tightenBoundUsingNe(A, B, NumIn, NumOut, DFSInStack);
1908}
1909
1910void ConstraintInfo::tightenBoundUsingNe(
1911 Value *A, Value *B, unsigned NumIn, unsigned NumOut,
1912 SmallVectorImpl<StackEntry> &DFSInStack) {
1913 if (!A->getType()->isIntegerTy())
1914 return;
1915
1916 for (bool IsSigned : {false, true}) {
1917 // In the unsigned system `A u>= 0` holds for every A, so getConstraint
1918 // already turned `A != 0` into `A u> 0`.
1919 if (!IsSigned && match(B, m_Zero()))
1920 continue;
1921
1922 // Skip if there are any unknown variables.
1923 const auto &Value2Index = getValue2Index(IsSigned);
1924 if (any_of(decompose(A, *this, IsSigned, DL).Vars,
1925 [&Value2Index](const DecompEntry &E) {
1926 return !Value2Index.contains(E.Variable);
1927 }))
1928 continue;
1929
1930 // If the system implies `A >= B` then together with `A != B` we get the
1931 // strict `A > B`; symmetrically `A <= B` becomes `A < B`.
1932 CmpInst::Predicate GEPred =
1934 CmpInst::Predicate LEPred =
1936 for (CmpInst::Predicate NonStrict : {GEPred, LEPred}) {
1937 if (!doesHold(NonStrict, A, B))
1938 continue;
1940 LLVM_DEBUG(dbgs() << "Tightening '";
1941 dumpUnpackedICmp(dbgs(), NonStrict, A, B); dbgs() << "' to '";
1943 dbgs() << "' using inequality\n");
1944 addFactImpl(Strict, A, B, NumIn, NumOut, DFSInStack,
1945 /*ForceSignedSystem=*/false);
1946 break;
1947 }
1948 }
1949}
1950
1951void ConstraintInfo::addFactImpl(CmpInst::Predicate Pred, Value *A, Value *B,
1952 unsigned NumIn, unsigned NumOut,
1953 SmallVectorImpl<StackEntry> &DFSInStack,
1954 bool ForceSignedSystem) {
1955 SmallVector<Value *> NewVariables;
1956 auto R = getConstraint(Pred, A, B, NewVariables, ForceSignedSystem);
1957
1958 // TODO: Support non-equality for facts as well.
1959 if (R.empty() || R.isNe())
1960 return;
1961
1962 LLVM_DEBUG(dbgs() << "Adding '"; dumpUnpackedICmp(dbgs(), Pred, A, B);
1963 dbgs() << "'\n");
1964 auto &CSToUse = getCS(R.IsSigned);
1965 bool Added = CSToUse.addRow(R.Coefficients, R.NumVars);
1966 if (!Added)
1967 return;
1968
1969 // If R has been added to the system, add the new variables and queue it for
1970 // removal once it goes out-of-scope.
1971 SmallVector<Value *, 2> ValuesToRelease;
1972 auto &Value2Index = getValue2Index(R.IsSigned);
1973 for (Value *V : NewVariables) {
1974 Value2Index.try_emplace(V, Value2Index.size() + 1);
1975 ValuesToRelease.push_back(V);
1976 }
1977
1978 LLVM_DEBUG({
1979 dbgs() << " constraint: ";
1980 dumpConstraint(R.Coefficients, getValue2Index(R.IsSigned));
1981 dbgs() << "\n";
1982 });
1983
1984 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
1985 std::move(ValuesToRelease));
1986
1987 if (!R.IsSigned) {
1988 for (Value *V : NewVariables) {
1989 // Add V > -1 constraints for all new variables.
1990 CSToUse.addRow({Entry(0, 0), Entry(-1, Value2Index.at(V))},
1991 Value2Index.size());
1992 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
1993 SmallVector<Value *, 2>());
1994 }
1995 }
1996
1997 if (R.isEq()) {
1998 // Also add the inverted constraint for equality constraints.
1999 for (Entry &E : R.Coefficients)
2000 if (MulOverflow(E.Coefficient, int64_t(-1), E.Coefficient))
2001 return;
2002 CSToUse.addRow(R.Coefficients, R.NumVars);
2003
2004 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
2005 SmallVector<Value *, 2>());
2006 }
2007}
2008
2011 bool Changed = false;
2012 IRBuilder<> Builder(II->getParent(), II->getIterator());
2013 Value *Sub = nullptr;
2014 for (User *U : make_early_inc_range(II->users())) {
2015 if (match(U, m_ExtractValue<0>(m_Value()))) {
2016 if (!Sub)
2017 Sub = Builder.CreateNSWSub(A, B);
2018 U->replaceAllUsesWith(Sub);
2019 Changed = true;
2020 } else if (match(U, m_ExtractValue<1>(m_Value()))) {
2021 U->replaceAllUsesWith(Builder.getFalse());
2022 Changed = true;
2023 } else
2024 continue;
2025
2026 if (U->use_empty()) {
2027 auto *I = cast<Instruction>(U);
2028 ToRemove.push_back(I);
2029 I->setOperand(0, PoisonValue::get(II->getType()));
2030 Changed = true;
2031 }
2032 }
2033
2034 if (II->use_empty()) {
2035 // Do not erase II here: the worklist may still hold Uses of II's operands.
2036 for (Use &Arg : II->args())
2037 Arg.set(PoisonValue::get(Arg->getType()));
2038 ToRemove.push_back(II);
2039 Changed = true;
2040 }
2041 return Changed;
2042}
2043
2044static bool
2047 auto DoesConditionHold = [](CmpInst::Predicate Pred, Value *A, Value *B,
2048 ConstraintInfo &Info) {
2049 auto R = Info.getConstraintForSolving(Pred, A, B);
2050 // Nothing can be proven if the constraint has no variables. This also
2051 // covers rows that could not be decomposed, which are empty.
2052 if (R.isConstantOnly())
2053 return false;
2054
2055 auto &CSToUse = Info.getCS(R.IsSigned);
2056 return CSToUse.isConditionImpliedInSubSystem(R.Coefficients);
2057 };
2058
2059 bool Changed = false;
2060 if (II->getIntrinsicID() == Intrinsic::ssub_with_overflow) {
2061 // If A s>= B && B s>= 0, ssub.with.overflow(a, b) should not overflow and
2062 // can be simplified to a regular sub.
2063 Value *A = II->getArgOperand(0);
2064 Value *B = II->getArgOperand(1);
2065 if (!DoesConditionHold(CmpInst::ICMP_SGE, A, B, Info) ||
2066 !DoesConditionHold(CmpInst::ICMP_SGE, B,
2067 ConstantInt::get(A->getType(), 0), Info))
2068 return false;
2070 }
2071 return Changed;
2072}
2073
2075 ScalarEvolution &SE,
2077 TargetLibraryInfo &TLI) {
2078 bool Changed = false;
2079 DT.updateDFSNumbers();
2080 SmallVector<Value *> FunctionArgs(llvm::make_pointer_range(F.args()));
2081 ConstraintInfo Info(F.getDataLayout(), FunctionArgs);
2082 State S(DT, LI, SE, TLI);
2083 std::unique_ptr<Module> ReproducerModule(
2084 DumpReproducers ? new Module(F.getName(), F.getContext()) : nullptr);
2085
2086 // First, collect conditions implied by branches and blocks with their
2087 // Dominator DFS in and out numbers.
2088 for (BasicBlock &BB : F) {
2089 if (!DT.getNode(&BB))
2090 continue;
2091 S.addInfoFor(BB);
2092 }
2093
2094 // Next, sort worklist by dominance, so that dominating conditions to check
2095 // and facts come before conditions and facts dominated by them. If a
2096 // condition to check and a fact have the same numbers, conditional facts come
2097 // first. Assume facts and checks are ordered according to their relative
2098 // order in the containing basic block. Also make sure conditions with
2099 // constant operands come before conditions without constant operands. This
2100 // increases the effectiveness of the current signed <-> unsigned fact
2101 // transfer logic.
2102 stable_sort(S.WorkList, [](const FactOrCheck &A, const FactOrCheck &B) {
2103 auto HasNoConstOp = [](const FactOrCheck &B) {
2104 Value *V0 = B.isConditionFact() ? B.Cond.Op0 : B.Inst->getOperand(0);
2105 Value *V1 = B.isConditionFact() ? B.Cond.Op1 : B.Inst->getOperand(1);
2106 return !isa<ConstantInt>(V0) && !isa<ConstantInt>(V1);
2107 };
2108 // If both entries have the same In numbers, conditional facts come first.
2109 // Otherwise use the relative order in the basic block.
2110 if (A.NumIn == B.NumIn) {
2111 if (A.isConditionFact() && B.isConditionFact()) {
2112 bool NoConstOpA = HasNoConstOp(A);
2113 bool NoConstOpB = HasNoConstOp(B);
2114 return NoConstOpA < NoConstOpB;
2115 }
2116 if (A.isConditionFact())
2117 return true;
2118 if (B.isConditionFact())
2119 return false;
2120 auto *InstA = A.getContextInst();
2121 auto *InstB = B.getContextInst();
2122 return InstA->comesBefore(InstB);
2123 }
2124 return A.NumIn < B.NumIn;
2125 });
2126
2127 SmallVector<Instruction *> ToRemove;
2128
2129 // Finally, process ordered worklist and eliminate implied conditions.
2130 SmallVector<StackEntry, 16> DFSInStack;
2131 SmallVector<ReproducerEntry> ReproducerCondStack;
2132 for (FactOrCheck &CB : S.WorkList) {
2133 // First, pop entries from the stack that are out-of-scope for CB. Remove
2134 // the corresponding entry from the constraint system.
2135 while (!DFSInStack.empty()) {
2136 auto &E = DFSInStack.back();
2137 LLVM_DEBUG(dbgs() << "Top of stack : " << E.NumIn << " " << E.NumOut
2138 << "\n");
2139 LLVM_DEBUG(dbgs() << "CB: " << CB.NumIn << " " << CB.NumOut << "\n");
2140 assert(E.NumIn <= CB.NumIn);
2141 if (CB.NumOut <= E.NumOut)
2142 break;
2143 LLVM_DEBUG({
2144 dbgs() << "Removing ";
2145 dumpConstraint(Info.getCS(E.IsSigned).getLastConstraint(),
2146 Info.getValue2Index(E.IsSigned));
2147 dbgs() << "\n";
2148 });
2149 removeEntryFromStack(E, Info, ReproducerModule.get(), ReproducerCondStack,
2150 DFSInStack);
2151 }
2152
2153 CmpPredicate Pred;
2154 Value *A, *B;
2155 // For a block, check if any CmpInsts become known based on the current set
2156 // of constraints.
2157 if (CB.isCheck()) {
2158 Instruction *Inst = CB.getInstructionToSimplify();
2159 if (!Inst)
2160 continue;
2161 LLVM_DEBUG(dbgs() << "Processing condition to simplify: " << *Inst
2162 << "\n");
2163 if (auto *II = dyn_cast<WithOverflowInst>(Inst)) {
2165 } else if (match(Inst, m_ICmpLike(Pred, m_Value(A), m_Value(B)))) {
2167 Pred, A, B, Inst, Info, CB.NumIn, CB.NumOut, CB.getContextInst(),
2168 ReproducerModule.get(), ReproducerCondStack, S.DT, ToRemove);
2169 if (!Simplified &&
2170 match(CB.getContextInst(), m_LogicalOp(m_Value(), m_Value()))) {
2172 CB, Info, ReproducerModule.get(), ReproducerCondStack, DFSInStack,
2173 ToRemove);
2174 }
2176 } else if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(Inst)) {
2177 Changed |= checkAndReplaceMinMax(MinMax, Info, ToRemove);
2178 } else if (auto *CmpIntr = dyn_cast<CmpIntrinsic>(Inst)) {
2179 Changed |= checkAndReplaceCmp(CmpIntr, Info, ToRemove);
2180 }
2181 continue;
2182 }
2183
2184 auto AddFact = [&](CmpPredicate Pred, Value *A, Value *B) {
2185 LLVM_DEBUG(dbgs() << "Processing fact to add to the system: ";
2186 dumpUnpackedICmp(dbgs(), Pred, A, B); dbgs() << "\n");
2187 if (Info.getCS(CmpInst::isSigned(Pred)).size() > MaxRows) {
2188 LLVM_DEBUG(
2189 dbgs()
2190 << "Skip adding constraint because system has too many rows.\n");
2191 return;
2192 }
2193
2194 Info.addFact(Pred, A, B, CB.NumIn, CB.NumOut, DFSInStack);
2195 if (ReproducerModule && DFSInStack.size() > ReproducerCondStack.size())
2196 ReproducerCondStack.emplace_back(Pred, A, B);
2197
2198 if (ICmpInst::isRelational(Pred)) {
2199 // If samesign is present on the ICmp, simply flip the sign of the
2200 // predicate, transferring the information from the signed system to the
2201 // unsigned system, and viceversa.
2202 if (Pred.hasSameSign())
2204 CB.NumIn, CB.NumOut, DFSInStack);
2205 else
2206 Info.transferToOtherSystem(Pred, A, B, CB.NumIn, CB.NumOut,
2207 DFSInStack);
2208 }
2209
2210 // (X | Y) >s -1 implies X >s -1 and Y >s -1, because the sign bit of an
2211 // OR is the OR of the operand sign bits. Similarly, (X & Y) <s 0 implies
2212 // X <s 0 and Y <s 0. Look through these canonical forms produced by
2213 // InstCombine so the sign facts on the operands are available to the
2214 // solver.
2215 if ((Pred == CmpInst::ICMP_SGT && match(B, m_AllOnes())) ||
2216 (Pred == CmpInst::ICMP_SLT && match(B, m_Zero()))) {
2217 unsigned Opc =
2218 Pred == CmpInst::ICMP_SGT ? Instruction::Or : Instruction::And;
2219 SmallVector<Value *> Worklist = {A};
2220 SmallPtrSet<Value *, 4> Seen;
2221 while (!Worklist.empty()) {
2222 Value *Cur = Worklist.pop_back_val();
2223 auto *BO = dyn_cast<BinaryOperator>(Cur);
2224 if (!BO || BO->getOpcode() != Opc)
2225 continue;
2226 for (Value *Op : {BO->getOperand(0), BO->getOperand(1)}) {
2227 if (!Seen.insert(Op).second)
2228 continue;
2229 Worklist.push_back(Op);
2230 Info.addFact(Pred, Op, B, CB.NumIn, CB.NumOut, DFSInStack);
2231 }
2232 }
2233 }
2234
2235 if (ReproducerModule && DFSInStack.size() > ReproducerCondStack.size()) {
2236 // Add dummy entries to ReproducerCondStack to keep it in sync with
2237 // DFSInStack.
2238 for (unsigned I = 0,
2239 E = (DFSInStack.size() - ReproducerCondStack.size());
2240 I < E; ++I) {
2241 ReproducerCondStack.emplace_back(ICmpInst::BAD_ICMP_PREDICATE,
2242 nullptr, nullptr);
2243 }
2244 }
2245 };
2246
2247 if (!CB.isConditionFact()) {
2248 Value *X;
2249 if (match(CB.Inst, m_Intrinsic<Intrinsic::abs>(m_Value(X)))) {
2250 // If is_int_min_poison is true then we may assume llvm.abs >= 0.
2251 if (cast<ConstantInt>(CB.Inst->getOperand(1))->isOne())
2252 AddFact(CmpInst::ICMP_SGE, CB.Inst,
2253 ConstantInt::get(CB.Inst->getType(), 0));
2254 AddFact(CmpInst::ICMP_SGE, CB.Inst, X);
2255 continue;
2256 }
2257
2258 if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(CB.Inst)) {
2259 Pred = ICmpInst::getNonStrictPredicate(MinMax->getPredicate());
2260 AddFact(Pred, MinMax, MinMax->getLHS());
2261 AddFact(Pred, MinMax, MinMax->getRHS());
2262 continue;
2263 }
2264 if (auto *USatI = dyn_cast<SaturatingInst>(CB.Inst)) {
2265 switch (USatI->getIntrinsicID()) {
2266 default:
2267 llvm_unreachable("Unexpected intrinsic.");
2268 case Intrinsic::uadd_sat:
2269 AddFact(ICmpInst::ICMP_UGE, USatI, USatI->getLHS());
2270 AddFact(ICmpInst::ICMP_UGE, USatI, USatI->getRHS());
2271 break;
2272 case Intrinsic::usub_sat:
2273 AddFact(ICmpInst::ICMP_ULE, USatI, USatI->getLHS());
2274 break;
2275 }
2276 continue;
2277 }
2278
2279 if (auto *BO = dyn_cast<BinaryOperator>(CB.Inst)) {
2280 if (BO->getOpcode() == Instruction::URem) {
2281 // urem x, n: result < n (remainder is always less than divisor)
2282 AddFact(CmpInst::ICMP_ULT, BO, BO->getOperand(1));
2283 // urem x, n: result <= x (remainder is at most the dividend)
2284 AddFact(CmpInst::ICMP_ULE, BO, BO->getOperand(0));
2285 continue;
2286 }
2287 if (BO->getOpcode() == Instruction::UDiv) {
2288 // udiv x, n: result <= x (quotient is at most the dividend)
2289 AddFact(CmpInst::ICMP_ULE, BO, BO->getOperand(0));
2290 continue;
2291 }
2292 if (BO->getOpcode() == Instruction::LShr) {
2293 // lshr x, n: result <= x (right shift cannot increase the value)
2294 AddFact(CmpInst::ICMP_ULE, BO, BO->getOperand(0));
2295 continue;
2296 }
2297 if (BO->getOpcode() == Instruction::SRem) {
2298 Value *X = BO->getOperand(0);
2299 Value *N = BO->getOperand(1);
2300 Constant *Zero = Constant::getNullValue(BO->getType());
2301 if (Info.doesHold(CmpInst::ICMP_SGE, X, Zero) ||
2302 isKnownNonNegative(X, F.getDataLayout())) {
2303 // srem x, n: result >= 0, if x >= 0 (result has the sign of x)
2304 AddFact(CmpInst::ICMP_SGE, BO, Zero);
2305 // srem x, n: result <= x, if x >= 0 (|result| <= |x| and both are
2306 // non-negative)
2307 AddFact(CmpInst::ICMP_SLE, BO, X);
2308 }
2309 if (Info.doesHold(CmpInst::ICMP_SGE, N, Zero) ||
2310 isKnownPositive(N, F.getDataLayout())) {
2311 // srem x, n: result <= n, if n >= 0 (|result| < n, so result <= n -
2312 // 1
2313 AddFact(CmpInst::ICMP_SLT, BO, N);
2314 }
2315 continue;
2316 }
2317 }
2318
2319 auto &DL = F.getDataLayout();
2320 auto AddFactsAboutIndices = [&](Value *Ptr, Type *AccessType) {
2321 CmpPredicate Pred;
2322 Value *A, *B;
2325 DL.getTypeStoreSize(AccessType).getFixedValue(), Pred, A, B, DL,
2326 TLI))
2327 AddFact(Pred, A, B);
2328 };
2329
2330 if (auto *LI = dyn_cast<LoadInst>(CB.Inst)) {
2331 AddFactsAboutIndices(LI->getPointerOperand(), LI->getAccessType());
2332 continue;
2333 }
2334 if (auto *SI = dyn_cast<StoreInst>(CB.Inst)) {
2335 AddFactsAboutIndices(SI->getPointerOperand(), SI->getAccessType());
2336 continue;
2337 }
2338 }
2339
2340 if (CB.isConditionFact()) {
2341 Pred = CB.Cond.Pred;
2342 A = CB.Cond.Op0;
2343 B = CB.Cond.Op1;
2344 if (CB.DoesHold.Pred != CmpInst::BAD_ICMP_PREDICATE &&
2345 !Info.doesHold(CB.DoesHold.Pred, CB.DoesHold.Op0, CB.DoesHold.Op1)) {
2346 LLVM_DEBUG({
2347 dbgs() << "Not adding fact ";
2348 dumpUnpackedICmp(dbgs(), Pred, A, B);
2349 dbgs() << " because precondition ";
2350 dumpUnpackedICmp(dbgs(), CB.DoesHold.Pred, CB.DoesHold.Op0,
2351 CB.DoesHold.Op1);
2352 dbgs() << " does not hold.\n";
2353 });
2354 continue;
2355 }
2356 } else {
2357 [[maybe_unused]] bool Matched =
2359 m_ICmpLike(Pred, m_Value(A), m_Value(B))));
2360 assert(Matched &&
2361 "Must have an assume intrinsic with a icmp like operand");
2362 }
2363 AddFact(Pred, A, B);
2364 }
2365
2366 if (ReproducerModule && !ReproducerModule->functions().empty()) {
2367 std::string S;
2368 raw_string_ostream StringS(S);
2369 ReproducerModule->print(StringS, nullptr);
2370 OptimizationRemark Rem(DEBUG_TYPE, "Reproducer", &F);
2371 Rem << ore::NV("module") << S;
2372 ORE.emit(Rem);
2373 }
2374
2375#ifndef NDEBUG
2376 unsigned SignedEntries =
2377 count_if(DFSInStack, [](const StackEntry &E) { return E.IsSigned; });
2378 assert(Info.getCS(false).size() - FunctionArgs.size() ==
2379 DFSInStack.size() - SignedEntries &&
2380 "updates to CS and DFSInStack are out of sync");
2381 assert(Info.getCS(true).size() == SignedEntries &&
2382 "updates to CS and DFSInStack are out of sync");
2383#endif
2384
2385 for (Instruction *I : ToRemove)
2386 I->eraseFromParent();
2387 return Changed;
2388}
2389
2392 auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
2393 auto &LI = AM.getResult<LoopAnalysis>(F);
2394 auto &SE = AM.getResult<ScalarEvolutionAnalysis>(F);
2396 auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
2397 if (!eliminateConstraints(F, DT, LI, SE, ORE, TLI))
2398 return PreservedAnalyses::all();
2399
2403 return PA;
2404}
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 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 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