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