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