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