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