xref: /llvm-project/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp (revision e6260ec49c5d16dc93ebe8b53e645200a0cfc0cd)
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 
14 #include "llvm/Transforms/Scalar/ConstraintElimination.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/ADT/ScopeExit.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/Statistic.h"
19 #include "llvm/Analysis/ConstraintSystem.h"
20 #include "llvm/Analysis/GlobalsModRef.h"
21 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
22 #include "llvm/Analysis/ValueTracking.h"
23 #include "llvm/IR/DataLayout.h"
24 #include "llvm/IR/Dominators.h"
25 #include "llvm/IR/Function.h"
26 #include "llvm/IR/GetElementPtrTypeIterator.h"
27 #include "llvm/IR/IRBuilder.h"
28 #include "llvm/IR/Instructions.h"
29 #include "llvm/IR/PatternMatch.h"
30 #include "llvm/IR/Verifier.h"
31 #include "llvm/Pass.h"
32 #include "llvm/Support/CommandLine.h"
33 #include "llvm/Support/Debug.h"
34 #include "llvm/Support/DebugCounter.h"
35 #include "llvm/Support/KnownBits.h"
36 #include "llvm/Support/MathExtras.h"
37 #include "llvm/Transforms/Utils/Cloning.h"
38 #include "llvm/Transforms/Utils/ValueMapper.h"
39 
40 #include <cmath>
41 #include <optional>
42 #include <string>
43 
44 using namespace llvm;
45 using namespace PatternMatch;
46 
47 #define DEBUG_TYPE "constraint-elimination"
48 
49 STATISTIC(NumCondsRemoved, "Number of instructions removed");
50 DEBUG_COUNTER(EliminatedCounter, "conds-eliminated",
51               "Controls which conditions are eliminated");
52 
53 static cl::opt<unsigned>
54     MaxRows("constraint-elimination-max-rows", cl::init(500), cl::Hidden,
55             cl::desc("Maximum number of rows to keep in constraint system"));
56 
57 static cl::opt<bool> DumpReproducers(
58     "constraint-elimination-dump-reproducers", cl::init(false), cl::Hidden,
59     cl::desc("Dump IR to reproduce successful transformations."));
60 
61 static int64_t MaxConstraintValue = std::numeric_limits<int64_t>::max();
62 static int64_t MinSignedConstraintValue = std::numeric_limits<int64_t>::min();
63 
64 // A helper to multiply 2 signed integers where overflowing is allowed.
65 static int64_t multiplyWithOverflow(int64_t A, int64_t B) {
66   int64_t Result;
67   MulOverflow(A, B, Result);
68   return Result;
69 }
70 
71 // A helper to add 2 signed integers where overflowing is allowed.
72 static int64_t addWithOverflow(int64_t A, int64_t B) {
73   int64_t Result;
74   AddOverflow(A, B, Result);
75   return Result;
76 }
77 
78 static Instruction *getContextInstForUse(Use &U) {
79   Instruction *UserI = cast<Instruction>(U.getUser());
80   if (auto *Phi = dyn_cast<PHINode>(UserI))
81     UserI = Phi->getIncomingBlock(U)->getTerminator();
82   return UserI;
83 }
84 
85 namespace {
86 /// Represents either
87 ///  * a condition that holds on entry to a block (=condition fact)
88 ///  * an assume (=assume fact)
89 ///  * a use of a compare instruction to simplify.
90 /// It also tracks the Dominator DFS in and out numbers for each entry.
91 struct FactOrCheck {
92   enum class EntryTy {
93     ConditionFact, /// A condition that holds on entry to a block.
94     InstFact,      /// A fact that holds after Inst executed (e.g. an assume or
95                    /// min/mix intrinsic.
96     InstCheck,     /// An instruction to simplify (e.g. an overflow math
97                    /// intrinsics).
98     UseCheck       /// An use of a compare instruction to simplify.
99   };
100 
101   union {
102     Instruction *Inst;
103     Use *U;
104   };
105 
106   unsigned NumIn;
107   unsigned NumOut;
108   EntryTy Ty;
109   bool Not;
110 
111   FactOrCheck(EntryTy Ty, DomTreeNode *DTN, Instruction *Inst, bool Not)
112       : Inst(Inst), NumIn(DTN->getDFSNumIn()), NumOut(DTN->getDFSNumOut()),
113         Ty(Ty), Not(Not) {}
114 
115   FactOrCheck(DomTreeNode *DTN, Use *U)
116       : U(U), NumIn(DTN->getDFSNumIn()), NumOut(DTN->getDFSNumOut()),
117         Ty(EntryTy::UseCheck), Not(false) {}
118 
119   static FactOrCheck getConditionFact(DomTreeNode *DTN, CmpInst *Inst,
120                                       bool Not = false) {
121     return FactOrCheck(EntryTy::ConditionFact, DTN, Inst, Not);
122   }
123 
124   static FactOrCheck getInstFact(DomTreeNode *DTN, Instruction *Inst,
125                                  bool Not = false) {
126     return FactOrCheck(EntryTy::InstFact, DTN, Inst, Not);
127   }
128 
129   static FactOrCheck getCheck(DomTreeNode *DTN, Use *U) {
130     return FactOrCheck(DTN, U);
131   }
132 
133   static FactOrCheck getCheck(DomTreeNode *DTN, CallInst *CI) {
134     return FactOrCheck(EntryTy::InstCheck, DTN, CI, false);
135   }
136 
137   bool isCheck() const {
138     return Ty == EntryTy::InstCheck || Ty == EntryTy::UseCheck;
139   }
140 
141   Instruction *getContextInst() const {
142     if (Ty == EntryTy::UseCheck)
143       return getContextInstForUse(*U);
144     return Inst;
145   }
146 
147   Instruction *getInstructionToSimplify() const {
148     assert(isCheck());
149     if (Ty == EntryTy::InstCheck)
150       return Inst;
151     // The use may have been simplified to a constant already.
152     return dyn_cast<Instruction>(*U);
153   }
154 
155   bool isConditionFact() const { return Ty == EntryTy::ConditionFact; }
156 };
157 
158 /// Keep state required to build worklist.
159 struct State {
160   DominatorTree &DT;
161   SmallVector<FactOrCheck, 64> WorkList;
162 
163   State(DominatorTree &DT) : DT(DT) {}
164 
165   /// Process block \p BB and add known facts to work-list.
166   void addInfoFor(BasicBlock &BB);
167 
168   /// Returns true if we can add a known condition from BB to its successor
169   /// block Succ.
170   bool canAddSuccessor(BasicBlock &BB, BasicBlock *Succ) const {
171     return DT.dominates(BasicBlockEdge(&BB, Succ), Succ);
172   }
173 };
174 
175 class ConstraintInfo;
176 
177 struct StackEntry {
178   unsigned NumIn;
179   unsigned NumOut;
180   bool IsSigned = false;
181   /// Variables that can be removed from the system once the stack entry gets
182   /// removed.
183   SmallVector<Value *, 2> ValuesToRelease;
184 
185   StackEntry(unsigned NumIn, unsigned NumOut, bool IsSigned,
186              SmallVector<Value *, 2> ValuesToRelease)
187       : NumIn(NumIn), NumOut(NumOut), IsSigned(IsSigned),
188         ValuesToRelease(ValuesToRelease) {}
189 };
190 
191 /// Struct to express a pre-condition of the form %Op0 Pred %Op1.
192 struct PreconditionTy {
193   CmpInst::Predicate Pred;
194   Value *Op0;
195   Value *Op1;
196 
197   PreconditionTy(CmpInst::Predicate Pred, Value *Op0, Value *Op1)
198       : Pred(Pred), Op0(Op0), Op1(Op1) {}
199 };
200 
201 struct ConstraintTy {
202   SmallVector<int64_t, 8> Coefficients;
203   SmallVector<PreconditionTy, 2> Preconditions;
204 
205   SmallVector<SmallVector<int64_t, 8>> ExtraInfo;
206 
207   bool IsSigned = false;
208 
209   ConstraintTy() = default;
210 
211   ConstraintTy(SmallVector<int64_t, 8> Coefficients, bool IsSigned, bool IsEq,
212                bool IsNe)
213       : Coefficients(Coefficients), IsSigned(IsSigned), IsEq(IsEq), IsNe(IsNe) {
214   }
215 
216   unsigned size() const { return Coefficients.size(); }
217 
218   unsigned empty() const { return Coefficients.empty(); }
219 
220   /// Returns true if all preconditions for this list of constraints are
221   /// satisfied given \p CS and the corresponding \p Value2Index mapping.
222   bool isValid(const ConstraintInfo &Info) const;
223 
224   bool isEq() const { return IsEq; }
225 
226   bool isNe() const { return IsNe; }
227 
228   /// Check if the current constraint is implied by the given ConstraintSystem.
229   ///
230   /// \return true or false if the constraint is proven to be respectively true,
231   /// or false. When the constraint cannot be proven to be either true or false,
232   /// std::nullopt is returned.
233   std::optional<bool> isImpliedBy(const ConstraintSystem &CS) const;
234 
235 private:
236   bool IsEq = false;
237   bool IsNe = false;
238 };
239 
240 /// Wrapper encapsulating separate constraint systems and corresponding value
241 /// mappings for both unsigned and signed information. Facts are added to and
242 /// conditions are checked against the corresponding system depending on the
243 /// signed-ness of their predicates. While the information is kept separate
244 /// based on signed-ness, certain conditions can be transferred between the two
245 /// systems.
246 class ConstraintInfo {
247 
248   ConstraintSystem UnsignedCS;
249   ConstraintSystem SignedCS;
250 
251   const DataLayout &DL;
252 
253 public:
254   ConstraintInfo(const DataLayout &DL, ArrayRef<Value *> FunctionArgs)
255       : UnsignedCS(FunctionArgs), SignedCS(FunctionArgs), DL(DL) {}
256 
257   DenseMap<Value *, unsigned> &getValue2Index(bool Signed) {
258     return Signed ? SignedCS.getValue2Index() : UnsignedCS.getValue2Index();
259   }
260   const DenseMap<Value *, unsigned> &getValue2Index(bool Signed) const {
261     return Signed ? SignedCS.getValue2Index() : UnsignedCS.getValue2Index();
262   }
263 
264   ConstraintSystem &getCS(bool Signed) {
265     return Signed ? SignedCS : UnsignedCS;
266   }
267   const ConstraintSystem &getCS(bool Signed) const {
268     return Signed ? SignedCS : UnsignedCS;
269   }
270 
271   void popLastConstraint(bool Signed) { getCS(Signed).popLastConstraint(); }
272   void popLastNVariables(bool Signed, unsigned N) {
273     getCS(Signed).popLastNVariables(N);
274   }
275 
276   bool doesHold(CmpInst::Predicate Pred, Value *A, Value *B) const;
277 
278   void addFact(CmpInst::Predicate Pred, Value *A, Value *B, unsigned NumIn,
279                unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack);
280 
281   /// Turn a comparison of the form \p Op0 \p Pred \p Op1 into a vector of
282   /// constraints, using indices from the corresponding constraint system.
283   /// New variables that need to be added to the system are collected in
284   /// \p NewVariables.
285   ConstraintTy getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
286                              SmallVectorImpl<Value *> &NewVariables) const;
287 
288   /// Turns a comparison of the form \p Op0 \p Pred \p Op1 into a vector of
289   /// constraints using getConstraint. Returns an empty constraint if the result
290   /// cannot be used to query the existing constraint system, e.g. because it
291   /// would require adding new variables. Also tries to convert signed
292   /// predicates to unsigned ones if possible to allow using the unsigned system
293   /// which increases the effectiveness of the signed <-> unsigned transfer
294   /// logic.
295   ConstraintTy getConstraintForSolving(CmpInst::Predicate Pred, Value *Op0,
296                                        Value *Op1) const;
297 
298   /// Try to add information from \p A \p Pred \p B to the unsigned/signed
299   /// system if \p Pred is signed/unsigned.
300   void transferToOtherSystem(CmpInst::Predicate Pred, Value *A, Value *B,
301                              unsigned NumIn, unsigned NumOut,
302                              SmallVectorImpl<StackEntry> &DFSInStack);
303 };
304 
305 /// Represents a (Coefficient * Variable) entry after IR decomposition.
306 struct DecompEntry {
307   int64_t Coefficient;
308   Value *Variable;
309   /// True if the variable is known positive in the current constraint.
310   bool IsKnownNonNegative;
311 
312   DecompEntry(int64_t Coefficient, Value *Variable,
313               bool IsKnownNonNegative = false)
314       : Coefficient(Coefficient), Variable(Variable),
315         IsKnownNonNegative(IsKnownNonNegative) {}
316 };
317 
318 /// Represents an Offset + Coefficient1 * Variable1 + ... decomposition.
319 struct Decomposition {
320   int64_t Offset = 0;
321   SmallVector<DecompEntry, 3> Vars;
322 
323   Decomposition(int64_t Offset) : Offset(Offset) {}
324   Decomposition(Value *V, bool IsKnownNonNegative = false) {
325     Vars.emplace_back(1, V, IsKnownNonNegative);
326   }
327   Decomposition(int64_t Offset, ArrayRef<DecompEntry> Vars)
328       : Offset(Offset), Vars(Vars) {}
329 
330   void add(int64_t OtherOffset) {
331     Offset = addWithOverflow(Offset, OtherOffset);
332   }
333 
334   void add(const Decomposition &Other) {
335     add(Other.Offset);
336     append_range(Vars, Other.Vars);
337   }
338 
339   void mul(int64_t Factor) {
340     Offset = multiplyWithOverflow(Offset, Factor);
341     for (auto &Var : Vars)
342       Var.Coefficient = multiplyWithOverflow(Var.Coefficient, Factor);
343   }
344 };
345 
346 } // namespace
347 
348 static Decomposition decompose(Value *V,
349                                SmallVectorImpl<PreconditionTy> &Preconditions,
350                                bool IsSigned, const DataLayout &DL);
351 
352 static bool canUseSExt(ConstantInt *CI) {
353   const APInt &Val = CI->getValue();
354   return Val.sgt(MinSignedConstraintValue) && Val.slt(MaxConstraintValue);
355 }
356 
357 static Decomposition
358 decomposeGEP(GEPOperator &GEP, SmallVectorImpl<PreconditionTy> &Preconditions,
359              bool IsSigned, const DataLayout &DL) {
360   // Do not reason about pointers where the index size is larger than 64 bits,
361   // as the coefficients used to encode constraints are 64 bit integers.
362   if (DL.getIndexTypeSizeInBits(GEP.getPointerOperand()->getType()) > 64)
363     return &GEP;
364 
365   if (!GEP.isInBounds())
366     return &GEP;
367 
368   assert(!IsSigned && "The logic below only supports decomposition for "
369                       "unsinged predicates at the moment.");
370   Type *PtrTy = GEP.getType()->getScalarType();
371   unsigned BitWidth = DL.getIndexTypeSizeInBits(PtrTy);
372   MapVector<Value *, APInt> VariableOffsets;
373   APInt ConstantOffset(BitWidth, 0);
374   if (!GEP.collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset))
375     return &GEP;
376 
377   // Handle the (gep (gep ....), C) case by incrementing the constant
378   // coefficient of the inner GEP, if C is a constant.
379   auto *InnerGEP = dyn_cast<GEPOperator>(GEP.getPointerOperand());
380   if (VariableOffsets.empty() && InnerGEP && InnerGEP->getNumOperands() == 2) {
381     auto Result = decompose(InnerGEP, Preconditions, IsSigned, DL);
382     Result.add(ConstantOffset.getSExtValue());
383 
384     if (ConstantOffset.isNegative()) {
385       unsigned Scale = DL.getTypeAllocSize(InnerGEP->getResultElementType());
386       int64_t ConstantOffsetI = ConstantOffset.getSExtValue();
387       if (ConstantOffsetI % Scale != 0)
388         return &GEP;
389       // Add pre-condition ensuring the GEP is increasing monotonically and
390       // can be de-composed.
391       // Both sides are normalized by being divided by Scale.
392       Preconditions.emplace_back(
393           CmpInst::ICMP_SGE, InnerGEP->getOperand(1),
394           ConstantInt::get(InnerGEP->getOperand(1)->getType(),
395                            -1 * (ConstantOffsetI / Scale)));
396     }
397     return Result;
398   }
399 
400   Decomposition Result(ConstantOffset.getSExtValue(),
401                        DecompEntry(1, GEP.getPointerOperand()));
402   for (auto [Index, Scale] : VariableOffsets) {
403     auto IdxResult = decompose(Index, Preconditions, IsSigned, DL);
404     IdxResult.mul(Scale.getSExtValue());
405     Result.add(IdxResult);
406 
407     // If Op0 is signed non-negative, the GEP is increasing monotonically and
408     // can be de-composed.
409     if (!isKnownNonNegative(Index, DL, /*Depth=*/MaxAnalysisRecursionDepth - 1))
410       Preconditions.emplace_back(CmpInst::ICMP_SGE, Index,
411                                  ConstantInt::get(Index->getType(), 0));
412   }
413   return Result;
414 }
415 
416 // Decomposes \p V into a constant offset + list of pairs { Coefficient,
417 // Variable } where Coefficient * Variable. The sum of the constant offset and
418 // pairs equals \p V.
419 static Decomposition decompose(Value *V,
420                                SmallVectorImpl<PreconditionTy> &Preconditions,
421                                bool IsSigned, const DataLayout &DL) {
422 
423   auto MergeResults = [&Preconditions, IsSigned, &DL](Value *A, Value *B,
424                                                       bool IsSignedB) {
425     auto ResA = decompose(A, Preconditions, IsSigned, DL);
426     auto ResB = decompose(B, Preconditions, IsSignedB, DL);
427     ResA.add(ResB);
428     return ResA;
429   };
430 
431   // Decompose \p V used with a signed predicate.
432   if (IsSigned) {
433     if (auto *CI = dyn_cast<ConstantInt>(V)) {
434       if (canUseSExt(CI))
435         return CI->getSExtValue();
436     }
437     Value *Op0;
438     Value *Op1;
439     if (match(V, m_NSWAdd(m_Value(Op0), m_Value(Op1))))
440       return MergeResults(Op0, Op1, IsSigned);
441 
442     ConstantInt *CI;
443     if (match(V, m_NSWMul(m_Value(Op0), m_ConstantInt(CI))) && canUseSExt(CI)) {
444       auto Result = decompose(Op0, Preconditions, IsSigned, DL);
445       Result.mul(CI->getSExtValue());
446       return Result;
447     }
448 
449     return V;
450   }
451 
452   if (auto *CI = dyn_cast<ConstantInt>(V)) {
453     if (CI->uge(MaxConstraintValue))
454       return V;
455     return int64_t(CI->getZExtValue());
456   }
457 
458   if (auto *GEP = dyn_cast<GEPOperator>(V))
459     return decomposeGEP(*GEP, Preconditions, IsSigned, DL);
460 
461   Value *Op0;
462   bool IsKnownNonNegative = false;
463   if (match(V, m_ZExt(m_Value(Op0)))) {
464     IsKnownNonNegative = true;
465     V = Op0;
466   }
467 
468   Value *Op1;
469   ConstantInt *CI;
470   if (match(V, m_NUWAdd(m_Value(Op0), m_Value(Op1)))) {
471     return MergeResults(Op0, Op1, IsSigned);
472   }
473   if (match(V, m_NSWAdd(m_Value(Op0), m_Value(Op1)))) {
474     if (!isKnownNonNegative(Op0, DL, /*Depth=*/MaxAnalysisRecursionDepth - 1))
475       Preconditions.emplace_back(CmpInst::ICMP_SGE, Op0,
476                                  ConstantInt::get(Op0->getType(), 0));
477     if (!isKnownNonNegative(Op1, DL, /*Depth=*/MaxAnalysisRecursionDepth - 1))
478       Preconditions.emplace_back(CmpInst::ICMP_SGE, Op1,
479                                  ConstantInt::get(Op1->getType(), 0));
480 
481     return MergeResults(Op0, Op1, IsSigned);
482   }
483 
484   if (match(V, m_Add(m_Value(Op0), m_ConstantInt(CI))) && CI->isNegative() &&
485       canUseSExt(CI)) {
486     Preconditions.emplace_back(
487         CmpInst::ICMP_UGE, Op0,
488         ConstantInt::get(Op0->getType(), CI->getSExtValue() * -1));
489     return MergeResults(Op0, CI, true);
490   }
491 
492   // Decompose or as an add if there are no common bits between the operands.
493   if (match(V, m_Or(m_Value(Op0), m_ConstantInt(CI))) &&
494       haveNoCommonBitsSet(Op0, CI, DL)) {
495     return MergeResults(Op0, CI, IsSigned);
496   }
497 
498   if (match(V, m_NUWShl(m_Value(Op1), m_ConstantInt(CI))) && canUseSExt(CI)) {
499     if (CI->getSExtValue() < 0 || CI->getSExtValue() >= 64)
500       return {V, IsKnownNonNegative};
501     auto Result = decompose(Op1, Preconditions, IsSigned, DL);
502     Result.mul(int64_t{1} << CI->getSExtValue());
503     return Result;
504   }
505 
506   if (match(V, m_NUWMul(m_Value(Op1), m_ConstantInt(CI))) && canUseSExt(CI) &&
507       (!CI->isNegative())) {
508     auto Result = decompose(Op1, Preconditions, IsSigned, DL);
509     Result.mul(CI->getSExtValue());
510     return Result;
511   }
512 
513   if (match(V, m_NUWSub(m_Value(Op0), m_ConstantInt(CI))) && canUseSExt(CI))
514     return {-1 * CI->getSExtValue(), {{1, Op0}}};
515   if (match(V, m_NUWSub(m_Value(Op0), m_Value(Op1))))
516     return {0, {{1, Op0}, {-1, Op1}}};
517 
518   return {V, IsKnownNonNegative};
519 }
520 
521 ConstraintTy
522 ConstraintInfo::getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
523                               SmallVectorImpl<Value *> &NewVariables) const {
524   assert(NewVariables.empty() && "NewVariables must be empty when passed in");
525   bool IsEq = false;
526   bool IsNe = false;
527 
528   // Try to convert Pred to one of ULE/SLT/SLE/SLT.
529   switch (Pred) {
530   case CmpInst::ICMP_UGT:
531   case CmpInst::ICMP_UGE:
532   case CmpInst::ICMP_SGT:
533   case CmpInst::ICMP_SGE: {
534     Pred = CmpInst::getSwappedPredicate(Pred);
535     std::swap(Op0, Op1);
536     break;
537   }
538   case CmpInst::ICMP_EQ:
539     if (match(Op1, m_Zero())) {
540       Pred = CmpInst::ICMP_ULE;
541     } else {
542       IsEq = true;
543       Pred = CmpInst::ICMP_ULE;
544     }
545     break;
546   case CmpInst::ICMP_NE:
547     if (match(Op1, m_Zero())) {
548       Pred = CmpInst::getSwappedPredicate(CmpInst::ICMP_UGT);
549       std::swap(Op0, Op1);
550     } else {
551       IsNe = true;
552       Pred = CmpInst::ICMP_ULE;
553     }
554     break;
555   default:
556     break;
557   }
558 
559   if (Pred != CmpInst::ICMP_ULE && Pred != CmpInst::ICMP_ULT &&
560       Pred != CmpInst::ICMP_SLE && Pred != CmpInst::ICMP_SLT)
561     return {};
562 
563   SmallVector<PreconditionTy, 4> Preconditions;
564   bool IsSigned = CmpInst::isSigned(Pred);
565   auto &Value2Index = getValue2Index(IsSigned);
566   auto ADec = decompose(Op0->stripPointerCastsSameRepresentation(),
567                         Preconditions, IsSigned, DL);
568   auto BDec = decompose(Op1->stripPointerCastsSameRepresentation(),
569                         Preconditions, IsSigned, DL);
570   int64_t Offset1 = ADec.Offset;
571   int64_t Offset2 = BDec.Offset;
572   Offset1 *= -1;
573 
574   auto &VariablesA = ADec.Vars;
575   auto &VariablesB = BDec.Vars;
576 
577   // First try to look up \p V in Value2Index and NewVariables. Otherwise add a
578   // new entry to NewVariables.
579   DenseMap<Value *, unsigned> NewIndexMap;
580   auto GetOrAddIndex = [&Value2Index, &NewVariables,
581                         &NewIndexMap](Value *V) -> unsigned {
582     auto V2I = Value2Index.find(V);
583     if (V2I != Value2Index.end())
584       return V2I->second;
585     auto Insert =
586         NewIndexMap.insert({V, Value2Index.size() + NewVariables.size() + 1});
587     if (Insert.second)
588       NewVariables.push_back(V);
589     return Insert.first->second;
590   };
591 
592   // Make sure all variables have entries in Value2Index or NewVariables.
593   for (const auto &KV : concat<DecompEntry>(VariablesA, VariablesB))
594     GetOrAddIndex(KV.Variable);
595 
596   // Build result constraint, by first adding all coefficients from A and then
597   // subtracting all coefficients from B.
598   ConstraintTy Res(
599       SmallVector<int64_t, 8>(Value2Index.size() + NewVariables.size() + 1, 0),
600       IsSigned, IsEq, IsNe);
601   // Collect variables that are known to be positive in all uses in the
602   // constraint.
603   DenseMap<Value *, bool> KnownNonNegativeVariables;
604   auto &R = Res.Coefficients;
605   for (const auto &KV : VariablesA) {
606     R[GetOrAddIndex(KV.Variable)] += KV.Coefficient;
607     auto I =
608         KnownNonNegativeVariables.insert({KV.Variable, KV.IsKnownNonNegative});
609     I.first->second &= KV.IsKnownNonNegative;
610   }
611 
612   for (const auto &KV : VariablesB) {
613     if (SubOverflow(R[GetOrAddIndex(KV.Variable)], KV.Coefficient,
614                     R[GetOrAddIndex(KV.Variable)]))
615       return {};
616     auto I =
617         KnownNonNegativeVariables.insert({KV.Variable, KV.IsKnownNonNegative});
618     I.first->second &= KV.IsKnownNonNegative;
619   }
620 
621   int64_t OffsetSum;
622   if (AddOverflow(Offset1, Offset2, OffsetSum))
623     return {};
624   if (Pred == (IsSigned ? CmpInst::ICMP_SLT : CmpInst::ICMP_ULT))
625     if (AddOverflow(OffsetSum, int64_t(-1), OffsetSum))
626       return {};
627   R[0] = OffsetSum;
628   Res.Preconditions = std::move(Preconditions);
629 
630   // Remove any (Coefficient, Variable) entry where the Coefficient is 0 for new
631   // variables.
632   while (!NewVariables.empty()) {
633     int64_t Last = R.back();
634     if (Last != 0)
635       break;
636     R.pop_back();
637     Value *RemovedV = NewVariables.pop_back_val();
638     NewIndexMap.erase(RemovedV);
639   }
640 
641   // Add extra constraints for variables that are known positive.
642   for (auto &KV : KnownNonNegativeVariables) {
643     if (!KV.second ||
644         (!Value2Index.contains(KV.first) && !NewIndexMap.contains(KV.first)))
645       continue;
646     SmallVector<int64_t, 8> C(Value2Index.size() + NewVariables.size() + 1, 0);
647     C[GetOrAddIndex(KV.first)] = -1;
648     Res.ExtraInfo.push_back(C);
649   }
650   return Res;
651 }
652 
653 ConstraintTy ConstraintInfo::getConstraintForSolving(CmpInst::Predicate Pred,
654                                                      Value *Op0,
655                                                      Value *Op1) const {
656   // If both operands are known to be non-negative, change signed predicates to
657   // unsigned ones. This increases the reasoning effectiveness in combination
658   // with the signed <-> unsigned transfer logic.
659   if (CmpInst::isSigned(Pred) &&
660       isKnownNonNegative(Op0, DL, /*Depth=*/MaxAnalysisRecursionDepth - 1) &&
661       isKnownNonNegative(Op1, DL, /*Depth=*/MaxAnalysisRecursionDepth - 1))
662     Pred = CmpInst::getUnsignedPredicate(Pred);
663 
664   SmallVector<Value *> NewVariables;
665   ConstraintTy R = getConstraint(Pred, Op0, Op1, NewVariables);
666   if (!NewVariables.empty())
667     return {};
668   return R;
669 }
670 
671 bool ConstraintTy::isValid(const ConstraintInfo &Info) const {
672   return Coefficients.size() > 0 &&
673          all_of(Preconditions, [&Info](const PreconditionTy &C) {
674            return Info.doesHold(C.Pred, C.Op0, C.Op1);
675          });
676 }
677 
678 std::optional<bool>
679 ConstraintTy::isImpliedBy(const ConstraintSystem &CS) const {
680   bool IsConditionImplied = CS.isConditionImplied(Coefficients);
681 
682   if (IsEq || IsNe) {
683     auto NegatedOrEqual = ConstraintSystem::negateOrEqual(Coefficients);
684     bool IsNegatedOrEqualImplied =
685         !NegatedOrEqual.empty() && CS.isConditionImplied(NegatedOrEqual);
686 
687     // In order to check that `%a == %b` is true (equality), both conditions `%a
688     // >= %b` and `%a <= %b` must hold true. When checking for equality (`IsEq`
689     // is true), we return true if they both hold, false in the other cases.
690     if (IsConditionImplied && IsNegatedOrEqualImplied)
691       return IsEq;
692 
693     auto Negated = ConstraintSystem::negate(Coefficients);
694     bool IsNegatedImplied = !Negated.empty() && CS.isConditionImplied(Negated);
695 
696     auto StrictLessThan = ConstraintSystem::toStrictLessThan(Coefficients);
697     bool IsStrictLessThanImplied =
698         !StrictLessThan.empty() && CS.isConditionImplied(StrictLessThan);
699 
700     // In order to check that `%a != %b` is true (non-equality), either
701     // condition `%a > %b` or `%a < %b` must hold true. When checking for
702     // non-equality (`IsNe` is true), we return true if one of the two holds,
703     // false in the other cases.
704     if (IsNegatedImplied || IsStrictLessThanImplied)
705       return IsNe;
706 
707     return std::nullopt;
708   }
709 
710   if (IsConditionImplied)
711     return true;
712 
713   auto Negated = ConstraintSystem::negate(Coefficients);
714   auto IsNegatedImplied = !Negated.empty() && CS.isConditionImplied(Negated);
715   if (IsNegatedImplied)
716     return false;
717 
718   // Neither the condition nor its negated holds, did not prove anything.
719   return std::nullopt;
720 }
721 
722 bool ConstraintInfo::doesHold(CmpInst::Predicate Pred, Value *A,
723                               Value *B) const {
724   auto R = getConstraintForSolving(Pred, A, B);
725   return R.isValid(*this) &&
726          getCS(R.IsSigned).isConditionImplied(R.Coefficients);
727 }
728 
729 void ConstraintInfo::transferToOtherSystem(
730     CmpInst::Predicate Pred, Value *A, Value *B, unsigned NumIn,
731     unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack) {
732   // Check if we can combine facts from the signed and unsigned systems to
733   // derive additional facts.
734   if (!A->getType()->isIntegerTy())
735     return;
736   // FIXME: This currently depends on the order we add facts. Ideally we
737   // would first add all known facts and only then try to add additional
738   // facts.
739   switch (Pred) {
740   default:
741     break;
742   case CmpInst::ICMP_ULT:
743     //  If B is a signed positive constant, A >=s 0 and A <s B.
744     if (doesHold(CmpInst::ICMP_SGE, B, ConstantInt::get(B->getType(), 0))) {
745       addFact(CmpInst::ICMP_SGE, A, ConstantInt::get(B->getType(), 0), NumIn,
746               NumOut, DFSInStack);
747       addFact(CmpInst::ICMP_SLT, A, B, NumIn, NumOut, DFSInStack);
748     }
749     break;
750   case CmpInst::ICMP_SLT:
751     if (doesHold(CmpInst::ICMP_SGE, A, ConstantInt::get(B->getType(), 0)))
752       addFact(CmpInst::ICMP_ULT, A, B, NumIn, NumOut, DFSInStack);
753     break;
754   case CmpInst::ICMP_SGT: {
755     if (doesHold(CmpInst::ICMP_SGE, B, ConstantInt::get(B->getType(), -1)))
756       addFact(CmpInst::ICMP_UGE, A, ConstantInt::get(B->getType(), 0), NumIn,
757               NumOut, DFSInStack);
758     if (doesHold(CmpInst::ICMP_SGE, B, ConstantInt::get(B->getType(), 0)))
759       addFact(CmpInst::ICMP_UGT, A, B, NumIn, NumOut, DFSInStack);
760 
761     break;
762   }
763   case CmpInst::ICMP_SGE:
764     if (doesHold(CmpInst::ICMP_SGE, B, ConstantInt::get(B->getType(), 0))) {
765       addFact(CmpInst::ICMP_UGE, A, B, NumIn, NumOut, DFSInStack);
766     }
767     break;
768   }
769 }
770 
771 #ifndef NDEBUG
772 
773 static void dumpConstraint(ArrayRef<int64_t> C,
774                            const DenseMap<Value *, unsigned> &Value2Index) {
775   ConstraintSystem CS(Value2Index);
776   CS.addVariableRowFill(C);
777   CS.dump();
778 }
779 #endif
780 
781 void State::addInfoFor(BasicBlock &BB) {
782   // True as long as long as the current instruction is guaranteed to execute.
783   bool GuaranteedToExecute = true;
784   // Queue conditions and assumes.
785   for (Instruction &I : BB) {
786     if (auto Cmp = dyn_cast<ICmpInst>(&I)) {
787       for (Use &U : Cmp->uses()) {
788         auto *UserI = getContextInstForUse(U);
789         auto *DTN = DT.getNode(UserI->getParent());
790         if (!DTN)
791           continue;
792         WorkList.push_back(FactOrCheck::getCheck(DTN, &U));
793       }
794       continue;
795     }
796 
797     if (match(&I, m_Intrinsic<Intrinsic::ssub_with_overflow>())) {
798       WorkList.push_back(
799           FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
800       continue;
801     }
802 
803     if (isa<MinMaxIntrinsic>(&I)) {
804       WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I));
805       continue;
806     }
807 
808     Value *Cond;
809     // For now, just handle assumes with a single compare as condition.
810     if (match(&I, m_Intrinsic<Intrinsic::assume>(m_Value(Cond))) &&
811         isa<ICmpInst>(Cond)) {
812       if (GuaranteedToExecute) {
813         // The assume is guaranteed to execute when BB is entered, hence Cond
814         // holds on entry to BB.
815         WorkList.emplace_back(FactOrCheck::getConditionFact(
816             DT.getNode(I.getParent()), cast<CmpInst>(Cond)));
817       } else {
818         WorkList.emplace_back(
819             FactOrCheck::getInstFact(DT.getNode(I.getParent()), &I));
820       }
821     }
822     GuaranteedToExecute &= isGuaranteedToTransferExecutionToSuccessor(&I);
823   }
824 
825   auto *Br = dyn_cast<BranchInst>(BB.getTerminator());
826   if (!Br || !Br->isConditional())
827     return;
828 
829   Value *Cond = Br->getCondition();
830 
831   // If the condition is a chain of ORs/AND and the successor only has the
832   // current block as predecessor, queue conditions for the successor.
833   Value *Op0, *Op1;
834   if (match(Cond, m_LogicalOr(m_Value(Op0), m_Value(Op1))) ||
835       match(Cond, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) {
836     bool IsOr = match(Cond, m_LogicalOr());
837     bool IsAnd = match(Cond, m_LogicalAnd());
838     // If there's a select that matches both AND and OR, we need to commit to
839     // one of the options. Arbitrarily pick OR.
840     if (IsOr && IsAnd)
841       IsAnd = false;
842 
843     BasicBlock *Successor = Br->getSuccessor(IsOr ? 1 : 0);
844     if (canAddSuccessor(BB, Successor)) {
845       SmallVector<Value *> CondWorkList;
846       SmallPtrSet<Value *, 8> SeenCond;
847       auto QueueValue = [&CondWorkList, &SeenCond](Value *V) {
848         if (SeenCond.insert(V).second)
849           CondWorkList.push_back(V);
850       };
851       QueueValue(Op1);
852       QueueValue(Op0);
853       while (!CondWorkList.empty()) {
854         Value *Cur = CondWorkList.pop_back_val();
855         if (auto *Cmp = dyn_cast<ICmpInst>(Cur)) {
856           WorkList.emplace_back(
857               FactOrCheck::getConditionFact(DT.getNode(Successor), Cmp, IsOr));
858           continue;
859         }
860         if (IsOr && match(Cur, m_LogicalOr(m_Value(Op0), m_Value(Op1)))) {
861           QueueValue(Op1);
862           QueueValue(Op0);
863           continue;
864         }
865         if (IsAnd && match(Cur, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) {
866           QueueValue(Op1);
867           QueueValue(Op0);
868           continue;
869         }
870       }
871     }
872     return;
873   }
874 
875   auto *CmpI = dyn_cast<ICmpInst>(Br->getCondition());
876   if (!CmpI)
877     return;
878   if (canAddSuccessor(BB, Br->getSuccessor(0)))
879     WorkList.emplace_back(
880         FactOrCheck::getConditionFact(DT.getNode(Br->getSuccessor(0)), CmpI));
881   if (canAddSuccessor(BB, Br->getSuccessor(1)))
882     WorkList.emplace_back(FactOrCheck::getConditionFact(
883         DT.getNode(Br->getSuccessor(1)), CmpI, true));
884 }
885 
886 namespace {
887 /// Helper to keep track of a condition and if it should be treated as negated
888 /// for reproducer construction.
889 /// Pred == Predicate::BAD_ICMP_PREDICATE indicates that this entry is a
890 /// placeholder to keep the ReproducerCondStack in sync with DFSInStack.
891 struct ReproducerEntry {
892   ICmpInst::Predicate Pred;
893   Value *LHS;
894   Value *RHS;
895 
896   ReproducerEntry(ICmpInst::Predicate Pred, Value *LHS, Value *RHS)
897       : Pred(Pred), LHS(LHS), RHS(RHS) {}
898 };
899 } // namespace
900 
901 /// Helper function to generate a reproducer function for simplifying \p Cond.
902 /// The reproducer function contains a series of @llvm.assume calls, one for
903 /// each condition in \p Stack. For each condition, the operand instruction are
904 /// cloned until we reach operands that have an entry in \p Value2Index. Those
905 /// will then be added as function arguments. \p DT is used to order cloned
906 /// instructions. The reproducer function will get added to \p M, if it is
907 /// non-null. Otherwise no reproducer function is generated.
908 static void generateReproducer(CmpInst *Cond, Module *M,
909                                ArrayRef<ReproducerEntry> Stack,
910                                ConstraintInfo &Info, DominatorTree &DT) {
911   if (!M)
912     return;
913 
914   LLVMContext &Ctx = Cond->getContext();
915 
916   LLVM_DEBUG(dbgs() << "Creating reproducer for " << *Cond << "\n");
917 
918   ValueToValueMapTy Old2New;
919   SmallVector<Value *> Args;
920   SmallPtrSet<Value *, 8> Seen;
921   // Traverse Cond and its operands recursively until we reach a value that's in
922   // Value2Index or not an instruction, or not a operation that
923   // ConstraintElimination can decompose. Such values will be considered as
924   // external inputs to the reproducer, they are collected and added as function
925   // arguments later.
926   auto CollectArguments = [&](ArrayRef<Value *> Ops, bool IsSigned) {
927     auto &Value2Index = Info.getValue2Index(IsSigned);
928     SmallVector<Value *, 4> WorkList(Ops);
929     while (!WorkList.empty()) {
930       Value *V = WorkList.pop_back_val();
931       if (!Seen.insert(V).second)
932         continue;
933       if (Old2New.find(V) != Old2New.end())
934         continue;
935       if (isa<Constant>(V))
936         continue;
937 
938       auto *I = dyn_cast<Instruction>(V);
939       if (Value2Index.contains(V) || !I ||
940           !isa<CmpInst, BinaryOperator, GEPOperator, CastInst>(V)) {
941         Old2New[V] = V;
942         Args.push_back(V);
943         LLVM_DEBUG(dbgs() << "  found external input " << *V << "\n");
944       } else {
945         append_range(WorkList, I->operands());
946       }
947     }
948   };
949 
950   for (auto &Entry : Stack)
951     if (Entry.Pred != ICmpInst::BAD_ICMP_PREDICATE)
952       CollectArguments({Entry.LHS, Entry.RHS}, ICmpInst::isSigned(Entry.Pred));
953   CollectArguments(Cond, ICmpInst::isSigned(Cond->getPredicate()));
954 
955   SmallVector<Type *> ParamTys;
956   for (auto *P : Args)
957     ParamTys.push_back(P->getType());
958 
959   FunctionType *FTy = FunctionType::get(Cond->getType(), ParamTys,
960                                         /*isVarArg=*/false);
961   Function *F = Function::Create(FTy, Function::ExternalLinkage,
962                                  Cond->getModule()->getName() +
963                                      Cond->getFunction()->getName() + "repro",
964                                  M);
965   // Add arguments to the reproducer function for each external value collected.
966   for (unsigned I = 0; I < Args.size(); ++I) {
967     F->getArg(I)->setName(Args[I]->getName());
968     Old2New[Args[I]] = F->getArg(I);
969   }
970 
971   BasicBlock *Entry = BasicBlock::Create(Ctx, "entry", F);
972   IRBuilder<> Builder(Entry);
973   Builder.CreateRet(Builder.getTrue());
974   Builder.SetInsertPoint(Entry->getTerminator());
975 
976   // Clone instructions in \p Ops and their operands recursively until reaching
977   // an value in Value2Index (external input to the reproducer). Update Old2New
978   // mapping for the original and cloned instructions. Sort instructions to
979   // clone by dominance, then insert the cloned instructions in the function.
980   auto CloneInstructions = [&](ArrayRef<Value *> Ops, bool IsSigned) {
981     SmallVector<Value *, 4> WorkList(Ops);
982     SmallVector<Instruction *> ToClone;
983     auto &Value2Index = Info.getValue2Index(IsSigned);
984     while (!WorkList.empty()) {
985       Value *V = WorkList.pop_back_val();
986       if (Old2New.find(V) != Old2New.end())
987         continue;
988 
989       auto *I = dyn_cast<Instruction>(V);
990       if (!Value2Index.contains(V) && I) {
991         Old2New[V] = nullptr;
992         ToClone.push_back(I);
993         append_range(WorkList, I->operands());
994       }
995     }
996 
997     sort(ToClone,
998          [&DT](Instruction *A, Instruction *B) { return DT.dominates(A, B); });
999     for (Instruction *I : ToClone) {
1000       Instruction *Cloned = I->clone();
1001       Old2New[I] = Cloned;
1002       Old2New[I]->setName(I->getName());
1003       Cloned->insertBefore(&*Builder.GetInsertPoint());
1004       Cloned->dropUnknownNonDebugMetadata();
1005       Cloned->setDebugLoc({});
1006     }
1007   };
1008 
1009   // Materialize the assumptions for the reproducer using the entries in Stack.
1010   // That is, first clone the operands of the condition recursively until we
1011   // reach an external input to the reproducer and add them to the reproducer
1012   // function. Then add an ICmp for the condition (with the inverse predicate if
1013   // the entry is negated) and an assert using the ICmp.
1014   for (auto &Entry : Stack) {
1015     if (Entry.Pred == ICmpInst::BAD_ICMP_PREDICATE)
1016       continue;
1017 
1018     LLVM_DEBUG(
1019         dbgs() << "  Materializing assumption icmp " << Entry.Pred << ' ';
1020         Entry.LHS->printAsOperand(dbgs(), /*PrintType=*/true); dbgs() << ", ";
1021         Entry.RHS->printAsOperand(dbgs(), /*PrintType=*/false); dbgs() << "\n");
1022     CloneInstructions({Entry.LHS, Entry.RHS}, CmpInst::isSigned(Entry.Pred));
1023 
1024     auto *Cmp = Builder.CreateICmp(Entry.Pred, Entry.LHS, Entry.RHS);
1025     Builder.CreateAssumption(Cmp);
1026   }
1027 
1028   // Finally, clone the condition to reproduce and remap instruction operands in
1029   // the reproducer using Old2New.
1030   CloneInstructions(Cond, CmpInst::isSigned(Cond->getPredicate()));
1031   Entry->getTerminator()->setOperand(0, Cond);
1032   remapInstructionsInBlocks({Entry}, Old2New);
1033 
1034   assert(!verifyFunction(*F, &dbgs()));
1035 }
1036 
1037 static std::optional<bool> checkCondition(CmpInst *Cmp, ConstraintInfo &Info,
1038                                           unsigned NumIn, unsigned NumOut,
1039                                           Instruction *ContextInst) {
1040   LLVM_DEBUG(dbgs() << "Checking " << *Cmp << "\n");
1041 
1042   CmpInst::Predicate Pred = Cmp->getPredicate();
1043   Value *A = Cmp->getOperand(0);
1044   Value *B = Cmp->getOperand(1);
1045 
1046   auto R = Info.getConstraintForSolving(Pred, A, B);
1047   if (R.empty() || !R.isValid(Info)){
1048     LLVM_DEBUG(dbgs() << "   failed to decompose condition\n");
1049     return std::nullopt;
1050   }
1051 
1052   auto &CSToUse = Info.getCS(R.IsSigned);
1053 
1054   // If there was extra information collected during decomposition, apply
1055   // it now and remove it immediately once we are done with reasoning
1056   // about the constraint.
1057   for (auto &Row : R.ExtraInfo)
1058     CSToUse.addVariableRow(Row);
1059   auto InfoRestorer = make_scope_exit([&]() {
1060     for (unsigned I = 0; I < R.ExtraInfo.size(); ++I)
1061       CSToUse.popLastConstraint();
1062   });
1063 
1064   if (auto ImpliedCondition = R.isImpliedBy(CSToUse)) {
1065     if (!DebugCounter::shouldExecute(EliminatedCounter))
1066       return std::nullopt;
1067 
1068     LLVM_DEBUG({
1069       if (*ImpliedCondition) {
1070         dbgs() << "Condition " << *Cmp;
1071       } else {
1072         auto InversePred = Cmp->getInversePredicate();
1073         dbgs() << "Condition " << CmpInst::getPredicateName(InversePred) << " "
1074                << *A << ", " << *B;
1075       }
1076       dbgs() << " implied by dominating constraints\n";
1077       CSToUse.dump();
1078     });
1079     return ImpliedCondition;
1080   }
1081 
1082   return std::nullopt;
1083 }
1084 
1085 static bool checkAndReplaceCondition(
1086     CmpInst *Cmp, ConstraintInfo &Info, unsigned NumIn, unsigned NumOut,
1087     Instruction *ContextInst, Module *ReproducerModule,
1088     ArrayRef<ReproducerEntry> ReproducerCondStack, DominatorTree &DT,
1089     SmallVectorImpl<Instruction *> &ToRemove) {
1090   auto ReplaceCmpWithConstant = [&](CmpInst *Cmp, bool IsTrue) {
1091     generateReproducer(Cmp, ReproducerModule, ReproducerCondStack, Info, DT);
1092     Constant *ConstantC = ConstantInt::getBool(
1093         CmpInst::makeCmpResultType(Cmp->getType()), IsTrue);
1094     Cmp->replaceUsesWithIf(ConstantC, [&DT, NumIn, NumOut,
1095                                        ContextInst](Use &U) {
1096       auto *UserI = getContextInstForUse(U);
1097       auto *DTN = DT.getNode(UserI->getParent());
1098       if (!DTN || DTN->getDFSNumIn() < NumIn || DTN->getDFSNumOut() > NumOut)
1099         return false;
1100       if (UserI->getParent() == ContextInst->getParent() &&
1101           UserI->comesBefore(ContextInst))
1102         return false;
1103 
1104       // Conditions in an assume trivially simplify to true. Skip uses
1105       // in assume calls to not destroy the available information.
1106       auto *II = dyn_cast<IntrinsicInst>(U.getUser());
1107       return !II || II->getIntrinsicID() != Intrinsic::assume;
1108     });
1109     NumCondsRemoved++;
1110     if (Cmp->use_empty())
1111       ToRemove.push_back(Cmp);
1112     return true;
1113   };
1114 
1115   if (auto ImpliedCondition =
1116           checkCondition(Cmp, Info, NumIn, NumOut, ContextInst))
1117     return ReplaceCmpWithConstant(Cmp, *ImpliedCondition);
1118   return false;
1119 }
1120 
1121 static void
1122 removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info,
1123                      Module *ReproducerModule,
1124                      SmallVectorImpl<ReproducerEntry> &ReproducerCondStack,
1125                      SmallVectorImpl<StackEntry> &DFSInStack) {
1126   Info.popLastConstraint(E.IsSigned);
1127   // Remove variables in the system that went out of scope.
1128   auto &Mapping = Info.getValue2Index(E.IsSigned);
1129   for (Value *V : E.ValuesToRelease)
1130     Mapping.erase(V);
1131   Info.popLastNVariables(E.IsSigned, E.ValuesToRelease.size());
1132   DFSInStack.pop_back();
1133   if (ReproducerModule)
1134     ReproducerCondStack.pop_back();
1135 }
1136 
1137 /// Check if the first condition for an AND implies the second.
1138 static bool checkAndSecondOpImpliedByFirst(
1139     FactOrCheck &CB, ConstraintInfo &Info, Module *ReproducerModule,
1140     SmallVectorImpl<ReproducerEntry> &ReproducerCondStack,
1141     SmallVectorImpl<StackEntry> &DFSInStack) {
1142   CmpInst::Predicate Pred;
1143   Value *A, *B;
1144   Instruction *And = CB.getContextInst();
1145   if (!match(And->getOperand(0), m_ICmp(Pred, m_Value(A), m_Value(B))))
1146     return false;
1147 
1148   // Optimistically add fact from first condition.
1149   unsigned OldSize = DFSInStack.size();
1150   Info.addFact(Pred, A, B, CB.NumIn, CB.NumOut, DFSInStack);
1151   if (OldSize == DFSInStack.size())
1152     return false;
1153 
1154   bool Changed = false;
1155   // Check if the second condition can be simplified now.
1156   if (auto ImpliedCondition =
1157           checkCondition(cast<ICmpInst>(And->getOperand(1)), Info, CB.NumIn,
1158                          CB.NumOut, CB.getContextInst())) {
1159     And->setOperand(1, ConstantInt::getBool(And->getType(), *ImpliedCondition));
1160     Changed = true;
1161   }
1162 
1163   // Remove entries again.
1164   while (OldSize < DFSInStack.size()) {
1165     StackEntry E = DFSInStack.back();
1166     removeEntryFromStack(E, Info, ReproducerModule, ReproducerCondStack,
1167                          DFSInStack);
1168   }
1169   return Changed;
1170 }
1171 
1172 void ConstraintInfo::addFact(CmpInst::Predicate Pred, Value *A, Value *B,
1173                              unsigned NumIn, unsigned NumOut,
1174                              SmallVectorImpl<StackEntry> &DFSInStack) {
1175   // If the constraint has a pre-condition, skip the constraint if it does not
1176   // hold.
1177   SmallVector<Value *> NewVariables;
1178   auto R = getConstraint(Pred, A, B, NewVariables);
1179 
1180   // TODO: Support non-equality for facts as well.
1181   if (!R.isValid(*this) || R.isNe())
1182     return;
1183 
1184   LLVM_DEBUG(dbgs() << "Adding '" << Pred << " ";
1185              A->printAsOperand(dbgs(), false); dbgs() << ", ";
1186              B->printAsOperand(dbgs(), false); dbgs() << "'\n");
1187   bool Added = false;
1188   auto &CSToUse = getCS(R.IsSigned);
1189   if (R.Coefficients.empty())
1190     return;
1191 
1192   Added |= CSToUse.addVariableRowFill(R.Coefficients);
1193 
1194   // If R has been added to the system, add the new variables and queue it for
1195   // removal once it goes out-of-scope.
1196   if (Added) {
1197     SmallVector<Value *, 2> ValuesToRelease;
1198     auto &Value2Index = getValue2Index(R.IsSigned);
1199     for (Value *V : NewVariables) {
1200       Value2Index.insert({V, Value2Index.size() + 1});
1201       ValuesToRelease.push_back(V);
1202     }
1203 
1204     LLVM_DEBUG({
1205       dbgs() << "  constraint: ";
1206       dumpConstraint(R.Coefficients, getValue2Index(R.IsSigned));
1207       dbgs() << "\n";
1208     });
1209 
1210     DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
1211                             std::move(ValuesToRelease));
1212 
1213     if (R.isEq()) {
1214       // Also add the inverted constraint for equality constraints.
1215       for (auto &Coeff : R.Coefficients)
1216         Coeff *= -1;
1217       CSToUse.addVariableRowFill(R.Coefficients);
1218 
1219       DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
1220                               SmallVector<Value *, 2>());
1221     }
1222   }
1223 }
1224 
1225 static bool replaceSubOverflowUses(IntrinsicInst *II, Value *A, Value *B,
1226                                    SmallVectorImpl<Instruction *> &ToRemove) {
1227   bool Changed = false;
1228   IRBuilder<> Builder(II->getParent(), II->getIterator());
1229   Value *Sub = nullptr;
1230   for (User *U : make_early_inc_range(II->users())) {
1231     if (match(U, m_ExtractValue<0>(m_Value()))) {
1232       if (!Sub)
1233         Sub = Builder.CreateSub(A, B);
1234       U->replaceAllUsesWith(Sub);
1235       Changed = true;
1236     } else if (match(U, m_ExtractValue<1>(m_Value()))) {
1237       U->replaceAllUsesWith(Builder.getFalse());
1238       Changed = true;
1239     } else
1240       continue;
1241 
1242     if (U->use_empty()) {
1243       auto *I = cast<Instruction>(U);
1244       ToRemove.push_back(I);
1245       I->setOperand(0, PoisonValue::get(II->getType()));
1246       Changed = true;
1247     }
1248   }
1249 
1250   if (II->use_empty()) {
1251     II->eraseFromParent();
1252     Changed = true;
1253   }
1254   return Changed;
1255 }
1256 
1257 static bool
1258 tryToSimplifyOverflowMath(IntrinsicInst *II, ConstraintInfo &Info,
1259                           SmallVectorImpl<Instruction *> &ToRemove) {
1260   auto DoesConditionHold = [](CmpInst::Predicate Pred, Value *A, Value *B,
1261                               ConstraintInfo &Info) {
1262     auto R = Info.getConstraintForSolving(Pred, A, B);
1263     if (R.size() < 2 || !R.isValid(Info))
1264       return false;
1265 
1266     auto &CSToUse = Info.getCS(R.IsSigned);
1267     return CSToUse.isConditionImplied(R.Coefficients);
1268   };
1269 
1270   bool Changed = false;
1271   if (II->getIntrinsicID() == Intrinsic::ssub_with_overflow) {
1272     // If A s>= B && B s>= 0, ssub.with.overflow(a, b) should not overflow and
1273     // can be simplified to a regular sub.
1274     Value *A = II->getArgOperand(0);
1275     Value *B = II->getArgOperand(1);
1276     if (!DoesConditionHold(CmpInst::ICMP_SGE, A, B, Info) ||
1277         !DoesConditionHold(CmpInst::ICMP_SGE, B,
1278                            ConstantInt::get(A->getType(), 0), Info))
1279       return false;
1280     Changed = replaceSubOverflowUses(II, A, B, ToRemove);
1281   }
1282   return Changed;
1283 }
1284 
1285 static bool eliminateConstraints(Function &F, DominatorTree &DT,
1286                                  OptimizationRemarkEmitter &ORE) {
1287   bool Changed = false;
1288   DT.updateDFSNumbers();
1289   SmallVector<Value *> FunctionArgs;
1290   for (Value &Arg : F.args())
1291     FunctionArgs.push_back(&Arg);
1292   ConstraintInfo Info(F.getParent()->getDataLayout(), FunctionArgs);
1293   State S(DT);
1294   std::unique_ptr<Module> ReproducerModule(
1295       DumpReproducers ? new Module(F.getName(), F.getContext()) : nullptr);
1296 
1297   // First, collect conditions implied by branches and blocks with their
1298   // Dominator DFS in and out numbers.
1299   for (BasicBlock &BB : F) {
1300     if (!DT.getNode(&BB))
1301       continue;
1302     S.addInfoFor(BB);
1303   }
1304 
1305   // Next, sort worklist by dominance, so that dominating conditions to check
1306   // and facts come before conditions and facts dominated by them. If a
1307   // condition to check and a fact have the same numbers, conditional facts come
1308   // first. Assume facts and checks are ordered according to their relative
1309   // order in the containing basic block. Also make sure conditions with
1310   // constant operands come before conditions without constant operands. This
1311   // increases the effectiveness of the current signed <-> unsigned fact
1312   // transfer logic.
1313   stable_sort(S.WorkList, [](const FactOrCheck &A, const FactOrCheck &B) {
1314     auto HasNoConstOp = [](const FactOrCheck &B) {
1315       return !isa<ConstantInt>(B.Inst->getOperand(0)) &&
1316              !isa<ConstantInt>(B.Inst->getOperand(1));
1317     };
1318     // If both entries have the same In numbers, conditional facts come first.
1319     // Otherwise use the relative order in the basic block.
1320     if (A.NumIn == B.NumIn) {
1321       if (A.isConditionFact() && B.isConditionFact()) {
1322         bool NoConstOpA = HasNoConstOp(A);
1323         bool NoConstOpB = HasNoConstOp(B);
1324         return NoConstOpA < NoConstOpB;
1325       }
1326       if (A.isConditionFact())
1327         return true;
1328       if (B.isConditionFact())
1329         return false;
1330       auto *InstA = A.getContextInst();
1331       auto *InstB = B.getContextInst();
1332       return InstA->comesBefore(InstB);
1333     }
1334     return A.NumIn < B.NumIn;
1335   });
1336 
1337   SmallVector<Instruction *> ToRemove;
1338 
1339   // Finally, process ordered worklist and eliminate implied conditions.
1340   SmallVector<StackEntry, 16> DFSInStack;
1341   SmallVector<ReproducerEntry> ReproducerCondStack;
1342   for (FactOrCheck &CB : S.WorkList) {
1343     // First, pop entries from the stack that are out-of-scope for CB. Remove
1344     // the corresponding entry from the constraint system.
1345     while (!DFSInStack.empty()) {
1346       auto &E = DFSInStack.back();
1347       LLVM_DEBUG(dbgs() << "Top of stack : " << E.NumIn << " " << E.NumOut
1348                         << "\n");
1349       LLVM_DEBUG(dbgs() << "CB: " << CB.NumIn << " " << CB.NumOut << "\n");
1350       assert(E.NumIn <= CB.NumIn);
1351       if (CB.NumOut <= E.NumOut)
1352         break;
1353       LLVM_DEBUG({
1354         dbgs() << "Removing ";
1355         dumpConstraint(Info.getCS(E.IsSigned).getLastConstraint(),
1356                        Info.getValue2Index(E.IsSigned));
1357         dbgs() << "\n";
1358       });
1359       removeEntryFromStack(E, Info, ReproducerModule.get(), ReproducerCondStack,
1360                            DFSInStack);
1361     }
1362 
1363     LLVM_DEBUG(dbgs() << "Processing ");
1364 
1365     // For a block, check if any CmpInsts become known based on the current set
1366     // of constraints.
1367     if (CB.isCheck()) {
1368       Instruction *Inst = CB.getInstructionToSimplify();
1369       if (!Inst)
1370         continue;
1371       LLVM_DEBUG(dbgs() << "condition to simplify: " << *Inst << "\n");
1372       if (auto *II = dyn_cast<WithOverflowInst>(Inst)) {
1373         Changed |= tryToSimplifyOverflowMath(II, Info, ToRemove);
1374       } else if (auto *Cmp = dyn_cast<ICmpInst>(Inst)) {
1375         bool Simplified = checkAndReplaceCondition(
1376             Cmp, Info, CB.NumIn, CB.NumOut, CB.getContextInst(),
1377             ReproducerModule.get(), ReproducerCondStack, S.DT, ToRemove);
1378         if (!Simplified && match(CB.getContextInst(),
1379                                  m_LogicalAnd(m_Value(), m_Specific(Inst)))) {
1380           Simplified =
1381               checkAndSecondOpImpliedByFirst(CB, Info, ReproducerModule.get(),
1382                                              ReproducerCondStack, DFSInStack);
1383         }
1384         Changed |= Simplified;
1385       }
1386       continue;
1387     }
1388 
1389     LLVM_DEBUG(dbgs() << "fact to add to the system: " << *CB.Inst << "\n");
1390     auto AddFact = [&](CmpInst::Predicate Pred, Value *A, Value *B) {
1391       if (Info.getCS(CmpInst::isSigned(Pred)).size() > MaxRows) {
1392         LLVM_DEBUG(
1393             dbgs()
1394             << "Skip adding constraint because system has too many rows.\n");
1395         return;
1396       }
1397 
1398       Info.addFact(Pred, A, B, CB.NumIn, CB.NumOut, DFSInStack);
1399       if (ReproducerModule && DFSInStack.size() > ReproducerCondStack.size())
1400         ReproducerCondStack.emplace_back(Pred, A, B);
1401 
1402       Info.transferToOtherSystem(Pred, A, B, CB.NumIn, CB.NumOut, DFSInStack);
1403       if (ReproducerModule && DFSInStack.size() > ReproducerCondStack.size()) {
1404         // Add dummy entries to ReproducerCondStack to keep it in sync with
1405         // DFSInStack.
1406         for (unsigned I = 0,
1407                       E = (DFSInStack.size() - ReproducerCondStack.size());
1408              I < E; ++I) {
1409           ReproducerCondStack.emplace_back(ICmpInst::BAD_ICMP_PREDICATE,
1410                                            nullptr, nullptr);
1411         }
1412       }
1413     };
1414 
1415     ICmpInst::Predicate Pred;
1416     if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(CB.Inst)) {
1417       Pred = ICmpInst::getNonStrictPredicate(MinMax->getPredicate());
1418       AddFact(Pred, MinMax, MinMax->getLHS());
1419       AddFact(Pred, MinMax, MinMax->getRHS());
1420       continue;
1421     }
1422 
1423     Value *A, *B;
1424     Value *Cmp = CB.Inst;
1425     match(Cmp, m_Intrinsic<Intrinsic::assume>(m_Value(Cmp)));
1426     if (match(Cmp, m_ICmp(Pred, m_Value(A), m_Value(B)))) {
1427       // Use the inverse predicate if required.
1428       if (CB.Not)
1429         Pred = CmpInst::getInversePredicate(Pred);
1430 
1431       AddFact(Pred, A, B);
1432     }
1433   }
1434 
1435   if (ReproducerModule && !ReproducerModule->functions().empty()) {
1436     std::string S;
1437     raw_string_ostream StringS(S);
1438     ReproducerModule->print(StringS, nullptr);
1439     StringS.flush();
1440     OptimizationRemark Rem(DEBUG_TYPE, "Reproducer", &F);
1441     Rem << ore::NV("module") << S;
1442     ORE.emit(Rem);
1443   }
1444 
1445 #ifndef NDEBUG
1446   unsigned SignedEntries =
1447       count_if(DFSInStack, [](const StackEntry &E) { return E.IsSigned; });
1448   assert(Info.getCS(false).size() == DFSInStack.size() - SignedEntries &&
1449          "updates to CS and DFSInStack are out of sync");
1450   assert(Info.getCS(true).size() == SignedEntries &&
1451          "updates to CS and DFSInStack are out of sync");
1452 #endif
1453 
1454   for (Instruction *I : ToRemove)
1455     I->eraseFromParent();
1456   return Changed;
1457 }
1458 
1459 PreservedAnalyses ConstraintEliminationPass::run(Function &F,
1460                                                  FunctionAnalysisManager &AM) {
1461   auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
1462   auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
1463   if (!eliminateConstraints(F, DT, ORE))
1464     return PreservedAnalyses::all();
1465 
1466   PreservedAnalyses PA;
1467   PA.preserve<DominatorTreeAnalysis>();
1468   PA.preserveSet<CFGAnalyses>();
1469   return PA;
1470 }
1471