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 auto *Br = dyn_cast<CondBrInst>(BB.getTerminator());
1090 if (!Br)
1091 return;
1092
1093 auto CountingCmp = m_c_ICmp(Pred, IndValue, m_Value(B));
1094 std::optional<bool> PeeledOnEdge;
1095 if (!match(Br->getCondition(), CountingCmp)) {
1096 // Look through AND/OR, and remember which edge requires all operands to be
1097 // true.
1098 if (match(Br->getCondition(), m_c_LogicalAnd(CountingCmp, m_Value())))
1099 PeeledOnEdge = true;
1100 else if (match(Br->getCondition(), m_c_LogicalOr(CountingCmp, m_Value())))
1101 PeeledOnEdge = false;
1102 else
1103 return;
1104 }
1105
1106 if (PN->getParent() != Header || PN->getNumIncomingValues() != 2 ||
1107 !SE.isSCEVable(PN->getType()))
1108 return;
1109
1110 // For latch conditions, we need to inject the condition that holds for the
1111 // next iteration into the header. We limit to post-inc conditions, for which
1112 // an original PN + Step != B condition results in a PN < B constraint in the
1113 // header, which also holds for the next loop iteration. This would no longer
1114 // be correct if the post-inc handling would inject a more precise PN + Step <
1115 // B constraint instead.
1116 if (&BB == Latch && !IncStep)
1117 return;
1118
1119 bool ContinueOnTrue =
1120 Pred == CmpInst::ICMP_NE || ICmpInst::isLT(Pred) || ICmpInst::isLE(Pred);
1121 CmpInst::Predicate ContinuePred =
1122 ContinueOnTrue ? Pred.dropSameSign() : CmpInst::getInversePredicate(Pred);
1123 BasicBlock *InLoopSucc = Br->getSuccessor(ContinueOnTrue ? 0 : 1);
1124
1125 // The peeled condition only implies the compare on the edge where the
1126 // combined condition forces its operands, which must be the in-loop edge.
1127 if (PeeledOnEdge && *PeeledOnEdge != ContinueOnTrue)
1128 return;
1129
1130 if (!L->contains(InLoopSucc) || !L->isLoopExiting(&BB))
1131 return;
1132
1133 BasicBlock *LoopPred = L->getLoopPredecessor();
1134 if (!LoopPred || !L->isLoopInvariant(B))
1135 return;
1136
1137 auto [StartValue, Backedge] = getStartAndBackedgeValue(*PN, LoopPred);
1138 DomTreeNode *DTN = DT.getNode(InLoopSucc);
1139
1140 if (ICmpInst::isRelational(ContinuePred)) {
1141 if (A != Backedge)
1142 return;
1143
1144 // The latch condition ensures ContinuePred holds in the header on each
1145 // iteration other than the first. Together with a precondition on the start
1146 // value (StartValue ContinuePred B), we can add B as bound of PN.
1147 WorkList.push_back(FactOrCheck::getConditionFact(
1148 DTN, ContinuePred, PN, B, ConditionTy(ContinuePred, StartValue, B)));
1149
1150 // A relational latch steps past B rather than landing on it, so none of the
1151 // reasoning below applies.
1152 return;
1153 }
1154
1155 const APInt *StepOffset = nullptr;
1156 const SCEV *StartSCEV = nullptr;
1157 if (match(Backedge, m_c_Add(m_Specific(PN), m_APInt(StepOffset)))) {
1158 if (StepOffset->isZero())
1159 return;
1160 } else {
1161 const SCEV *Expr = SE.getSCEV(PN);
1162 if (!match(Expr,
1163 m_scev_AffineAddRec(m_SCEV(StartSCEV), m_scev_APInt(StepOffset),
1164 m_SpecificLoop(L))))
1165 return;
1166 }
1167
1168 // If we looked through `PN + C`, only derive facts when that add is
1169 // really the induction's post-increment or post-decrement.
1170 if (IncStep && *IncStep != *StepOffset)
1171 return;
1172
1173 MonotonicInfo Info = getMonotonicityInfo(*PN, Backedge);
1174
1175 // Handle negative steps.
1176 if (StepOffset->isNegative()) {
1177 // TODO: Extend to allow steps > -1.
1178 if (!(-*StepOffset).isOne())
1179 return;
1180
1181 // AR may wrap.
1182 // The loop exits once the compared value reaches B, that is at PN == B when
1183 // comparing the phi, and at PN == B + 1 for a post-decrement. Use
1184 // non-strict predicate for the former, and a strict one for the latter to
1185 // ensure the loop exits before wrapping.
1186 CmpInst::Predicate UPrecond =
1188 ConditionTy BBeforeStartUnsigned = {UPrecond, B, StartValue};
1189 ConditionTy BBeforeStartSigned = {ICmpInst::getSignedPredicate(UPrecond), B,
1190 StartValue};
1191
1192 // AR may wrap, so both facts are conditional on B being below StartValue.
1193 // Add StartValue >= PN, which holds as the loop exits before wrapping.
1194 WorkList.push_back(FactOrCheck::getConditionFact(
1195 DTN, CmpInst::ICMP_UGE, StartValue, PN, BBeforeStartUnsigned));
1196 if (!(Info.Decreasing && Info.Signed))
1197 WorkList.push_back(FactOrCheck::getConditionFact(
1198 DTN, CmpInst::ICMP_SGE, StartValue, PN, BBeforeStartSigned));
1199 // Add PN > B, which holds as the loop exits when reaching B.
1200 WorkList.push_back(FactOrCheck::getConditionFact(DTN, CmpInst::ICMP_UGT, PN,
1201 B, BBeforeStartUnsigned));
1202 WorkList.push_back(FactOrCheck::getConditionFact(DTN, CmpInst::ICMP_SGT, PN,
1203 B, BBeforeStartSigned));
1204 return;
1205 }
1206
1207 // Make sure AR either steps by 1 or that the value we compare against is a
1208 // GEP based on the same start value and all offsets are a multiple of the
1209 // step size, to guarantee that the induction will reach the value.
1210 if (StepOffset->isZero() || StepOffset->isNegative())
1211 return;
1212
1213 if (!StepOffset->isOne()) {
1214 // Check whether B-Start is known to be a multiple of StepOffset.
1215 if (!StartSCEV)
1216 StartSCEV = SE.getSCEV(StartValue);
1217 const SCEV *BMinusStart = SE.getMinusSCEV(SE.getSCEV(B), StartSCEV);
1218 if (isa<SCEVCouldNotCompute>(BMinusStart) ||
1219 !SE.getConstantMultiple(BMinusStart).urem(*StepOffset).isZero())
1220 return;
1221 }
1222
1223 // We already established that B - Start is a multiple of Step above. The loop
1224 // exits once the compared value reaches B, that is at PN == B when comparing
1225 // the phi, and at PN + Step == B for a post-increment. Together with the
1226 // added precondition StartValue <= B for the former and the strict
1227 // StartValue < B for the latter (which implies StartValue + Step <= B),
1228 // neither PN nor the increment can wrap.
1230 ConditionTy StartBeforeBoundUnsigned = {UPrecond, StartValue, B};
1231 ConditionTy StartBeforeBoundSigned = {ICmpInst::getSignedPredicate(UPrecond),
1232 StartValue, B};
1233
1234 // Add PN >= StartValue, as the loop exits before wrapping.
1235 if (!Info.Unsigned)
1236 WorkList.push_back(FactOrCheck::getConditionFact(
1237 DTN, CmpInst::ICMP_UGE, PN, StartValue, StartBeforeBoundUnsigned));
1238 if (!Info.Signed)
1239 WorkList.push_back(FactOrCheck::getConditionFact(
1240 DTN, CmpInst::ICMP_SGE, PN, StartValue, StartBeforeBoundSigned));
1241 // Add PN < B, as the loop exits once the compared value reaches B.
1242 WorkList.push_back(FactOrCheck::getConditionFact(DTN, CmpInst::ICMP_SLT, PN,
1243 B, StartBeforeBoundSigned));
1244 WorkList.push_back(FactOrCheck::getConditionFact(
1245 DTN, CmpInst::ICMP_ULT, PN, B, StartBeforeBoundUnsigned));
1246
1247 // Try to add condition from the header or latch to the dedicated exit
1248 // blocks. When exiting either with EQ or NE, we know that the induction value
1249 // must be u<= B, as other exits may only exit earlier.
1250 assert(!StepOffset->isNegative() && "induction must be increasing");
1251 assert(ContinuePred == CmpInst::ICMP_NE && "unsupported predicate");
1253 L->getExitBlocks(ExitBBs);
1254 for (BasicBlock *EB : ExitBBs) {
1255 // Bail out on non-dedicated exits.
1256 if (DT.dominates(&BB, EB)) {
1257 WorkList.emplace_back(FactOrCheck::getConditionFact(
1258 DT.getNode(EB), CmpInst::ICMP_ULE, A, B, StartBeforeBoundUnsigned));
1259 }
1260 }
1261}
1262
1264 uint64_t AccessSize,
1265 CmpPredicate &Pred, Value *&A,
1266 Value *&B, const DataLayout &DL,
1267 const TargetLibraryInfo &TLI) {
1269 if (!Offset.NW.hasNoUnsignedWrap())
1270 return false;
1271
1272 if (Offset.VariableOffsets.size() != 1)
1273 return false;
1274
1275 uint64_t BitWidth = Offset.ConstantOffset.getBitWidth();
1276 auto &[Index, Scale] = Offset.VariableOffsets.front();
1277 // Bail out on non-canonical GEPs.
1278 if (Index->getType()->getScalarSizeInBits() != BitWidth)
1279 return false;
1280
1281 ObjectSizeOpts Opts;
1282 // Workaround for gep inbounds, ptr null, idx.
1283 Opts.NullIsUnknownSize = true;
1284 // Be conservative since we are not clear on whether an out of bounds access
1285 // to the padding is UB or not.
1286 Opts.RoundToAlign = true;
1287 std::optional<TypeSize> Size =
1288 getBaseObjectSize(Offset.BasePtr, DL, &TLI, Opts);
1289 if (!Size || Size->isScalable())
1290 return false;
1291
1292 // Index * Scale + ConstOffset + AccessSize <= AllocSize
1293 // With nuw flag, we know that the index addition doesn't have unsigned wrap.
1294 // If (AllocSize - (ConstOffset + AccessSize)) wraps around, there is no valid
1295 // value for Index.
1296 APInt MaxIndex = (APInt(BitWidth, Size->getFixedValue() - AccessSize,
1297 /*isSigned=*/false, /*implicitTrunc=*/true) -
1298 Offset.ConstantOffset)
1299 .udiv(Scale);
1300 Pred = ICmpInst::ICMP_ULE;
1301 A = Index;
1302 B = ConstantInt::get(Index->getType(), MaxIndex);
1303 return true;
1304}
1305
1306/// Returns true if \p I is a candidate whose poison-generating flags may be
1307/// strengthened using the constraint systems.
1309 auto *BO = dyn_cast<BinaryOperator>(I);
1310 if (!BO || !BO->getType()->isIntegerTy())
1311 return false;
1312
1313 switch (BO->getOpcode()) {
1314 case Instruction::Sub:
1315 // A - B does not wrap unsigned, if A >=u B. Subs with constant operands get
1316 // canonicalized to Add.
1317 return !BO->hasNoUnsignedWrap() && !isa<Constant>(BO->getOperand(1));
1318 case Instruction::Add:
1319 // NSW/NUW can be refined using constant ranges.
1320 return (!BO->hasNoUnsignedWrap() || !BO->hasNoSignedWrap()) &&
1321 isa<Constant>(BO->getOperand(1));
1322 case Instruction::Mul:
1323 case Instruction::Shl:
1324 if (BO->hasNoUnsignedWrap() && BO->hasNoSignedWrap())
1325 return false;
1326 // With a constant second operand, we can use bounds on the first operand to
1327 // refine no-wrap flags. Independently, nuw can be added for nsw if the
1328 // operands are non-negative.
1329 return isa<ConstantInt>(BO->getOperand(1)) || BO->hasNoSignedWrap();
1330 default:
1331 return false;
1332 }
1333}
1334
1335/// Returns true if \p Info implies that \p Op is in \p R, interpreting \p R as
1336/// a signed range if \p Signed is set and as an unsigned range otherwise.
1337static bool doesHoldInRange(const ConstraintInfo &Info, Value *Op,
1338 const ConstantRange &R, bool Signed) {
1339 if (R.isEmptySet() || (Signed ? R.isSignWrappedSet() : R.isWrappedSet()))
1340 return false;
1341
1342 if (R.isFullSet())
1343 return true;
1344
1345 unsigned BitWidth = R.getBitWidth();
1346 APInt Min = Signed ? R.getSignedMin() : R.getUnsignedMin();
1347 APInt Max = Signed ? R.getSignedMax() : R.getUnsignedMax();
1352 Type *Ty = Op->getType();
1353 if (Min != MinVal &&
1354 !Info.doesHold(Signed ? CmpInst::ICMP_SGE : CmpInst::ICMP_UGE, Op,
1355 ConstantInt::get(Ty, Min)))
1356 return false;
1357 if (Max != MaxVal &&
1358 !Info.doesHold(Signed ? CmpInst::ICMP_SLE : CmpInst::ICMP_ULE, Op,
1359 ConstantInt::get(Ty, Max)))
1360 return false;
1361 return true;
1362}
1363
1365 ConstraintInfo &Info) {
1366 auto *C = dyn_cast<ConstantInt>(Op1);
1367 if (!C)
1368 return false;
1369
1370 // For a constant Op1, the ranges of Op0 for which the operation does not
1371 // wrap are known exactly; check if the systems imply one of them.
1372 bool Changed = false;
1373 auto Opcode = static_cast<Instruction::BinaryOps>(I->getOpcode());
1374 using OBO = OverflowingBinaryOperator;
1375 ConstantRange Other(C->getValue());
1376 if (!I->hasNoUnsignedWrap() &&
1377 doesHoldInRange(Info, Op0,
1379 Opcode, Other, OBO::NoUnsignedWrap),
1380 /*Signed=*/false)) {
1381 LLVM_DEBUG(dbgs() << "Adding nuw to " << *I << "\n");
1382 I->setHasNoUnsignedWrap();
1383 Changed = true;
1384 }
1385 if (!I->hasNoSignedWrap() &&
1386 doesHoldInRange(Info, Op0,
1388 Opcode, Other, OBO::NoSignedWrap),
1389 /*Signed=*/true)) {
1390 LLVM_DEBUG(dbgs() << "Adding nsw to " << *I << "\n");
1391 I->setHasNoSignedWrap();
1392 Changed = true;
1393 }
1394 return Changed;
1395}
1396
1397/// Try to strengthen \p I's poison generating flags using \p Info. Returns
1398/// true if \p I was modified.
1399static bool tryToStrengthenFlags(Instruction *I, ConstraintInfo &Info,
1401 assert(canStrengthenFlags(I) && "not a candidate for flag strengthening");
1402
1403 Value *Op0 = I->getOperand(0), *Op1 = I->getOperand(1);
1404 switch (I->getOpcode()) {
1405 case Instruction::Sub: {
1406 // Op0 - Op1 does not wrap unsigned, if Op0 >=u Op1.
1407 if (!Info.doesHold(CmpInst::ICMP_UGE, Op0, Op1))
1408 return false;
1409 LLVM_DEBUG(dbgs() << "Adding nuw to " << *I << "\n");
1410 I->setHasNoUnsignedWrap();
1411 return true;
1412 }
1413 case Instruction::Add:
1414 return tryToStrengthenBinOpFlags(I, Op0, Op1, Info);
1415 case Instruction::Mul:
1416 case Instruction::Shl: {
1417 auto Opcode = static_cast<Instruction::BinaryOps>(I->getOpcode());
1418 bool Changed = tryToStrengthenBinOpFlags(I, Op0, Op1, Info);
1419 if (!I->hasNoUnsignedWrap() && I->hasNoSignedWrap() &&
1420 Info.isKnownNonNegative(Op0) &&
1421 (Opcode == Instruction::Shl || Info.isKnownNonNegative(Op1))) {
1422 LLVM_DEBUG(dbgs() << "Adding nuw to " << *I << "\n");
1423 I->setHasNoUnsignedWrap();
1424 Changed = true;
1425 }
1426 return Changed;
1427 }
1428 default:
1429 return false;
1430 }
1431}
1432
1433void State::addInfoFor(BasicBlock &BB) {
1434 addBoundsForHeaderInductions(BB);
1435 addInfoForInductions(BB);
1436 auto &DL = BB.getDataLayout();
1437
1438 Value *A, *B;
1439 CmpPredicate Pred;
1440 // True as long as the current instruction is guaranteed to execute.
1441 bool GuaranteedToExecute = true;
1442 // Queue conditions and assumes.
1443 for (Instruction &I : BB) {
1444 if (match(&I, m_ICmpLike(Pred, m_Value(), m_Value()))) {
1445 for (Use &U : I.uses()) {
1446 auto *UserI = getContextInstForUse(U);
1447 auto *DTN = DT.getNode(UserI->getParent());
1448 if (!DTN)
1449 continue;
1450 WorkList.push_back(FactOrCheck::getCheck(DTN, &U));
1451 }
1452 continue;
1453 }
1454
1455 auto AddFactFromMemoryAccess = [&](Value *Ptr, Type *AccessType) {
1456 auto *GEP = dyn_cast<GetElementPtrInst>(Ptr);
1457 if (!GEP)
1458 return;
1459 TypeSize AccessSize = DL.getTypeStoreSize(AccessType);
1460 if (!AccessSize.isFixed())
1461 return;
1462 if (GuaranteedToExecute) {
1464 Pred, A, B, DL, TLI)) {
1465 // The memory access is guaranteed to execute when BB is entered,
1466 // hence the constraint holds on entry to BB.
1467 WorkList.emplace_back(FactOrCheck::getConditionFact(
1468 DT.getNode(I.getParent()), Pred, A, B));
1469 }
1470 } else {
1471 WorkList.emplace_back(
1472 FactOrCheck::getInstFact(DT.getNode(I.getParent()), &I));
1473 }
1474 };
1475
1476 if (auto *LI = dyn_cast<LoadInst>(&I)) {
1477 if (!LI->isVolatile())
1478 AddFactFromMemoryAccess(LI->getPointerOperand(), LI->getAccessType());
1479 }
1480 if (auto *SI = dyn_cast<StoreInst>(&I)) {
1481 if (!SI->isVolatile())
1482 AddFactFromMemoryAccess(SI->getPointerOperand(), SI->getAccessType());
1483 }
1484
1485 auto *II = dyn_cast<IntrinsicInst>(&I);
1486 Intrinsic::ID ID = II ? II->getIntrinsicID() : Intrinsic::not_intrinsic;
1487 switch (ID) {
1488 case Intrinsic::assume: {
1489 if (!match(I.getOperand(0), m_ICmpLike(Pred, m_Value(A), m_Value(B))))
1490 break;
1491 if (GuaranteedToExecute) {
1492 // The assume is guaranteed to execute when BB is entered, hence Cond
1493 // holds on entry to BB.
1494 WorkList.emplace_back(FactOrCheck::getConditionFact(
1495 DT.getNode(I.getParent()), Pred, A, B));
1496 } else {
1497 WorkList.emplace_back(
1498 FactOrCheck::getInstFact(DT.getNode(I.getParent()), &I));
1499 }
1500 break;
1501 }
1502 // Enqueue ssub_with_overflow for simplification.
1503 case Intrinsic::ssub_with_overflow:
1504 case Intrinsic::ucmp:
1505 case Intrinsic::scmp:
1506 WorkList.push_back(
1507 FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
1508 break;
1509 // Enqueue the intrinsics to add extra info.
1510 case Intrinsic::umin:
1511 case Intrinsic::umax:
1512 case Intrinsic::smin:
1513 case Intrinsic::smax:
1514 case Intrinsic::usub_sat:
1515 // TODO: handle llvm.abs as well
1516 WorkList.push_back(
1517 FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
1518 [[fallthrough]];
1519 case Intrinsic::uadd_sat:
1520 // TODO: Check if it is possible to instead only added the min/max facts
1521 // when simplifying uses of the min/max intrinsics.
1523 break;
1524 [[fallthrough]];
1525 case Intrinsic::abs:
1526 WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I));
1527 break;
1528 }
1529
1530 // Add facts from unsigned division, remainder and logical shift right, and
1531 // from signed remainder.
1532 // urem x, n: result < n and result <= x
1533 // udiv x, n: result <= x
1534 // lshr x, n: result <= x
1535 // srem x, n: result >= 0 and result <= x, if x >= 0
1536 // result < n, if n > 0
1537 if (auto *BO = dyn_cast<BinaryOperator>(&I)) {
1538 if ((BO->getOpcode() == Instruction::URem ||
1539 BO->getOpcode() == Instruction::UDiv ||
1540 BO->getOpcode() == Instruction::LShr ||
1541 BO->getOpcode() == Instruction::SRem) &&
1543 WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), BO));
1544 }
1545
1546 // Queue instructions whose flags may be strengthened based on the facts
1547 // that hold on entry to BB.
1548 if (canStrengthenFlags(&I))
1549 WorkList.push_back(FactOrCheck::getCheck(DT.getNode(&BB), &I));
1550
1551 GuaranteedToExecute &= isGuaranteedToTransferExecutionToSuccessor(&I);
1552 }
1553
1554 if (auto *Switch = dyn_cast<SwitchInst>(BB.getTerminator())) {
1555 for (auto &Case : Switch->cases()) {
1556 BasicBlock *Succ = Case.getCaseSuccessor();
1557 Value *V = Case.getCaseValue();
1558 if (!canAddSuccessor(BB, Succ))
1559 continue;
1560 WorkList.emplace_back(FactOrCheck::getConditionFact(
1561 DT.getNode(Succ), CmpInst::ICMP_EQ, Switch->getCondition(), V));
1562 }
1563 return;
1564 }
1565
1566 auto *Br = dyn_cast<CondBrInst>(BB.getTerminator());
1567 if (!Br)
1568 return;
1569
1570 Value *Cond = Br->getCondition();
1571
1572 // If the condition is a chain of ORs/AND and the successor only has the
1573 // current block as predecessor, queue conditions for the successor.
1574 Value *Op0, *Op1;
1575 if (match(Cond, m_LogicalOr(m_Value(Op0), m_Value(Op1))) ||
1576 match(Cond, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) {
1577 bool IsOr = match(Cond, m_LogicalOr());
1578 bool IsAnd = match(Cond, m_LogicalAnd());
1579 // If there's a select that matches both AND and OR, we need to commit to
1580 // one of the options. Arbitrarily pick OR.
1581 if (IsOr && IsAnd)
1582 IsAnd = false;
1583
1584 BasicBlock *Successor = Br->getSuccessor(IsOr ? 1 : 0);
1585 if (canAddSuccessor(BB, Successor)) {
1586 SmallVector<Value *> CondWorkList;
1587 SmallPtrSet<Value *, 8> SeenCond;
1588 auto QueueValue = [&CondWorkList, &SeenCond](Value *V) {
1589 if (SeenCond.insert(V).second)
1590 CondWorkList.push_back(V);
1591 };
1592 QueueValue(Op1);
1593 QueueValue(Op0);
1594 while (!CondWorkList.empty()) {
1595 Value *Cur = CondWorkList.pop_back_val();
1596 if (match(Cur, m_ICmpLike(Pred, m_Value(A), m_Value(B)))) {
1597 WorkList.emplace_back(FactOrCheck::getConditionFact(
1598 DT.getNode(Successor),
1599 IsOr ? CmpPredicate::getInverse(Pred) : Pred, A, B));
1600 continue;
1601 }
1602 if (IsOr && match(Cur, m_LogicalOr(m_Value(Op0), m_Value(Op1)))) {
1603 QueueValue(Op1);
1604 QueueValue(Op0);
1605 continue;
1606 }
1607 if (IsAnd && match(Cur, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) {
1608 QueueValue(Op1);
1609 QueueValue(Op0);
1610 continue;
1611 }
1612 }
1613 }
1614 return;
1615 }
1616
1617 if (!match(Br->getCondition(), m_ICmpLike(Pred, m_Value(A), m_Value(B))))
1618 return;
1619 if (canAddSuccessor(BB, Br->getSuccessor(0)))
1620 WorkList.emplace_back(FactOrCheck::getConditionFact(
1621 DT.getNode(Br->getSuccessor(0)), Pred, A, B));
1622 if (canAddSuccessor(BB, Br->getSuccessor(1)))
1623 WorkList.emplace_back(FactOrCheck::getConditionFact(
1624 DT.getNode(Br->getSuccessor(1)), CmpPredicate::getInverse(Pred), A, B));
1625}
1626
1627#ifndef NDEBUG
1629 Value *LHS, Value *RHS) {
1630 OS << "icmp " << Pred << ' ';
1631 LHS->printAsOperand(OS, /*PrintType=*/true);
1632 OS << ", ";
1633 RHS->printAsOperand(OS, /*PrintType=*/false);
1634}
1635#endif
1636
1637namespace {
1638/// Helper to keep track of a condition and if it should be treated as negated
1639/// for reproducer construction.
1640/// Pred == Predicate::BAD_ICMP_PREDICATE indicates that this entry is a
1641/// placeholder to keep the ReproducerCondStack in sync with DFSInStack.
1642struct ReproducerEntry {
1643 ICmpInst::Predicate Pred;
1644 Value *LHS;
1645 Value *RHS;
1646
1647 ReproducerEntry(ICmpInst::Predicate Pred, Value *LHS, Value *RHS)
1648 : Pred(Pred), LHS(LHS), RHS(RHS) {}
1649};
1650} // namespace
1651
1652/// Helper function to generate a reproducer function for simplifying \p Cond.
1653/// The reproducer function contains a series of @llvm.assume calls, one for
1654/// each condition in \p Stack. For each condition, the operand instruction are
1655/// cloned until we reach operands that have an entry in \p Value2Index. Those
1656/// will then be added as function arguments. \p DT is used to order cloned
1657/// instructions. The reproducer function will get added to \p M, if it is
1658/// non-null. Otherwise no reproducer function is generated.
1659static void generateReproducer(Instruction *Cond, bool IsSigned, Module *M,
1661 ConstraintInfo &Info, DominatorTree &DT) {
1662 if (!M)
1663 return;
1664
1665 LLVMContext &Ctx = Cond->getContext();
1666
1667 LLVM_DEBUG(dbgs() << "Creating reproducer for " << *Cond << "\n");
1668
1669 ValueToValueMapTy Old2New;
1672 // Traverse Cond and its operands recursively until we reach a value that's in
1673 // Value2Index or not an instruction, or not a operation that
1674 // ConstraintElimination can decompose. Such values will be considered as
1675 // external inputs to the reproducer, they are collected and added as function
1676 // arguments later.
1677 auto CollectArguments = [&](ArrayRef<Value *> Ops, bool IsSigned) {
1678 auto &Value2Index = Info.getValue2Index(IsSigned);
1679 SmallVector<Value *, 4> WorkList(Ops);
1680 while (!WorkList.empty()) {
1681 Value *V = WorkList.pop_back_val();
1682 if (!Seen.insert(V).second)
1683 continue;
1684 if (Old2New.find(V) != Old2New.end())
1685 continue;
1686 if (isa<Constant>(V))
1687 continue;
1688
1689 auto *I = dyn_cast<Instruction>(V);
1690 if (Value2Index.contains(V) || !I ||
1692 Old2New[V] = V;
1693 Args.push_back(V);
1694 LLVM_DEBUG(dbgs() << " found external input " << *V << "\n");
1695 } else {
1696 append_range(WorkList, I->operands());
1697 }
1698 }
1699 };
1700
1701 for (auto &Entry : Stack)
1702 if (Entry.Pred != ICmpInst::BAD_ICMP_PREDICATE)
1703 CollectArguments({Entry.LHS, Entry.RHS}, ICmpInst::isSigned(Entry.Pred));
1704 CollectArguments(Cond, IsSigned);
1705
1706 SmallVector<Type *> ParamTys;
1707 for (auto *P : Args)
1708 ParamTys.push_back(P->getType());
1709
1710 FunctionType *FTy = FunctionType::get(Cond->getType(), ParamTys,
1711 /*isVarArg=*/false);
1713 Cond->getModule()->getName() +
1714 Cond->getFunction()->getName() + "repro",
1715 M);
1716 // Add arguments to the reproducer function for each external value collected.
1717 for (unsigned I = 0; I < Args.size(); ++I) {
1718 F->getArg(I)->setName(Args[I]->getName());
1719 Old2New[Args[I]] = F->getArg(I);
1720 }
1721
1722 BasicBlock *Entry = BasicBlock::Create(Ctx, "entry", F);
1723 IRBuilder<> Builder(Entry);
1724 Builder.CreateRet(Builder.getTrue());
1725 Builder.SetInsertPoint(Entry->getTerminator());
1726
1727 // Clone instructions in \p Ops and their operands recursively until reaching
1728 // an value in Value2Index (external input to the reproducer). Update Old2New
1729 // mapping for the original and cloned instructions. Sort instructions to
1730 // clone by dominance, then insert the cloned instructions in the function.
1731 auto CloneInstructions = [&](ArrayRef<Value *> Ops, bool IsSigned) {
1732 SmallVector<Value *, 4> WorkList(Ops);
1734 auto &Value2Index = Info.getValue2Index(IsSigned);
1735 while (!WorkList.empty()) {
1736 Value *V = WorkList.pop_back_val();
1737 if (Old2New.find(V) != Old2New.end())
1738 continue;
1739
1740 auto *I = dyn_cast<Instruction>(V);
1741 if (!Value2Index.contains(V) && I) {
1742 Old2New[V] = nullptr;
1743 ToClone.push_back(I);
1744 append_range(WorkList, I->operands());
1745 }
1746 }
1747
1748 sort(ToClone,
1749 [&DT](Instruction *A, Instruction *B) { return DT.dominates(A, B); });
1750 for (Instruction *I : ToClone) {
1751 Instruction *Cloned = I->clone();
1752 Old2New[I] = Cloned;
1753 Old2New[I]->setName(I->getName());
1754 Cloned->insertBefore(Builder.GetInsertPoint());
1756 Cloned->setDebugLoc({});
1757 }
1758 };
1759
1760 // Materialize the assumptions for the reproducer using the entries in Stack.
1761 // That is, first clone the operands of the condition recursively until we
1762 // reach an external input to the reproducer and add them to the reproducer
1763 // function. Then add an ICmp for the condition (with the inverse predicate if
1764 // the entry is negated) and an assert using the ICmp.
1765 for (auto &Entry : Stack) {
1766 if (Entry.Pred == ICmpInst::BAD_ICMP_PREDICATE)
1767 continue;
1768
1769 LLVM_DEBUG(dbgs() << " Materializing assumption ";
1770 dumpUnpackedICmp(dbgs(), Entry.Pred, Entry.LHS, Entry.RHS);
1771 dbgs() << "\n");
1772 CloneInstructions({Entry.LHS, Entry.RHS}, CmpInst::isSigned(Entry.Pred));
1773
1774 auto *Cmp = Builder.CreateICmp(Entry.Pred, Entry.LHS, Entry.RHS);
1775 Builder.CreateAssumption(Cmp);
1776 }
1777
1778 // Finally, clone the condition to reproduce and remap instruction operands in
1779 // the reproducer using Old2New.
1780 CloneInstructions(Cond, IsSigned);
1781 Entry->getTerminator()->setOperand(0, Cond);
1782 remapInstructionsInBlocks({Entry}, Old2New);
1783
1784 assert(!verifyFunction(*F, &dbgs()));
1785}
1786
1787static std::optional<bool> checkCondition(CmpInst::Predicate Pred, Value *A,
1788 Value *B, Instruction *CheckInst,
1789 ConstraintInfo &Info) {
1790 LLVM_DEBUG(dbgs() << "Checking " << *CheckInst << "\n");
1791
1792 auto TryWithConstraint = [&](const ConstraintTy &R) -> std::optional<bool> {
1793 if (R.empty()) {
1794 LLVM_DEBUG(dbgs() << " failed to decompose condition\n");
1795 return std::nullopt;
1796 }
1797
1798 auto &CSToUse = Info.getCS(R.IsSigned);
1799 if (auto ImpliedCondition = R.isImpliedBy(CSToUse)) {
1800 if (!DebugCounter::shouldExecute(EliminatedCounter))
1801 return std::nullopt;
1802 LLVM_DEBUG({
1803 dbgs() << "Condition ";
1805 *ImpliedCondition ? Pred
1807 A, B);
1808 dbgs() << " implied by dominating constraints\n";
1809 CSToUse.dump();
1810 });
1811 return ImpliedCondition;
1812 }
1813 return std::nullopt;
1814 };
1815
1816 auto R = Info.getConstraintForSolving(Pred, A, B);
1817 if (auto ImpliedCondition = TryWithConstraint(R))
1818 return ImpliedCondition;
1819
1820 // For non-negative operands unsigned queries can also be checked against the
1821 // signed system.
1822 if (CmpInst::isUnsigned(Pred) && A->getType()->isIntegerTy()) {
1823 SmallVector<Value *> NewVariables;
1824 auto SR = Info.getConstraint(ICmpInst::getSignedPredicate(Pred), A, B,
1825 NewVariables);
1826 if (NewVariables.empty() && !SR.empty() && Info.isKnownNonNegative(A) &&
1827 Info.isKnownNonNegative(B))
1828 if (auto ImpliedCondition = TryWithConstraint(SR))
1829 return ImpliedCondition;
1830 }
1831
1832 // Additionally, query the signed system for eq/ne predicates if we know about
1833 // A or B.
1834 if (CmpInst::isEquality(Pred)) {
1835 const auto &Value2Index = Info.getValue2Index(/*Signed=*/true);
1836 if (!Value2Index.contains(A) && !Value2Index.contains(B))
1837 return std::nullopt;
1838
1839 SmallVector<Value *> NewVariables;
1840 auto SR = Info.getConstraint(Pred, A, B, NewVariables,
1841 /*ForceSignedSystem=*/true);
1842 if (NewVariables.empty())
1843 if (auto ImpliedCondition = TryWithConstraint(SR))
1844 return ImpliedCondition;
1845 }
1846 return std::nullopt;
1847}
1848
1850 CmpPredicate Pred, Value *A, Value *B, Instruction *CheckInst,
1851 ConstraintInfo &Info, unsigned NumIn, unsigned NumOut,
1852 Instruction *ContextInst, Module *ReproducerModule,
1853 ArrayRef<ReproducerEntry> ReproducerCondStack, DominatorTree &DT,
1855 auto ReplaceCmpWithConstant = [&](Instruction *CheckInst, bool IsTrue) {
1856 generateReproducer(CheckInst, ICmpInst::isSigned(Pred), ReproducerModule,
1857 ReproducerCondStack, Info, DT);
1858 Constant *ConstantC = ConstantInt::getBool(
1859 CmpInst::makeCmpResultType(CheckInst->getType()), IsTrue);
1860 bool Changed = CheckInst->replaceUsesWithIf(ConstantC, [&](Use &U) {
1861 auto *UserI = getContextInstForUse(U);
1862 auto *DTN = DT.getNode(UserI->getParent());
1863 if (!DTN || DTN->getDFSNumIn() < NumIn || DTN->getDFSNumOut() > NumOut)
1864 return false;
1865 if (UserI->getParent() == ContextInst->getParent() &&
1866 UserI->comesBefore(ContextInst))
1867 return false;
1868
1869 // Conditions in an assume trivially simplify to true. Skip uses
1870 // in assume calls to not destroy the available information.
1871 auto *II = dyn_cast<IntrinsicInst>(U.getUser());
1872 return !II || II->getIntrinsicID() != Intrinsic::assume;
1873 });
1874 NumCondsRemoved++;
1875
1876 // Update the debug value records that satisfy the same condition used
1877 // in replaceUsesWithIf.
1879 findDbgUsers(CheckInst, DVRUsers);
1880
1881 for (auto *DVR : DVRUsers) {
1882 auto *DTN = DT.getNode(DVR->getParent());
1883 if (!DTN || DTN->getDFSNumIn() < NumIn || DTN->getDFSNumOut() > NumOut)
1884 continue;
1885
1886 auto *MarkedI = DVR->getInstruction();
1887 if (MarkedI->getParent() == ContextInst->getParent() &&
1888 MarkedI->comesBefore(ContextInst))
1889 continue;
1890
1891 DVR->replaceVariableLocationOp(CheckInst, ConstantC);
1892 }
1893
1894 if (CheckInst->use_empty())
1895 ToRemove.push_back(CheckInst);
1896
1897 return Changed;
1898 };
1899
1900 if (auto ImpliedCondition = checkCondition(Pred, A, B, CheckInst, Info))
1901 return ReplaceCmpWithConstant(CheckInst, *ImpliedCondition);
1902
1903 // When the predicate is samesign and unsigned, we can also make use of the
1904 // signed predicate information.
1905 if (Pred.hasSameSign() && ICmpInst::isUnsigned(Pred))
1906 if (auto ImpliedCondition = checkCondition(
1907 ICmpInst::getSignedPredicate(Pred), A, B, CheckInst, Info))
1908 return ReplaceCmpWithConstant(CheckInst, *ImpliedCondition);
1909
1910 return false;
1911}
1912
1913static bool checkAndReplaceMinMax(MinMaxIntrinsic *MinMax, ConstraintInfo &Info,
1915 auto ReplaceMinMaxWithOperand = [&](MinMaxIntrinsic *MinMax, bool UseLHS) {
1916 // TODO: generate reproducer for min/max.
1917 MinMax->replaceAllUsesWith(MinMax->getOperand(UseLHS ? 0 : 1));
1918 ToRemove.push_back(MinMax);
1919 return true;
1920 };
1921
1922 ICmpInst::Predicate Pred =
1923 ICmpInst::getNonStrictPredicate(MinMax->getPredicate());
1924 if (auto ImpliedCondition = checkCondition(
1925 Pred, MinMax->getOperand(0), MinMax->getOperand(1), MinMax, Info))
1926 return ReplaceMinMaxWithOperand(MinMax, *ImpliedCondition);
1927 if (auto ImpliedCondition = checkCondition(
1928 Pred, MinMax->getOperand(1), MinMax->getOperand(0), MinMax, Info))
1929 return ReplaceMinMaxWithOperand(MinMax, !*ImpliedCondition);
1930 return false;
1931}
1932
1933static bool checkAndReplaceCmp(CmpIntrinsic *I, ConstraintInfo &Info,
1935 Value *LHS = I->getOperand(0);
1936 Value *RHS = I->getOperand(1);
1937 if (checkCondition(I->getGTPredicate(), LHS, RHS, I, Info).value_or(false)) {
1938 I->replaceAllUsesWith(ConstantInt::get(I->getType(), 1));
1939 ToRemove.push_back(I);
1940 return true;
1941 }
1942 if (checkCondition(I->getLTPredicate(), LHS, RHS, I, Info).value_or(false)) {
1943 I->replaceAllUsesWith(ConstantInt::getSigned(I->getType(), -1));
1944 ToRemove.push_back(I);
1945 return true;
1946 }
1947 if (checkCondition(ICmpInst::ICMP_EQ, LHS, RHS, I, Info).value_or(false)) {
1948 I->replaceAllUsesWith(ConstantInt::get(I->getType(), 0));
1949 ToRemove.push_back(I);
1950 return true;
1951 }
1952 return false;
1953}
1954
1955/// Try to replace \p USub by a plain subtract, if \p Info proves it cannot
1956/// saturate. Returns true if \p USub was replaced.
1957static bool checkAndReplaceUSubSat(SaturatingInst *USub, ConstraintInfo &Info,
1959 // usub.sat(A, B) is A - B exactly when A >=u B.
1960 Value *A = USub->getLHS();
1961 Value *B = USub->getRHS();
1962 if (!checkCondition(CmpInst::ICMP_UGE, A, B, USub, Info).value_or(false))
1963 return false;
1964
1965 IRBuilder<> Builder(USub);
1966 Value *Sub = Builder.CreateSub(A, B, "", /*HasNUW=*/true,
1967 /*HasNSW=*/Info.isKnownNonNegative(A));
1968 USub->replaceAllUsesWith(Sub);
1969 Sub->takeName(USub);
1970 ToRemove.push_back(USub);
1971 return true;
1972}
1973
1974static void
1975removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info,
1976 Module *ReproducerModule,
1977 SmallVectorImpl<ReproducerEntry> &ReproducerCondStack,
1978 SmallVectorImpl<StackEntry> &DFSInStack) {
1979 Info.popLastConstraint(E.IsSigned);
1980 // Remove variables in the system that went out of scope.
1981 auto &Mapping = Info.getValue2Index(E.IsSigned);
1982 for (Value *V : E.ValuesToRelease)
1983 Mapping.erase(V);
1984 Info.popLastNVariables(E.IsSigned, E.ValuesToRelease.size());
1985 DFSInStack.pop_back();
1986 if (ReproducerModule)
1987 ReproducerCondStack.pop_back();
1988}
1989
1990/// Check if either the first condition of an AND or OR is implied by the
1991/// (negated in case of OR) second condition or vice versa.
1993 FactOrCheck &CB, ConstraintInfo &Info, Module *ReproducerModule,
1994 SmallVectorImpl<ReproducerEntry> &ReproducerCondStack,
1995 SmallVectorImpl<StackEntry> &DFSInStack,
1997 Instruction *JoinOp = CB.getContextInst();
1998 if (JoinOp->use_empty())
1999 return false;
2000
2001 Instruction *CmpToCheck = cast<Instruction>(CB.getInstructionToSimplify());
2002 unsigned OtherOpIdx = JoinOp->getOperand(0) == CmpToCheck ? 1 : 0;
2003
2004 // Don't try to simplify the first condition of a select by the second, as
2005 // this may make the select more poisonous than the original one.
2006 // TODO: check if the first operand may be poison.
2007 if (OtherOpIdx != 0 && isa<SelectInst>(JoinOp))
2008 return false;
2009
2010 unsigned OldSize = DFSInStack.size();
2011 llvm::scope_exit InfoRestorer([&]() {
2012 // Remove entries again.
2013 while (OldSize < DFSInStack.size()) {
2014 StackEntry E = DFSInStack.back();
2015 removeEntryFromStack(E, Info, ReproducerModule, ReproducerCondStack,
2016 DFSInStack);
2017 }
2018 });
2019 bool IsOr = match(JoinOp, m_LogicalOr());
2020 SmallVector<Value *, 4> Worklist({JoinOp->getOperand(OtherOpIdx)});
2021 // Do a traversal of the AND/OR tree to add facts from leaf compares.
2022 while (!Worklist.empty()) {
2023 Value *Val = Worklist.pop_back_val();
2024 Value *LHS, *RHS;
2025 CmpPredicate Pred;
2026 if (match(Val, m_ICmpLike(Pred, m_Value(LHS), m_Value(RHS)))) {
2027 // For OR, check if the negated condition implies CmpToCheck.
2028 if (IsOr)
2029 Pred = CmpInst::getInversePredicate(Pred);
2030 // Optimistically add fact from the other compares in the AND/OR.
2031 Info.addFact(Pred, LHS, RHS, CB.NumIn, CB.NumOut, DFSInStack);
2032 continue;
2033 }
2034 if (IsOr ? match(Val, m_LogicalOr(m_Value(LHS), m_Value(RHS)))
2035 : match(Val, m_LogicalAnd(m_Value(LHS), m_Value(RHS)))) {
2036 Worklist.push_back(LHS);
2037 Worklist.push_back(RHS);
2038 }
2039 }
2040 if (OldSize == DFSInStack.size())
2041 return false;
2042
2043 Value *A, *B;
2044 CmpPredicate Pred;
2045 [[maybe_unused]] bool Matched =
2046 match(CmpToCheck, m_ICmpLike(Pred, m_Value(A), m_Value(B)));
2047 assert(Matched && "expected icmp-like match");
2048 // Check if the second condition can be simplified now.
2049 if (auto ImpliedCondition = checkCondition(Pred, A, B, CmpToCheck, Info)) {
2050 if (IsOr == *ImpliedCondition)
2051 JoinOp->replaceAllUsesWith(
2052 ConstantInt::getBool(JoinOp->getType(), *ImpliedCondition));
2053 else
2054 JoinOp->replaceAllUsesWith(JoinOp->getOperand(OtherOpIdx));
2055 ToRemove.push_back(JoinOp);
2056 return true;
2057 }
2058
2059 return false;
2060}
2061
2062void ConstraintInfo::addFact(CmpInst::Predicate Pred, Value *A, Value *B,
2063 unsigned NumIn, unsigned NumOut,
2064 SmallVectorImpl<StackEntry> &DFSInStack) {
2065 addFactImpl(Pred, A, B, NumIn, NumOut, DFSInStack, false);
2066 // If the Pred is eq/ne, also add the fact to signed system.
2067 if (CmpInst::isEquality(Pred))
2068 addFactImpl(Pred, A, B, NumIn, NumOut, DFSInStack, true);
2069 if (Pred == CmpInst::ICMP_NE)
2070 tightenBoundUsingNe(A, B, NumIn, NumOut, DFSInStack);
2071}
2072
2073void ConstraintInfo::tightenBoundUsingNe(
2074 Value *A, Value *B, unsigned NumIn, unsigned NumOut,
2075 SmallVectorImpl<StackEntry> &DFSInStack) {
2076 if (!A->getType()->isIntegerTy())
2077 return;
2078
2079 for (bool IsSigned : {false, true}) {
2080 // In the unsigned system `A u>= 0` holds for every A, so getConstraint
2081 // already turned `A != 0` into `A u> 0`.
2082 if (!IsSigned && match(B, m_Zero()))
2083 continue;
2084
2085 // Skip if there are any unknown variables.
2086 const auto &Value2Index = getValue2Index(IsSigned);
2087 if (any_of(decompose(A, *this, IsSigned, DL).Vars,
2088 [&Value2Index](const DecompEntry &E) {
2089 return !Value2Index.contains(E.Variable);
2090 }))
2091 continue;
2092
2093 // If the system implies `A >= B` then together with `A != B` we get the
2094 // strict `A > B`; symmetrically `A <= B` becomes `A < B`.
2095 CmpInst::Predicate GEPred =
2097 CmpInst::Predicate LEPred =
2099 for (CmpInst::Predicate NonStrict : {GEPred, LEPred}) {
2100 if (!doesHold(NonStrict, A, B))
2101 continue;
2103 LLVM_DEBUG(dbgs() << "Tightening '";
2104 dumpUnpackedICmp(dbgs(), NonStrict, A, B); dbgs() << "' to '";
2106 dbgs() << "' using inequality\n");
2107 addFactImpl(Strict, A, B, NumIn, NumOut, DFSInStack,
2108 /*ForceSignedSystem=*/false);
2109 break;
2110 }
2111 }
2112}
2113
2114void ConstraintInfo::addFactImpl(CmpInst::Predicate Pred, Value *A, Value *B,
2115 unsigned NumIn, unsigned NumOut,
2116 SmallVectorImpl<StackEntry> &DFSInStack,
2117 bool ForceSignedSystem) {
2118 SmallVector<Value *> NewVariables;
2119 auto R = getConstraint(Pred, A, B, NewVariables, ForceSignedSystem);
2120
2121 // TODO: Support non-equality for facts as well.
2122 if (R.empty() || R.isNe())
2123 return;
2124
2125 LLVM_DEBUG(dbgs() << "Adding '"; dumpUnpackedICmp(dbgs(), Pred, A, B);
2126 dbgs() << "'\n");
2127 auto &CSToUse = getCS(R.IsSigned);
2128 bool Added = CSToUse.addRow(R.Coefficients, R.NumVars);
2129 if (!Added)
2130 return;
2131
2132 // If R has been added to the system, add the new variables and queue it for
2133 // removal once it goes out-of-scope.
2134 SmallVector<Value *, 2> ValuesToRelease;
2135 auto &Value2Index = getValue2Index(R.IsSigned);
2136 for (Value *V : NewVariables) {
2137 Value2Index.try_emplace(V, Value2Index.size() + 1);
2138 ValuesToRelease.push_back(V);
2139 }
2140
2141 LLVM_DEBUG({
2142 dbgs() << " constraint: ";
2143 dumpConstraint(R.Coefficients, getValue2Index(R.IsSigned));
2144 dbgs() << "\n";
2145 });
2146
2147 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
2148 std::move(ValuesToRelease));
2149
2150 if (!R.IsSigned) {
2151 for (Value *V : NewVariables) {
2152 // Add V > -1 constraints for all new variables.
2153 CSToUse.addRow({Entry(0, 0), Entry(-1, Value2Index.at(V))},
2154 Value2Index.size());
2155 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
2156 SmallVector<Value *, 2>());
2157 }
2158 }
2159
2160 if (R.isEq()) {
2161 // Also add the inverted constraint for equality constraints.
2162 for (Entry &E : R.Coefficients)
2163 if (MulOverflow(E.Coefficient, int64_t(-1), E.Coefficient))
2164 return;
2165 CSToUse.addRow(R.Coefficients, R.NumVars);
2166
2167 DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
2168 SmallVector<Value *, 2>());
2169 }
2170}
2171
2174 bool Changed = false;
2175 IRBuilder<> Builder(II->getParent(), II->getIterator());
2176 Value *Sub = nullptr;
2177 for (User *U : make_early_inc_range(II->users())) {
2178 if (match(U, m_ExtractValue<0>(m_Value()))) {
2179 if (!Sub)
2180 Sub = Builder.CreateNSWSub(A, B);
2181 U->replaceAllUsesWith(Sub);
2182 Changed = true;
2183 } else if (match(U, m_ExtractValue<1>(m_Value()))) {
2184 U->replaceAllUsesWith(Builder.getFalse());
2185 Changed = true;
2186 } else
2187 continue;
2188
2189 if (U->use_empty()) {
2190 auto *I = cast<Instruction>(U);
2191 ToRemove.push_back(I);
2192 I->setOperand(0, PoisonValue::get(II->getType()));
2193 Changed = true;
2194 }
2195 }
2196
2197 if (II->use_empty()) {
2198 // Do not erase II here: the worklist may still hold Uses of II's operands.
2199 for (Use &Arg : II->args())
2200 Arg.set(PoisonValue::get(Arg->getType()));
2201 ToRemove.push_back(II);
2202 Changed = true;
2203 }
2204 return Changed;
2205}
2206
2207static bool
2210 auto DoesConditionHold = [](CmpInst::Predicate Pred, Value *A, Value *B,
2211 ConstraintInfo &Info) {
2212 auto R = Info.getConstraintForSolving(Pred, A, B);
2213 // Nothing can be proven if the constraint has no variables. This also
2214 // covers rows that could not be decomposed, which are empty.
2215 if (R.isConstantOnly())
2216 return false;
2217
2218 auto &CSToUse = Info.getCS(R.IsSigned);
2219 return CSToUse.isConditionImpliedInSubSystem(R.Coefficients);
2220 };
2221
2222 bool Changed = false;
2223 if (II->getIntrinsicID() == Intrinsic::ssub_with_overflow) {
2224 // If A s>= B && B s>= 0, ssub.with.overflow(a, b) should not overflow and
2225 // can be simplified to a regular sub.
2226 Value *A = II->getArgOperand(0);
2227 Value *B = II->getArgOperand(1);
2228 if (!DoesConditionHold(CmpInst::ICMP_SGE, A, B, Info) ||
2229 !DoesConditionHold(CmpInst::ICMP_SGE, B,
2230 ConstantInt::get(A->getType(), 0), Info))
2231 return false;
2233 }
2234 return Changed;
2235}
2236
2238 ScalarEvolution &SE,
2240 TargetLibraryInfo &TLI) {
2241 bool Changed = false;
2242 DT.updateDFSNumbers();
2243 SmallVector<Value *> FunctionArgs(llvm::make_pointer_range(F.args()));
2244 ConstraintInfo Info(F.getDataLayout(), FunctionArgs);
2245 State S(DT, LI, SE, TLI);
2246 std::unique_ptr<Module> ReproducerModule(
2247 DumpReproducers ? new Module(F.getName(), F.getContext()) : nullptr);
2248
2249 // First, collect conditions implied by branches and blocks with their
2250 // Dominator DFS in and out numbers.
2251 for (BasicBlock &BB : F) {
2252 if (!DT.getNode(&BB))
2253 continue;
2254 S.addInfoFor(BB);
2255 }
2256
2257 // Next, sort worklist by dominance, so that dominating conditions to check
2258 // and facts come before conditions and facts dominated by them. If a
2259 // condition to check and a fact have the same numbers, conditional facts come
2260 // first. Assume facts and checks are ordered according to their relative
2261 // order in the containing basic block. Also make sure conditions with
2262 // constant operands come before conditions without constant operands. This
2263 // increases the effectiveness of the current signed <-> unsigned fact
2264 // transfer logic.
2265 stable_sort(S.WorkList, [](const FactOrCheck &A, const FactOrCheck &B) {
2266 auto HasNoConstOp = [](const FactOrCheck &B) {
2267 Value *V0 = B.isConditionFact() ? B.Cond.Op0 : B.Inst->getOperand(0);
2268 Value *V1 = B.isConditionFact() ? B.Cond.Op1 : B.Inst->getOperand(1);
2269 return !isa<ConstantInt>(V0) && !isa<ConstantInt>(V1);
2270 };
2271 // If both entries have the same In numbers, conditional facts come first.
2272 // Otherwise use the relative order in the basic block.
2273 if (A.NumIn == B.NumIn) {
2274 if (A.isConditionFact() && B.isConditionFact()) {
2275 bool NoConstOpA = HasNoConstOp(A);
2276 bool NoConstOpB = HasNoConstOp(B);
2277 return NoConstOpA < NoConstOpB;
2278 }
2279 if (A.isConditionFact())
2280 return true;
2281 if (B.isConditionFact())
2282 return false;
2283 auto *InstA = A.getContextInst();
2284 auto *InstB = B.getContextInst();
2285 return InstA->comesBefore(InstB);
2286 }
2287 return A.NumIn < B.NumIn;
2288 });
2289
2290 SmallVector<Instruction *> ToRemove;
2291
2292 // Finally, process ordered worklist and eliminate implied conditions.
2293 SmallVector<StackEntry, 16> DFSInStack;
2294 SmallVector<ReproducerEntry> ReproducerCondStack;
2295 for (FactOrCheck &CB : S.WorkList) {
2296 // First, pop entries from the stack that are out-of-scope for CB. Remove
2297 // the corresponding entry from the constraint system.
2298 while (!DFSInStack.empty()) {
2299 auto &E = DFSInStack.back();
2300 LLVM_DEBUG(dbgs() << "Top of stack : " << E.NumIn << " " << E.NumOut
2301 << "\n");
2302 LLVM_DEBUG(dbgs() << "CB: " << CB.NumIn << " " << CB.NumOut << "\n");
2303 assert(E.NumIn <= CB.NumIn);
2304 if (CB.NumOut <= E.NumOut)
2305 break;
2306 LLVM_DEBUG({
2307 dbgs() << "Removing ";
2308 dumpConstraint(Info.getCS(E.IsSigned).getLastConstraint(),
2309 Info.getValue2Index(E.IsSigned));
2310 dbgs() << "\n";
2311 });
2312 removeEntryFromStack(E, Info, ReproducerModule.get(), ReproducerCondStack,
2313 DFSInStack);
2314 }
2315
2316 CmpPredicate Pred;
2317 Value *A, *B;
2318 // For a block, check if any CmpInsts become known based on the current set
2319 // of constraints.
2320 if (CB.isCheck()) {
2321 Instruction *Inst = CB.getInstructionToSimplify();
2322 if (!Inst)
2323 continue;
2324 if (canStrengthenFlags(Inst)) {
2325 Changed |= tryToStrengthenFlags(Inst, Info, ToRemove);
2326 continue;
2327 }
2328 LLVM_DEBUG(dbgs() << "Processing condition to simplify: " << *Inst
2329 << "\n");
2330 if (auto *II = dyn_cast<WithOverflowInst>(Inst)) {
2332 } else if (match(Inst, m_ICmpLike(Pred, m_Value(A), m_Value(B)))) {
2334 Pred, A, B, Inst, Info, CB.NumIn, CB.NumOut, CB.getContextInst(),
2335 ReproducerModule.get(), ReproducerCondStack, S.DT, ToRemove);
2336 if (!Simplified &&
2337 match(CB.getContextInst(), m_LogicalOp(m_Value(), m_Value()))) {
2339 CB, Info, ReproducerModule.get(), ReproducerCondStack, DFSInStack,
2340 ToRemove);
2341 }
2343 } else if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(Inst)) {
2344 Changed |= checkAndReplaceMinMax(MinMax, Info, ToRemove);
2345 } else if (auto *CmpIntr = dyn_cast<CmpIntrinsic>(Inst)) {
2346 Changed |= checkAndReplaceCmp(CmpIntr, Info, ToRemove);
2347 } else if (match(Inst, m_Intrinsic<Intrinsic::usub_sat>())) {
2348 Changed |=
2350 }
2351 continue;
2352 }
2353
2354 auto AddFact = [&](CmpPredicate Pred, Value *A, Value *B) {
2355 LLVM_DEBUG(dbgs() << "Processing fact to add to the system: ";
2356 dumpUnpackedICmp(dbgs(), Pred, A, B); dbgs() << "\n");
2357 if (Info.getCS(CmpInst::isSigned(Pred)).size() > MaxRows) {
2358 LLVM_DEBUG(
2359 dbgs()
2360 << "Skip adding constraint because system has too many rows.\n");
2361 return;
2362 }
2363
2364 Info.addFact(Pred, A, B, CB.NumIn, CB.NumOut, DFSInStack);
2365 if (ReproducerModule && DFSInStack.size() > ReproducerCondStack.size())
2366 ReproducerCondStack.emplace_back(Pred, A, B);
2367
2368 if (ICmpInst::isRelational(Pred)) {
2369 // If samesign is present on the ICmp, simply flip the sign of the
2370 // predicate, transferring the information from the signed system to the
2371 // unsigned system, and viceversa.
2372 if (Pred.hasSameSign())
2374 CB.NumIn, CB.NumOut, DFSInStack);
2375 else
2376 Info.transferToOtherSystem(Pred, A, B, CB.NumIn, CB.NumOut,
2377 DFSInStack);
2378 }
2379
2380 // (X | Y) >s -1 implies X >s -1 and Y >s -1, because the sign bit of an
2381 // OR is the OR of the operand sign bits. Similarly, (X & Y) <s 0 implies
2382 // X <s 0 and Y <s 0. Look through these canonical forms produced by
2383 // InstCombine so the sign facts on the operands are available to the
2384 // solver.
2385 if ((Pred == CmpInst::ICMP_SGT && match(B, m_AllOnes())) ||
2386 (Pred == CmpInst::ICMP_SLT && match(B, m_Zero()))) {
2387 unsigned Opc =
2388 Pred == CmpInst::ICMP_SGT ? Instruction::Or : Instruction::And;
2389 SmallVector<Value *> Worklist = {A};
2390 SmallPtrSet<Value *, 4> Seen;
2391 while (!Worklist.empty()) {
2392 Value *Cur = Worklist.pop_back_val();
2393 auto *BO = dyn_cast<BinaryOperator>(Cur);
2394 if (!BO || BO->getOpcode() != Opc)
2395 continue;
2396 for (Value *Op : {BO->getOperand(0), BO->getOperand(1)}) {
2397 if (!Seen.insert(Op).second)
2398 continue;
2399 Worklist.push_back(Op);
2400 Info.addFact(Pred, Op, B, CB.NumIn, CB.NumOut, DFSInStack);
2401 }
2402 }
2403 }
2404
2405 if (ReproducerModule && DFSInStack.size() > ReproducerCondStack.size()) {
2406 // Add dummy entries to ReproducerCondStack to keep it in sync with
2407 // DFSInStack.
2408 for (unsigned I = 0,
2409 E = (DFSInStack.size() - ReproducerCondStack.size());
2410 I < E; ++I) {
2411 ReproducerCondStack.emplace_back(ICmpInst::BAD_ICMP_PREDICATE,
2412 nullptr, nullptr);
2413 }
2414 }
2415 };
2416
2417 if (!CB.isConditionFact()) {
2418 Value *X;
2419 if (match(CB.Inst, m_Intrinsic<Intrinsic::abs>(m_Value(X)))) {
2420 // If is_int_min_poison is true then we may assume llvm.abs >= 0.
2421 if (cast<ConstantInt>(CB.Inst->getOperand(1))->isOne())
2422 AddFact(CmpInst::ICMP_SGE, CB.Inst,
2423 ConstantInt::get(CB.Inst->getType(), 0));
2424 AddFact(CmpInst::ICMP_SGE, CB.Inst, X);
2425 continue;
2426 }
2427
2428 if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(CB.Inst)) {
2429 Pred = ICmpInst::getNonStrictPredicate(MinMax->getPredicate());
2430 AddFact(Pred, MinMax, MinMax->getLHS());
2431 AddFact(Pred, MinMax, MinMax->getRHS());
2432 continue;
2433 }
2434 if (auto *USatI = dyn_cast<SaturatingInst>(CB.Inst)) {
2435 switch (USatI->getIntrinsicID()) {
2436 default:
2437 llvm_unreachable("Unexpected intrinsic.");
2438 case Intrinsic::uadd_sat:
2439 AddFact(ICmpInst::ICMP_UGE, USatI, USatI->getLHS());
2440 AddFact(ICmpInst::ICMP_UGE, USatI, USatI->getRHS());
2441 break;
2442 case Intrinsic::usub_sat:
2443 AddFact(ICmpInst::ICMP_ULE, USatI, USatI->getLHS());
2444 break;
2445 }
2446 continue;
2447 }
2448
2449 if (auto *BO = dyn_cast<BinaryOperator>(CB.Inst)) {
2450 if (BO->getOpcode() == Instruction::URem) {
2451 // urem x, n: result < n (remainder is always less than divisor)
2452 AddFact(CmpInst::ICMP_ULT, BO, BO->getOperand(1));
2453 // urem x, n: result <= x (remainder is at most the dividend)
2454 AddFact(CmpInst::ICMP_ULE, BO, BO->getOperand(0));
2455 continue;
2456 }
2457 if (BO->getOpcode() == Instruction::UDiv) {
2458 // udiv x, n: result <= x (quotient is at most the dividend)
2459 AddFact(CmpInst::ICMP_ULE, BO, BO->getOperand(0));
2460 continue;
2461 }
2462 if (BO->getOpcode() == Instruction::LShr) {
2463 // lshr x, n: result <= x (right shift cannot increase the value)
2464 AddFact(CmpInst::ICMP_ULE, BO, BO->getOperand(0));
2465 continue;
2466 }
2467 if (BO->getOpcode() == Instruction::SRem) {
2468 Value *X = BO->getOperand(0);
2469 Value *N = BO->getOperand(1);
2470 Constant *Zero = Constant::getNullValue(BO->getType());
2471 if (Info.doesHold(CmpInst::ICMP_SGE, X, Zero) ||
2472 isKnownNonNegative(X, F.getDataLayout())) {
2473 // srem x, n: result >= 0, if x >= 0 (result has the sign of x)
2474 AddFact(CmpInst::ICMP_SGE, BO, Zero);
2475 // srem x, n: result <= x, if x >= 0 (|result| <= |x| and both are
2476 // non-negative)
2477 AddFact(CmpInst::ICMP_SLE, BO, X);
2478 }
2479 if (Info.doesHold(CmpInst::ICMP_SGE, N, Zero) ||
2480 isKnownPositive(N, F.getDataLayout())) {
2481 // srem x, n: result <= n, if n >= 0 (|result| < n, so result <= n -
2482 // 1
2483 AddFact(CmpInst::ICMP_SLT, BO, N);
2484 }
2485 continue;
2486 }
2487 }
2488
2489 auto &DL = F.getDataLayout();
2490 auto AddFactsAboutIndices = [&](Value *Ptr, Type *AccessType) {
2491 CmpPredicate Pred;
2492 Value *A, *B;
2495 DL.getTypeStoreSize(AccessType).getFixedValue(), Pred, A, B, DL,
2496 TLI))
2497 AddFact(Pred, A, B);
2498 };
2499
2500 if (auto *LI = dyn_cast<LoadInst>(CB.Inst)) {
2501 AddFactsAboutIndices(LI->getPointerOperand(), LI->getAccessType());
2502 continue;
2503 }
2504 if (auto *SI = dyn_cast<StoreInst>(CB.Inst)) {
2505 AddFactsAboutIndices(SI->getPointerOperand(), SI->getAccessType());
2506 continue;
2507 }
2508 }
2509
2510 if (CB.isConditionFact()) {
2511 Pred = CB.Cond.Pred;
2512 A = CB.Cond.Op0;
2513 B = CB.Cond.Op1;
2514 if (CB.DoesHold.Pred != CmpInst::BAD_ICMP_PREDICATE &&
2515 !Info.doesHold(CB.DoesHold.Pred, CB.DoesHold.Op0, CB.DoesHold.Op1)) {
2516 LLVM_DEBUG({
2517 dbgs() << "Not adding fact ";
2518 dumpUnpackedICmp(dbgs(), Pred, A, B);
2519 dbgs() << " because precondition ";
2520 dumpUnpackedICmp(dbgs(), CB.DoesHold.Pred, CB.DoesHold.Op0,
2521 CB.DoesHold.Op1);
2522 dbgs() << " does not hold.\n";
2523 });
2524 continue;
2525 }
2526 } else {
2527 [[maybe_unused]] bool Matched =
2529 m_ICmpLike(Pred, m_Value(A), m_Value(B))));
2530 assert(Matched &&
2531 "Must have an assume intrinsic with a icmp like operand");
2532 }
2533 AddFact(Pred, A, B);
2534 }
2535
2536 if (ReproducerModule && !ReproducerModule->functions().empty()) {
2537 std::string S;
2538 raw_string_ostream StringS(S);
2539 ReproducerModule->print(StringS, nullptr);
2540 OptimizationRemark Rem(DEBUG_TYPE, "Reproducer", &F);
2541 Rem << ore::NV("module") << S;
2542 ORE.emit(Rem);
2543 }
2544
2545#ifndef NDEBUG
2546 unsigned SignedEntries =
2547 count_if(DFSInStack, [](const StackEntry &E) { return E.IsSigned; });
2548 assert(Info.getCS(false).size() - FunctionArgs.size() ==
2549 DFSInStack.size() - SignedEntries &&
2550 "updates to CS and DFSInStack are out of sync");
2551 assert(Info.getCS(true).size() == SignedEntries &&
2552 "updates to CS and DFSInStack are out of sync");
2553#endif
2554
2555 for (Instruction *I : ToRemove)
2556 I->eraseFromParent();
2557 return Changed;
2558}
2559
2562 auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
2563 auto &LI = AM.getResult<LoopAnalysis>(F);
2564 auto &SE = AM.getResult<ScalarEvolutionAnalysis>(F);
2566 auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
2567 if (!eliminateConstraints(F, DT, LI, SE, ORE, TLI))
2568 return PreservedAnalyses::all();
2569
2573 return PA;
2574}
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 bool tryToStrengthenBinOpFlags(Instruction *I, Value *Op0, Value *Op1, ConstraintInfo &Info)
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:1695
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)
LogicalOp_match< LHS, RHS, Instruction::And, true > m_c_LogicalAnd(const LHS &L, const RHS &R)
Matches L && R with LHS and RHS in either order.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
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".
LogicalOp_match< LHS, RHS, Instruction::Or, true > m_c_LogicalOr(const LHS &L, const RHS &R)
Matches L || R with LHS and RHS in either order.
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