xref: /llvm-project/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp (revision 3771310eede0041bae452870ef5e3fa70e48c17b)
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/ValueTracking.h"
22 #include "llvm/IR/DataLayout.h"
23 #include "llvm/IR/Dominators.h"
24 #include "llvm/IR/Function.h"
25 #include "llvm/IR/IRBuilder.h"
26 #include "llvm/IR/Instructions.h"
27 #include "llvm/IR/PatternMatch.h"
28 #include "llvm/InitializePasses.h"
29 #include "llvm/Pass.h"
30 #include "llvm/Support/Debug.h"
31 #include "llvm/Support/DebugCounter.h"
32 #include "llvm/Support/MathExtras.h"
33 #include "llvm/Transforms/Scalar.h"
34 
35 #include <cmath>
36 #include <string>
37 
38 using namespace llvm;
39 using namespace PatternMatch;
40 
41 #define DEBUG_TYPE "constraint-elimination"
42 
43 STATISTIC(NumCondsRemoved, "Number of instructions removed");
44 DEBUG_COUNTER(EliminatedCounter, "conds-eliminated",
45               "Controls which conditions are eliminated");
46 
47 static int64_t MaxConstraintValue = std::numeric_limits<int64_t>::max();
48 static int64_t MinSignedConstraintValue = std::numeric_limits<int64_t>::min();
49 
50 namespace {
51 
52 class ConstraintInfo;
53 
54 struct StackEntry {
55   unsigned NumIn;
56   unsigned NumOut;
57   bool IsSigned = false;
58   /// Variables that can be removed from the system once the stack entry gets
59   /// removed.
60   SmallVector<Value *, 2> ValuesToRelease;
61 
62   StackEntry(unsigned NumIn, unsigned NumOut, bool IsSigned,
63              SmallVector<Value *, 2> ValuesToRelease)
64       : NumIn(NumIn), NumOut(NumOut), IsSigned(IsSigned),
65         ValuesToRelease(ValuesToRelease) {}
66 };
67 
68 /// Struct to express a pre-condition of the form %Op0 Pred %Op1.
69 struct PreconditionTy {
70   CmpInst::Predicate Pred;
71   Value *Op0;
72   Value *Op1;
73 
74   PreconditionTy(CmpInst::Predicate Pred, Value *Op0, Value *Op1)
75       : Pred(Pred), Op0(Op0), Op1(Op1) {}
76 };
77 
78 struct ConstraintTy {
79   SmallVector<int64_t, 8> Coefficients;
80   SmallVector<PreconditionTy, 2> Preconditions;
81 
82   SmallVector<SmallVector<int64_t, 8>> ExtraInfo;
83 
84   bool IsSigned = false;
85   bool IsEq = false;
86 
87   ConstraintTy() = default;
88 
89   ConstraintTy(SmallVector<int64_t, 8> Coefficients, bool IsSigned)
90       : Coefficients(Coefficients), IsSigned(IsSigned) {}
91 
92   unsigned size() const { return Coefficients.size(); }
93 
94   unsigned empty() const { return Coefficients.empty(); }
95 
96   /// Returns true if all preconditions for this list of constraints are
97   /// satisfied given \p CS and the corresponding \p Value2Index mapping.
98   bool isValid(const ConstraintInfo &Info) const;
99 };
100 
101 /// Wrapper encapsulating separate constraint systems and corresponding value
102 /// mappings for both unsigned and signed information. Facts are added to and
103 /// conditions are checked against the corresponding system depending on the
104 /// signed-ness of their predicates. While the information is kept separate
105 /// based on signed-ness, certain conditions can be transferred between the two
106 /// systems.
107 class ConstraintInfo {
108   DenseMap<Value *, unsigned> UnsignedValue2Index;
109   DenseMap<Value *, unsigned> SignedValue2Index;
110 
111   ConstraintSystem UnsignedCS;
112   ConstraintSystem SignedCS;
113 
114   const DataLayout &DL;
115 
116 public:
117   ConstraintInfo(const DataLayout &DL) : DL(DL) {}
118 
119   DenseMap<Value *, unsigned> &getValue2Index(bool Signed) {
120     return Signed ? SignedValue2Index : UnsignedValue2Index;
121   }
122   const DenseMap<Value *, unsigned> &getValue2Index(bool Signed) const {
123     return Signed ? SignedValue2Index : UnsignedValue2Index;
124   }
125 
126   ConstraintSystem &getCS(bool Signed) {
127     return Signed ? SignedCS : UnsignedCS;
128   }
129   const ConstraintSystem &getCS(bool Signed) const {
130     return Signed ? SignedCS : UnsignedCS;
131   }
132 
133   void popLastConstraint(bool Signed) { getCS(Signed).popLastConstraint(); }
134   void popLastNVariables(bool Signed, unsigned N) {
135     getCS(Signed).popLastNVariables(N);
136   }
137 
138   bool doesHold(CmpInst::Predicate Pred, Value *A, Value *B) const;
139 
140   void addFact(CmpInst::Predicate Pred, Value *A, Value *B, unsigned NumIn,
141                unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack);
142 
143   /// Turn a comparison of the form \p Op0 \p Pred \p Op1 into a vector of
144   /// constraints, using indices from the corresponding constraint system.
145   /// New variables that need to be added to the system are collected in
146   /// \p NewVariables.
147   ConstraintTy getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
148                              SmallVectorImpl<Value *> &NewVariables) const;
149 
150   /// Turn a condition \p CmpI into a vector of constraints, using indices from
151   /// the corresponding constraint system. New variables that need to be added
152   /// to the system are collected in \p NewVariables.
153   ConstraintTy getConstraint(CmpInst *Cmp,
154                              SmallVectorImpl<Value *> &NewVariables) {
155     return getConstraint(Cmp->getPredicate(), Cmp->getOperand(0),
156                          Cmp->getOperand(1), NewVariables);
157   }
158 
159   /// Try to add information from \p A \p Pred \p B to the unsigned/signed
160   /// system if \p Pred is signed/unsigned.
161   void transferToOtherSystem(CmpInst::Predicate Pred, Value *A, Value *B,
162                              unsigned NumIn, unsigned NumOut,
163                              SmallVectorImpl<StackEntry> &DFSInStack);
164 };
165 
166 /// Represents a (Coefficient * Variable) entry after IR decomposition.
167 struct DecompEntry {
168   int64_t Coefficient;
169   Value *Variable;
170   /// True if the variable is known positive in the current constraint.
171   bool IsKnownPositive;
172 
173   DecompEntry(int64_t Coefficient, Value *Variable,
174               bool IsKnownPositive = false)
175       : Coefficient(Coefficient), Variable(Variable),
176         IsKnownPositive(IsKnownPositive) {}
177 };
178 
179 } // namespace
180 
181 // Decomposes \p V into a vector of entries of the form { Coefficient, Variable
182 // } where Coefficient * Variable. The sum of the pairs equals \p V.  The first
183 // pair is the constant-factor and X must be nullptr. If the expression cannot
184 // be decomposed, returns an empty vector.
185 static SmallVector<DecompEntry, 4>
186 decompose(Value *V, SmallVector<PreconditionTy, 4> &Preconditions,
187           bool IsSigned) {
188 
189   auto CanUseSExt = [](ConstantInt *CI) {
190     const APInt &Val = CI->getValue();
191     return Val.sgt(MinSignedConstraintValue) && Val.slt(MaxConstraintValue);
192   };
193   // Decompose \p V used with a signed predicate.
194   if (IsSigned) {
195     if (auto *CI = dyn_cast<ConstantInt>(V)) {
196       if (CanUseSExt(CI))
197         return {{CI->getSExtValue(), nullptr}};
198     }
199 
200     return {{0, nullptr}, {1, V}};
201   }
202 
203   if (auto *CI = dyn_cast<ConstantInt>(V)) {
204     if (CI->uge(MaxConstraintValue))
205       return {};
206     return {{int64_t(CI->getZExtValue()), nullptr}};
207   }
208   auto *GEP = dyn_cast<GetElementPtrInst>(V);
209   if (GEP && GEP->getNumOperands() == 2 && GEP->isInBounds()) {
210     Value *Op0, *Op1;
211     ConstantInt *CI;
212 
213     // If the index is zero-extended, it is guaranteed to be positive.
214     if (match(GEP->getOperand(GEP->getNumOperands() - 1),
215               m_ZExt(m_Value(Op0)))) {
216       if (match(Op0, m_NUWShl(m_Value(Op1), m_ConstantInt(CI))) &&
217           CanUseSExt(CI))
218         return {{0, nullptr},
219                 {1, GEP->getPointerOperand()},
220                 {int64_t(std::pow(int64_t(2), CI->getSExtValue())), Op1}};
221       if (match(Op0, m_NSWAdd(m_Value(Op1), m_ConstantInt(CI))) &&
222           CanUseSExt(CI))
223         return {{CI->getSExtValue(), nullptr},
224                 {1, GEP->getPointerOperand()},
225                 {1, Op1}};
226       return {{0, nullptr}, {1, GEP->getPointerOperand()}, {1, Op0, true}};
227     }
228 
229     if (match(GEP->getOperand(GEP->getNumOperands() - 1), m_ConstantInt(CI)) &&
230         !CI->isNegative() && CanUseSExt(CI))
231       return {{CI->getSExtValue(), nullptr}, {1, GEP->getPointerOperand()}};
232 
233     SmallVector<DecompEntry, 4> Result;
234     if (match(GEP->getOperand(GEP->getNumOperands() - 1),
235               m_NUWShl(m_Value(Op0), m_ConstantInt(CI))) &&
236         CanUseSExt(CI))
237       Result = {{0, nullptr},
238                 {1, GEP->getPointerOperand()},
239                 {int(std::pow(int64_t(2), CI->getSExtValue())), Op0}};
240     else if (match(GEP->getOperand(GEP->getNumOperands() - 1),
241                    m_NSWAdd(m_Value(Op0), m_ConstantInt(CI))) &&
242              CanUseSExt(CI))
243       Result = {{CI->getSExtValue(), nullptr},
244                 {1, GEP->getPointerOperand()},
245                 {1, Op0}};
246     else {
247       Op0 = GEP->getOperand(GEP->getNumOperands() - 1);
248       Result = {{0, nullptr}, {1, GEP->getPointerOperand()}, {1, Op0}};
249     }
250     // If Op0 is signed non-negative, the GEP is increasing monotonically and
251     // can be de-composed.
252     Preconditions.emplace_back(CmpInst::ICMP_SGE, Op0,
253                                ConstantInt::get(Op0->getType(), 0));
254     return Result;
255   }
256 
257   Value *Op0;
258   bool IsKnownPositive = false;
259   if (match(V, m_ZExt(m_Value(Op0)))) {
260     IsKnownPositive = true;
261     V = Op0;
262   }
263 
264   auto MergeResults = [&Preconditions, IsSigned](
265                           Value *A, Value *B,
266                           bool IsSignedB) -> SmallVector<DecompEntry, 4> {
267     auto ResA = decompose(A, Preconditions, IsSigned);
268     auto ResB = decompose(B, Preconditions, IsSignedB);
269     if (ResA.empty() || ResB.empty())
270       return {};
271     ResA[0].Coefficient += ResB[0].Coefficient;
272     append_range(ResA, drop_begin(ResB));
273     return ResA;
274   };
275   Value *Op1;
276   ConstantInt *CI;
277   if (match(V, m_NUWAdd(m_Value(Op0), m_Value(Op1)))) {
278     return MergeResults(Op0, Op1, IsSigned);
279   }
280   if (match(V, m_Add(m_Value(Op0), m_ConstantInt(CI))) && CI->isNegative() &&
281       CanUseSExt(CI)) {
282     Preconditions.emplace_back(
283         CmpInst::ICMP_UGE, Op0,
284         ConstantInt::get(Op0->getType(), CI->getSExtValue() * -1));
285     return MergeResults(Op0, CI, true);
286   }
287 
288   if (match(V, m_NUWSub(m_Value(Op0), m_ConstantInt(CI))) && CanUseSExt(CI))
289     return {{-1 * CI->getSExtValue(), nullptr}, {1, Op0}};
290   if (match(V, m_NUWSub(m_Value(Op0), m_Value(Op1))))
291     return {{0, nullptr}, {1, Op0}, {-1, Op1}};
292 
293   return {{0, nullptr}, {1, V, IsKnownPositive}};
294 }
295 
296 ConstraintTy
297 ConstraintInfo::getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
298                               SmallVectorImpl<Value *> &NewVariables) const {
299   assert(NewVariables.empty() && "NewVariables must be empty when passed in");
300   bool IsEq = false;
301   // Try to convert Pred to one of ULE/SLT/SLE/SLT.
302   switch (Pred) {
303   case CmpInst::ICMP_UGT:
304   case CmpInst::ICMP_UGE:
305   case CmpInst::ICMP_SGT:
306   case CmpInst::ICMP_SGE: {
307     Pred = CmpInst::getSwappedPredicate(Pred);
308     std::swap(Op0, Op1);
309     break;
310   }
311   case CmpInst::ICMP_EQ:
312     if (match(Op1, m_Zero())) {
313       Pred = CmpInst::ICMP_ULE;
314     } else {
315       IsEq = true;
316       Pred = CmpInst::ICMP_ULE;
317     }
318     break;
319   case CmpInst::ICMP_NE:
320     if (!match(Op1, m_Zero()))
321       return {};
322     Pred = CmpInst::getSwappedPredicate(CmpInst::ICMP_UGT);
323     std::swap(Op0, Op1);
324     break;
325   default:
326     break;
327   }
328 
329   // Only ULE and ULT predicates are supported at the moment.
330   if (Pred != CmpInst::ICMP_ULE && Pred != CmpInst::ICMP_ULT &&
331       Pred != CmpInst::ICMP_SLE && Pred != CmpInst::ICMP_SLT)
332     return {};
333 
334   // If both operands are known to be non-negative, change signed predicates to
335   // unsigned ones. This increases the reasoning effectiveness in combination
336   // with the signed <-> unsigned transfer logic.
337   if (CmpInst::isSigned(Pred) &&
338       isKnownNonNegative(Op0, DL, /*Depth=*/MaxAnalysisRecursionDepth - 1) &&
339       isKnownNonNegative(Op1, DL, /*Depth=*/MaxAnalysisRecursionDepth - 1))
340     Pred = CmpInst::getUnsignedPredicate(Pred);
341 
342   SmallVector<PreconditionTy, 4> Preconditions;
343   bool IsSigned = CmpInst::isSigned(Pred);
344   auto &Value2Index = getValue2Index(IsSigned);
345   auto ADec = decompose(Op0->stripPointerCastsSameRepresentation(),
346                         Preconditions, IsSigned);
347   auto BDec = decompose(Op1->stripPointerCastsSameRepresentation(),
348                         Preconditions, IsSigned);
349   // Skip if decomposing either of the values failed.
350   if (ADec.empty() || BDec.empty())
351     return {};
352 
353   int64_t Offset1 = ADec[0].Coefficient;
354   int64_t Offset2 = BDec[0].Coefficient;
355   Offset1 *= -1;
356 
357   // Create iterator ranges that skip the constant-factor.
358   auto VariablesA = llvm::drop_begin(ADec);
359   auto VariablesB = llvm::drop_begin(BDec);
360 
361   // First try to look up \p V in Value2Index and NewVariables. Otherwise add a
362   // new entry to NewVariables.
363   DenseMap<Value *, unsigned> NewIndexMap;
364   auto GetOrAddIndex = [&Value2Index, &NewVariables,
365                         &NewIndexMap](Value *V) -> unsigned {
366     auto V2I = Value2Index.find(V);
367     if (V2I != Value2Index.end())
368       return V2I->second;
369     auto Insert =
370         NewIndexMap.insert({V, Value2Index.size() + NewVariables.size() + 1});
371     if (Insert.second)
372       NewVariables.push_back(V);
373     return Insert.first->second;
374   };
375 
376   // Make sure all variables have entries in Value2Index or NewVariables.
377   for (const auto &KV : concat<DecompEntry>(VariablesA, VariablesB))
378     GetOrAddIndex(KV.Variable);
379 
380   // Build result constraint, by first adding all coefficients from A and then
381   // subtracting all coefficients from B.
382   ConstraintTy Res(
383       SmallVector<int64_t, 8>(Value2Index.size() + NewVariables.size() + 1, 0),
384       IsSigned);
385   // Collect variables that are known to be positive in all uses in the
386   // constraint.
387   DenseMap<Value *, bool> KnownPositiveVariables;
388   Res.IsEq = IsEq;
389   auto &R = Res.Coefficients;
390   for (const auto &KV : VariablesA) {
391     R[GetOrAddIndex(KV.Variable)] += KV.Coefficient;
392     auto I = KnownPositiveVariables.insert({KV.Variable, KV.IsKnownPositive});
393     I.first->second &= KV.IsKnownPositive;
394   }
395 
396   for (const auto &KV : VariablesB) {
397     R[GetOrAddIndex(KV.Variable)] -= KV.Coefficient;
398     auto I = KnownPositiveVariables.insert({KV.Variable, KV.IsKnownPositive});
399     I.first->second &= KV.IsKnownPositive;
400   }
401 
402   int64_t OffsetSum;
403   if (AddOverflow(Offset1, Offset2, OffsetSum))
404     return {};
405   if (Pred == (IsSigned ? CmpInst::ICMP_SLT : CmpInst::ICMP_ULT))
406     if (AddOverflow(OffsetSum, int64_t(-1), OffsetSum))
407       return {};
408   R[0] = OffsetSum;
409   Res.Preconditions = std::move(Preconditions);
410 
411   // Remove any (Coefficient, Variable) entry where the Coefficient is 0 for new
412   // variables.
413   while (!NewVariables.empty()) {
414     int64_t Last = R.back();
415     if (Last != 0)
416       break;
417     R.pop_back();
418     Value *RemovedV = NewVariables.pop_back_val();
419     NewIndexMap.erase(RemovedV);
420   }
421 
422   // Add extra constraints for variables that are known positive.
423   for (auto &KV : KnownPositiveVariables) {
424     if (!KV.second || (Value2Index.find(KV.first) == Value2Index.end() &&
425                        NewIndexMap.find(KV.first) == NewIndexMap.end()))
426       continue;
427     SmallVector<int64_t, 8> C(Value2Index.size() + NewVariables.size() + 1, 0);
428     C[GetOrAddIndex(KV.first)] = -1;
429     Res.ExtraInfo.push_back(C);
430   }
431   return Res;
432 }
433 
434 bool ConstraintTy::isValid(const ConstraintInfo &Info) const {
435   return Coefficients.size() > 0 &&
436          all_of(Preconditions, [&Info](const PreconditionTy &C) {
437            return Info.doesHold(C.Pred, C.Op0, C.Op1);
438          });
439 }
440 
441 bool ConstraintInfo::doesHold(CmpInst::Predicate Pred, Value *A,
442                               Value *B) const {
443   SmallVector<Value *> NewVariables;
444   auto R = getConstraint(Pred, A, B, NewVariables);
445 
446   if (!NewVariables.empty())
447     return false;
448 
449   return NewVariables.empty() && R.Preconditions.empty() && !R.IsEq &&
450          !R.empty() && getCS(R.IsSigned).isConditionImplied(R.Coefficients);
451 }
452 
453 void ConstraintInfo::transferToOtherSystem(
454     CmpInst::Predicate Pred, Value *A, Value *B, unsigned NumIn,
455     unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack) {
456   // Check if we can combine facts from the signed and unsigned systems to
457   // derive additional facts.
458   if (!A->getType()->isIntegerTy())
459     return;
460   // FIXME: This currently depends on the order we add facts. Ideally we
461   // would first add all known facts and only then try to add additional
462   // facts.
463   switch (Pred) {
464   default:
465     break;
466   case CmpInst::ICMP_ULT:
467     //  If B is a signed positive constant, A >=s 0 and A <s B.
468     if (doesHold(CmpInst::ICMP_SGE, B, ConstantInt::get(B->getType(), 0))) {
469       addFact(CmpInst::ICMP_SGE, A, ConstantInt::get(B->getType(), 0), NumIn,
470               NumOut, DFSInStack);
471       addFact(CmpInst::ICMP_SLT, A, B, NumIn, NumOut, DFSInStack);
472     }
473     break;
474   case CmpInst::ICMP_SLT:
475     if (doesHold(CmpInst::ICMP_SGE, A, ConstantInt::get(B->getType(), 0)))
476       addFact(CmpInst::ICMP_ULT, A, B, NumIn, NumOut, DFSInStack);
477     break;
478   case CmpInst::ICMP_SGT:
479     if (doesHold(CmpInst::ICMP_SGE, B, ConstantInt::get(B->getType(), -1)))
480       addFact(CmpInst::ICMP_UGE, A, ConstantInt::get(B->getType(), 0), NumIn,
481               NumOut, DFSInStack);
482     break;
483   case CmpInst::ICMP_SGE:
484     if (doesHold(CmpInst::ICMP_SGE, B, ConstantInt::get(B->getType(), 0))) {
485       addFact(CmpInst::ICMP_UGE, A, B, NumIn, NumOut, DFSInStack);
486     }
487     break;
488   }
489 }
490 
491 namespace {
492 /// Represents either a condition that holds on entry to a block or a basic
493 /// block, with their respective Dominator DFS in and out numbers.
494 struct ConstraintOrBlock {
495   unsigned NumIn;
496   unsigned NumOut;
497   bool IsBlock;
498   bool Not;
499   union {
500     BasicBlock *BB;
501     CmpInst *Condition;
502   };
503 
504   ConstraintOrBlock(DomTreeNode *DTN)
505       : NumIn(DTN->getDFSNumIn()), NumOut(DTN->getDFSNumOut()), IsBlock(true),
506         BB(DTN->getBlock()) {}
507   ConstraintOrBlock(DomTreeNode *DTN, CmpInst *Condition, bool Not)
508       : NumIn(DTN->getDFSNumIn()), NumOut(DTN->getDFSNumOut()), IsBlock(false),
509         Not(Not), Condition(Condition) {}
510 };
511 
512 /// Keep state required to build worklist.
513 struct State {
514   DominatorTree &DT;
515   SmallVector<ConstraintOrBlock, 64> WorkList;
516 
517   State(DominatorTree &DT) : DT(DT) {}
518 
519   /// Process block \p BB and add known facts to work-list.
520   void addInfoFor(BasicBlock &BB);
521 
522   /// Returns true if we can add a known condition from BB to its successor
523   /// block Succ. Each predecessor of Succ can either be BB or be dominated
524   /// by Succ (e.g. the case when adding a condition from a pre-header to a
525   /// loop header).
526   bool canAddSuccessor(BasicBlock &BB, BasicBlock *Succ) const {
527     if (BB.getSingleSuccessor()) {
528       assert(BB.getSingleSuccessor() == Succ);
529       return DT.properlyDominates(&BB, Succ);
530     }
531     return any_of(successors(&BB),
532                   [Succ](const BasicBlock *S) { return S != Succ; }) &&
533            all_of(predecessors(Succ), [&BB, Succ, this](BasicBlock *Pred) {
534              return Pred == &BB || DT.dominates(Succ, Pred);
535            });
536   }
537 };
538 
539 } // namespace
540 
541 #ifndef NDEBUG
542 static void dumpWithNames(const ConstraintSystem &CS,
543                           DenseMap<Value *, unsigned> &Value2Index) {
544   SmallVector<std::string> Names(Value2Index.size(), "");
545   for (auto &KV : Value2Index) {
546     Names[KV.second - 1] = std::string("%") + KV.first->getName().str();
547   }
548   CS.dump(Names);
549 }
550 
551 static void dumpWithNames(ArrayRef<int64_t> C,
552                           DenseMap<Value *, unsigned> &Value2Index) {
553   ConstraintSystem CS;
554   CS.addVariableRowFill(C);
555   dumpWithNames(CS, Value2Index);
556 }
557 #endif
558 
559 void State::addInfoFor(BasicBlock &BB) {
560   WorkList.emplace_back(DT.getNode(&BB));
561 
562   // True as long as long as the current instruction is guaranteed to execute.
563   bool GuaranteedToExecute = true;
564   // Scan BB for assume calls.
565   // TODO: also use this scan to queue conditions to simplify, so we can
566   // interleave facts from assumes and conditions to simplify in a single
567   // basic block. And to skip another traversal of each basic block when
568   // simplifying.
569   for (Instruction &I : BB) {
570     Value *Cond;
571     // For now, just handle assumes with a single compare as condition.
572     if (match(&I, m_Intrinsic<Intrinsic::assume>(m_Value(Cond))) &&
573         isa<ICmpInst>(Cond)) {
574       if (GuaranteedToExecute) {
575         // The assume is guaranteed to execute when BB is entered, hence Cond
576         // holds on entry to BB.
577         WorkList.emplace_back(DT.getNode(&BB), cast<ICmpInst>(Cond), false);
578       } else {
579         // Otherwise the condition only holds in the successors.
580         for (BasicBlock *Succ : successors(&BB)) {
581           if (!canAddSuccessor(BB, Succ))
582             continue;
583           WorkList.emplace_back(DT.getNode(Succ), cast<ICmpInst>(Cond), false);
584         }
585       }
586     }
587     GuaranteedToExecute &= isGuaranteedToTransferExecutionToSuccessor(&I);
588   }
589 
590   auto *Br = dyn_cast<BranchInst>(BB.getTerminator());
591   if (!Br || !Br->isConditional())
592     return;
593 
594   Value *Cond = Br->getCondition();
595 
596   // If the condition is a chain of ORs/AND and the successor only has the
597   // current block as predecessor, queue conditions for the successor.
598   Value *Op0, *Op1;
599   if (match(Cond, m_LogicalOr(m_Value(Op0), m_Value(Op1))) ||
600       match(Cond, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) {
601     bool IsOr = match(Cond, m_LogicalOr());
602     bool IsAnd = match(Cond, m_LogicalAnd());
603     // If there's a select that matches both AND and OR, we need to commit to
604     // one of the options. Arbitrarily pick OR.
605     if (IsOr && IsAnd)
606       IsAnd = false;
607 
608     BasicBlock *Successor = Br->getSuccessor(IsOr ? 1 : 0);
609     if (canAddSuccessor(BB, Successor)) {
610       SmallVector<Value *> CondWorkList;
611       SmallPtrSet<Value *, 8> SeenCond;
612       auto QueueValue = [&CondWorkList, &SeenCond](Value *V) {
613         if (SeenCond.insert(V).second)
614           CondWorkList.push_back(V);
615       };
616       QueueValue(Op1);
617       QueueValue(Op0);
618       while (!CondWorkList.empty()) {
619         Value *Cur = CondWorkList.pop_back_val();
620         if (auto *Cmp = dyn_cast<ICmpInst>(Cur)) {
621           WorkList.emplace_back(DT.getNode(Successor), Cmp, IsOr);
622           continue;
623         }
624         if (IsOr && match(Cur, m_LogicalOr(m_Value(Op0), m_Value(Op1)))) {
625           QueueValue(Op1);
626           QueueValue(Op0);
627           continue;
628         }
629         if (IsAnd && match(Cur, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) {
630           QueueValue(Op1);
631           QueueValue(Op0);
632           continue;
633         }
634       }
635     }
636     return;
637   }
638 
639   auto *CmpI = dyn_cast<ICmpInst>(Br->getCondition());
640   if (!CmpI)
641     return;
642   if (canAddSuccessor(BB, Br->getSuccessor(0)))
643     WorkList.emplace_back(DT.getNode(Br->getSuccessor(0)), CmpI, false);
644   if (canAddSuccessor(BB, Br->getSuccessor(1)))
645     WorkList.emplace_back(DT.getNode(Br->getSuccessor(1)), CmpI, true);
646 }
647 
648 void ConstraintInfo::addFact(CmpInst::Predicate Pred, Value *A, Value *B,
649                              unsigned NumIn, unsigned NumOut,
650                              SmallVectorImpl<StackEntry> &DFSInStack) {
651   // If the constraint has a pre-condition, skip the constraint if it does not
652   // hold.
653   SmallVector<Value *> NewVariables;
654   auto R = getConstraint(Pred, A, B, NewVariables);
655   if (!R.isValid(*this))
656     return;
657 
658   LLVM_DEBUG(dbgs() << "Adding '" << CmpInst::getPredicateName(Pred) << " ";
659              A->printAsOperand(dbgs(), false); dbgs() << ", ";
660              B->printAsOperand(dbgs(), false); dbgs() << "'\n");
661   bool Added = false;
662   auto &CSToUse = getCS(R.IsSigned);
663   if (R.Coefficients.empty())
664     return;
665 
666   Added |= CSToUse.addVariableRowFill(R.Coefficients);
667 
668   // If R has been added to the system, add the new variables and queue it for
669   // removal once it goes out-of-scope.
670   if (Added) {
671     SmallVector<Value *, 2> ValuesToRelease;
672     auto &Value2Index = getValue2Index(R.IsSigned);
673     for (Value *V : NewVariables) {
674       Value2Index.insert({V, Value2Index.size() + 1});
675       ValuesToRelease.push_back(V);
676     }
677 
678     LLVM_DEBUG({
679       dbgs() << "  constraint: ";
680       dumpWithNames(R.Coefficients, getValue2Index(R.IsSigned));
681       dbgs() << "\n";
682     });
683 
684     DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned, ValuesToRelease);
685 
686     if (R.IsEq) {
687       // Also add the inverted constraint for equality constraints.
688       for (auto &Coeff : R.Coefficients)
689         Coeff *= -1;
690       CSToUse.addVariableRowFill(R.Coefficients);
691 
692       DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
693                               SmallVector<Value *, 2>());
694     }
695   }
696 }
697 
698 static bool
699 tryToSimplifyOverflowMath(IntrinsicInst *II, ConstraintInfo &Info,
700                           SmallVectorImpl<Instruction *> &ToRemove) {
701   auto DoesConditionHold = [](CmpInst::Predicate Pred, Value *A, Value *B,
702                               ConstraintInfo &Info) {
703     SmallVector<Value *> NewVariables;
704     auto R = Info.getConstraint(Pred, A, B, NewVariables);
705     if (R.size() < 2 || !NewVariables.empty() || !R.isValid(Info))
706       return false;
707 
708     auto &CSToUse = Info.getCS(R.IsSigned);
709     return CSToUse.isConditionImplied(R.Coefficients);
710   };
711 
712   bool Changed = false;
713   if (II->getIntrinsicID() == Intrinsic::ssub_with_overflow) {
714     // If A s>= B && B s>= 0, ssub.with.overflow(a, b) should not overflow and
715     // can be simplified to a regular sub.
716     Value *A = II->getArgOperand(0);
717     Value *B = II->getArgOperand(1);
718     if (!DoesConditionHold(CmpInst::ICMP_SGE, A, B, Info) ||
719         !DoesConditionHold(CmpInst::ICMP_SGE, B,
720                            ConstantInt::get(A->getType(), 0), Info))
721       return false;
722 
723     IRBuilder<> Builder(II->getParent(), II->getIterator());
724     Value *Sub = nullptr;
725     for (User *U : make_early_inc_range(II->users())) {
726       if (match(U, m_ExtractValue<0>(m_Value()))) {
727         if (!Sub)
728           Sub = Builder.CreateSub(A, B);
729         U->replaceAllUsesWith(Sub);
730         Changed = true;
731       } else if (match(U, m_ExtractValue<1>(m_Value()))) {
732         U->replaceAllUsesWith(Builder.getFalse());
733         Changed = true;
734       } else
735         continue;
736 
737       if (U->use_empty()) {
738         auto *I = cast<Instruction>(U);
739         ToRemove.push_back(I);
740         I->setOperand(0, PoisonValue::get(II->getType()));
741         Changed = true;
742       }
743     }
744 
745     if (II->use_empty()) {
746       II->eraseFromParent();
747       Changed = true;
748     }
749   }
750   return Changed;
751 }
752 
753 static bool eliminateConstraints(Function &F, DominatorTree &DT) {
754   bool Changed = false;
755   DT.updateDFSNumbers();
756 
757   ConstraintInfo Info(F.getParent()->getDataLayout());
758   State S(DT);
759 
760   // First, collect conditions implied by branches and blocks with their
761   // Dominator DFS in and out numbers.
762   for (BasicBlock &BB : F) {
763     if (!DT.getNode(&BB))
764       continue;
765     S.addInfoFor(BB);
766   }
767 
768   // Next, sort worklist by dominance, so that dominating blocks and conditions
769   // come before blocks and conditions dominated by them. If a block and a
770   // condition have the same numbers, the condition comes before the block, as
771   // it holds on entry to the block. Also make sure conditions with constant
772   // operands come before conditions without constant operands. This increases
773   // the effectiveness of the current signed <-> unsigned fact transfer logic.
774   stable_sort(
775       S.WorkList, [](const ConstraintOrBlock &A, const ConstraintOrBlock &B) {
776         auto HasNoConstOp = [](const ConstraintOrBlock &B) {
777           return !B.IsBlock && !isa<ConstantInt>(B.Condition->getOperand(0)) &&
778                  !isa<ConstantInt>(B.Condition->getOperand(1));
779         };
780         bool NoConstOpA = HasNoConstOp(A);
781         bool NoConstOpB = HasNoConstOp(B);
782         return std::tie(A.NumIn, A.IsBlock, NoConstOpA) <
783                std::tie(B.NumIn, B.IsBlock, NoConstOpB);
784       });
785 
786   SmallVector<Instruction *> ToRemove;
787 
788   // Finally, process ordered worklist and eliminate implied conditions.
789   SmallVector<StackEntry, 16> DFSInStack;
790   for (ConstraintOrBlock &CB : S.WorkList) {
791     // First, pop entries from the stack that are out-of-scope for CB. Remove
792     // the corresponding entry from the constraint system.
793     while (!DFSInStack.empty()) {
794       auto &E = DFSInStack.back();
795       LLVM_DEBUG(dbgs() << "Top of stack : " << E.NumIn << " " << E.NumOut
796                         << "\n");
797       LLVM_DEBUG(dbgs() << "CB: " << CB.NumIn << " " << CB.NumOut << "\n");
798       assert(E.NumIn <= CB.NumIn);
799       if (CB.NumOut <= E.NumOut)
800         break;
801       LLVM_DEBUG({
802         dbgs() << "Removing ";
803         dumpWithNames(Info.getCS(E.IsSigned).getLastConstraint(),
804                       Info.getValue2Index(E.IsSigned));
805         dbgs() << "\n";
806       });
807 
808       Info.popLastConstraint(E.IsSigned);
809       // Remove variables in the system that went out of scope.
810       auto &Mapping = Info.getValue2Index(E.IsSigned);
811       for (Value *V : E.ValuesToRelease)
812         Mapping.erase(V);
813       Info.popLastNVariables(E.IsSigned, E.ValuesToRelease.size());
814       DFSInStack.pop_back();
815     }
816 
817     LLVM_DEBUG({
818       dbgs() << "Processing ";
819       if (CB.IsBlock)
820         dbgs() << *CB.BB;
821       else
822         dbgs() << *CB.Condition;
823       dbgs() << "\n";
824     });
825 
826     // For a block, check if any CmpInsts become known based on the current set
827     // of constraints.
828     if (CB.IsBlock) {
829       for (Instruction &I : make_early_inc_range(*CB.BB)) {
830         if (auto *II = dyn_cast<WithOverflowInst>(&I)) {
831           Changed |= tryToSimplifyOverflowMath(II, Info, ToRemove);
832           continue;
833         }
834         auto *Cmp = dyn_cast<ICmpInst>(&I);
835         if (!Cmp)
836           continue;
837 
838         LLVM_DEBUG(dbgs() << "Checking " << *Cmp << "\n");
839         SmallVector<Value *> NewVariables;
840         auto R = Info.getConstraint(Cmp, NewVariables);
841         if (R.IsEq || R.empty() || !NewVariables.empty() || !R.isValid(Info))
842           continue;
843 
844         auto &CSToUse = Info.getCS(R.IsSigned);
845 
846         // If there was extra information collected during decomposition, apply
847         // it now and remove it immediately once we are done with reasoning
848         // about the constraint.
849         for (auto &Row : R.ExtraInfo)
850           CSToUse.addVariableRow(Row);
851         auto InfoRestorer = make_scope_exit([&]() {
852           for (unsigned I = 0; I < R.ExtraInfo.size(); ++I)
853             CSToUse.popLastConstraint();
854         });
855 
856         if (CSToUse.isConditionImplied(R.Coefficients)) {
857           if (!DebugCounter::shouldExecute(EliminatedCounter))
858             continue;
859 
860           LLVM_DEBUG({
861             dbgs() << "Condition " << *Cmp
862                    << " implied by dominating constraints\n";
863             dumpWithNames(CSToUse, Info.getValue2Index(R.IsSigned));
864           });
865           Cmp->replaceUsesWithIf(
866               ConstantInt::getTrue(F.getParent()->getContext()), [](Use &U) {
867                 // Conditions in an assume trivially simplify to true. Skip uses
868                 // in assume calls to not destroy the available information.
869                 auto *II = dyn_cast<IntrinsicInst>(U.getUser());
870                 return !II || II->getIntrinsicID() != Intrinsic::assume;
871               });
872           NumCondsRemoved++;
873           Changed = true;
874         }
875         if (CSToUse.isConditionImplied(
876                 ConstraintSystem::negate(R.Coefficients))) {
877           if (!DebugCounter::shouldExecute(EliminatedCounter))
878             continue;
879 
880           LLVM_DEBUG({
881             dbgs() << "Condition !" << *Cmp
882                    << " implied by dominating constraints\n";
883             dumpWithNames(CSToUse, Info.getValue2Index(R.IsSigned));
884           });
885           Cmp->replaceAllUsesWith(
886               ConstantInt::getFalse(F.getParent()->getContext()));
887           NumCondsRemoved++;
888           Changed = true;
889         }
890       }
891       continue;
892     }
893 
894     ICmpInst::Predicate Pred;
895     Value *A, *B;
896     if (match(CB.Condition, m_ICmp(Pred, m_Value(A), m_Value(B)))) {
897       // Use the inverse predicate if required.
898       if (CB.Not)
899         Pred = CmpInst::getInversePredicate(Pred);
900 
901       Info.addFact(Pred, A, B, CB.NumIn, CB.NumOut, DFSInStack);
902       Info.transferToOtherSystem(Pred, A, B, CB.NumIn, CB.NumOut, DFSInStack);
903     }
904   }
905 
906 #ifndef NDEBUG
907   unsigned SignedEntries =
908       count_if(DFSInStack, [](const StackEntry &E) { return E.IsSigned; });
909   assert(Info.getCS(false).size() == DFSInStack.size() - SignedEntries &&
910          "updates to CS and DFSInStack are out of sync");
911   assert(Info.getCS(true).size() == SignedEntries &&
912          "updates to CS and DFSInStack are out of sync");
913 #endif
914 
915   for (Instruction *I : ToRemove)
916     I->eraseFromParent();
917   return Changed;
918 }
919 
920 PreservedAnalyses ConstraintEliminationPass::run(Function &F,
921                                                  FunctionAnalysisManager &AM) {
922   auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
923   if (!eliminateConstraints(F, DT))
924     return PreservedAnalyses::all();
925 
926   PreservedAnalyses PA;
927   PA.preserve<DominatorTreeAnalysis>();
928   PA.preserveSet<CFGAnalyses>();
929   return PA;
930 }
931 
932 namespace {
933 
934 class ConstraintElimination : public FunctionPass {
935 public:
936   static char ID;
937 
938   ConstraintElimination() : FunctionPass(ID) {
939     initializeConstraintEliminationPass(*PassRegistry::getPassRegistry());
940   }
941 
942   bool runOnFunction(Function &F) override {
943     auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
944     return eliminateConstraints(F, DT);
945   }
946 
947   void getAnalysisUsage(AnalysisUsage &AU) const override {
948     AU.setPreservesCFG();
949     AU.addRequired<DominatorTreeWrapperPass>();
950     AU.addPreserved<GlobalsAAWrapperPass>();
951     AU.addPreserved<DominatorTreeWrapperPass>();
952   }
953 };
954 
955 } // end anonymous namespace
956 
957 char ConstraintElimination::ID = 0;
958 
959 INITIALIZE_PASS_BEGIN(ConstraintElimination, "constraint-elimination",
960                       "Constraint Elimination", false, false)
961 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
962 INITIALIZE_PASS_DEPENDENCY(LazyValueInfoWrapperPass)
963 INITIALIZE_PASS_END(ConstraintElimination, "constraint-elimination",
964                     "Constraint Elimination", false, false)
965 
966 FunctionPass *llvm::createConstraintEliminationPass() {
967   return new ConstraintElimination();
968 }
969