1 //===-- ConstraintElimination.cpp - Eliminate conds using constraints. ----===//
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
7 //===----------------------------------------------------------------------===//
9 // Eliminate conditions based on constraints collected from dominating
12 //===----------------------------------------------------------------------===//
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/LoopInfo.h"
22 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
23 #include "llvm/Analysis/ScalarEvolution.h"
24 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
25 #include "llvm/Analysis/ValueTracking.h"
26 #include "llvm/IR/DataLayout.h"
27 #include "llvm/IR/Dominators.h"
28 #include "llvm/IR/Function.h"
29 #include "llvm/IR/IRBuilder.h"
30 #include "llvm/IR/InstrTypes.h"
31 #include "llvm/IR/Instructions.h"
32 #include "llvm/IR/PatternMatch.h"
33 #include "llvm/IR/Verifier.h"
34 #include "llvm/Pass.h"
35 #include "llvm/Support/CommandLine.h"
36 #include "llvm/Support/Debug.h"
37 #include "llvm/Support/DebugCounter.h"
38 #include "llvm/Support/MathExtras.h"
39 #include "llvm/Transforms/Utils/Cloning.h"
40 #include "llvm/Transforms/Utils/ValueMapper.h"
47 using namespace PatternMatch
;
49 #define DEBUG_TYPE "constraint-elimination"
51 STATISTIC(NumCondsRemoved
, "Number of instructions removed");
52 DEBUG_COUNTER(EliminatedCounter
, "conds-eliminated",
53 "Controls which conditions are eliminated");
55 static cl::opt
<unsigned>
56 MaxRows("constraint-elimination-max-rows", cl::init(500), cl::Hidden
,
57 cl::desc("Maximum number of rows to keep in constraint system"));
59 static cl::opt
<bool> DumpReproducers(
60 "constraint-elimination-dump-reproducers", cl::init(false), cl::Hidden
,
61 cl::desc("Dump IR to reproduce successful transformations."));
63 static int64_t MaxConstraintValue
= std::numeric_limits
<int64_t>::max();
64 static int64_t MinSignedConstraintValue
= std::numeric_limits
<int64_t>::min();
66 // A helper to multiply 2 signed integers where overflowing is allowed.
67 static int64_t multiplyWithOverflow(int64_t A
, int64_t B
) {
69 MulOverflow(A
, B
, Result
);
73 // A helper to add 2 signed integers where overflowing is allowed.
74 static int64_t addWithOverflow(int64_t A
, int64_t B
) {
76 AddOverflow(A
, B
, Result
);
80 static Instruction
*getContextInstForUse(Use
&U
) {
81 Instruction
*UserI
= cast
<Instruction
>(U
.getUser());
82 if (auto *Phi
= dyn_cast
<PHINode
>(UserI
))
83 UserI
= Phi
->getIncomingBlock(U
)->getTerminator();
88 /// Struct to express a condition of the form %Op0 Pred %Op1.
90 CmpInst::Predicate Pred
;
95 : Pred(CmpInst::BAD_ICMP_PREDICATE
), Op0(nullptr), Op1(nullptr) {}
96 ConditionTy(CmpInst::Predicate Pred
, Value
*Op0
, Value
*Op1
)
97 : Pred(Pred
), Op0(Op0
), Op1(Op1
) {}
100 /// Represents either
101 /// * a condition that holds on entry to a block (=condition fact)
102 /// * an assume (=assume fact)
103 /// * a use of a compare instruction to simplify.
104 /// It also tracks the Dominator DFS in and out numbers for each entry.
107 ConditionFact
, /// A condition that holds on entry to a block.
108 InstFact
, /// A fact that holds after Inst executed (e.g. an assume or
109 /// min/mix intrinsic.
110 InstCheck
, /// An instruction to simplify (e.g. an overflow math
112 UseCheck
/// An use of a compare instruction to simplify.
121 /// A pre-condition that must hold for the current fact to be added to the
123 ConditionTy DoesHold
;
129 FactOrCheck(EntryTy Ty
, DomTreeNode
*DTN
, Instruction
*Inst
)
130 : Inst(Inst
), NumIn(DTN
->getDFSNumIn()), NumOut(DTN
->getDFSNumOut()),
133 FactOrCheck(DomTreeNode
*DTN
, Use
*U
)
134 : U(U
), DoesHold(CmpInst::BAD_ICMP_PREDICATE
, nullptr, nullptr),
135 NumIn(DTN
->getDFSNumIn()), NumOut(DTN
->getDFSNumOut()),
136 Ty(EntryTy::UseCheck
) {}
138 FactOrCheck(DomTreeNode
*DTN
, CmpInst::Predicate Pred
, Value
*Op0
, Value
*Op1
,
139 ConditionTy Precond
= ConditionTy())
140 : Cond(Pred
, Op0
, Op1
), DoesHold(Precond
), NumIn(DTN
->getDFSNumIn()),
141 NumOut(DTN
->getDFSNumOut()), Ty(EntryTy::ConditionFact
) {}
143 static FactOrCheck
getConditionFact(DomTreeNode
*DTN
, CmpInst::Predicate Pred
,
144 Value
*Op0
, Value
*Op1
,
145 ConditionTy Precond
= ConditionTy()) {
146 return FactOrCheck(DTN
, Pred
, Op0
, Op1
, Precond
);
149 static FactOrCheck
getInstFact(DomTreeNode
*DTN
, Instruction
*Inst
) {
150 return FactOrCheck(EntryTy::InstFact
, DTN
, Inst
);
153 static FactOrCheck
getCheck(DomTreeNode
*DTN
, Use
*U
) {
154 return FactOrCheck(DTN
, U
);
157 static FactOrCheck
getCheck(DomTreeNode
*DTN
, CallInst
*CI
) {
158 return FactOrCheck(EntryTy::InstCheck
, DTN
, CI
);
161 bool isCheck() const {
162 return Ty
== EntryTy::InstCheck
|| Ty
== EntryTy::UseCheck
;
165 Instruction
*getContextInst() const {
166 if (Ty
== EntryTy::UseCheck
)
167 return getContextInstForUse(*U
);
171 Instruction
*getInstructionToSimplify() const {
173 if (Ty
== EntryTy::InstCheck
)
175 // The use may have been simplified to a constant already.
176 return dyn_cast
<Instruction
>(*U
);
179 bool isConditionFact() const { return Ty
== EntryTy::ConditionFact
; }
182 /// Keep state required to build worklist.
187 SmallVector
<FactOrCheck
, 64> WorkList
;
189 State(DominatorTree
&DT
, LoopInfo
&LI
, ScalarEvolution
&SE
)
190 : DT(DT
), LI(LI
), SE(SE
) {}
192 /// Process block \p BB and add known facts to work-list.
193 void addInfoFor(BasicBlock
&BB
);
195 /// Try to add facts for loop inductions (AddRecs) in EQ/NE compares
196 /// controlling the loop header.
197 void addInfoForInductions(BasicBlock
&BB
);
199 /// Returns true if we can add a known condition from BB to its successor
201 bool canAddSuccessor(BasicBlock
&BB
, BasicBlock
*Succ
) const {
202 return DT
.dominates(BasicBlockEdge(&BB
, Succ
), Succ
);
206 class ConstraintInfo
;
211 bool IsSigned
= false;
212 /// Variables that can be removed from the system once the stack entry gets
214 SmallVector
<Value
*, 2> ValuesToRelease
;
216 StackEntry(unsigned NumIn
, unsigned NumOut
, bool IsSigned
,
217 SmallVector
<Value
*, 2> ValuesToRelease
)
218 : NumIn(NumIn
), NumOut(NumOut
), IsSigned(IsSigned
),
219 ValuesToRelease(ValuesToRelease
) {}
222 struct ConstraintTy
{
223 SmallVector
<int64_t, 8> Coefficients
;
224 SmallVector
<ConditionTy
, 2> Preconditions
;
226 SmallVector
<SmallVector
<int64_t, 8>> ExtraInfo
;
228 bool IsSigned
= false;
230 ConstraintTy() = default;
232 ConstraintTy(SmallVector
<int64_t, 8> Coefficients
, bool IsSigned
, bool IsEq
,
234 : Coefficients(Coefficients
), IsSigned(IsSigned
), IsEq(IsEq
), IsNe(IsNe
) {
237 unsigned size() const { return Coefficients
.size(); }
239 unsigned empty() const { return Coefficients
.empty(); }
241 /// Returns true if all preconditions for this list of constraints are
242 /// satisfied given \p CS and the corresponding \p Value2Index mapping.
243 bool isValid(const ConstraintInfo
&Info
) const;
245 bool isEq() const { return IsEq
; }
247 bool isNe() const { return IsNe
; }
249 /// Check if the current constraint is implied by the given ConstraintSystem.
251 /// \return true or false if the constraint is proven to be respectively true,
252 /// or false. When the constraint cannot be proven to be either true or false,
253 /// std::nullopt is returned.
254 std::optional
<bool> isImpliedBy(const ConstraintSystem
&CS
) const;
261 /// Wrapper encapsulating separate constraint systems and corresponding value
262 /// mappings for both unsigned and signed information. Facts are added to and
263 /// conditions are checked against the corresponding system depending on the
264 /// signed-ness of their predicates. While the information is kept separate
265 /// based on signed-ness, certain conditions can be transferred between the two
267 class ConstraintInfo
{
269 ConstraintSystem UnsignedCS
;
270 ConstraintSystem SignedCS
;
272 const DataLayout
&DL
;
275 ConstraintInfo(const DataLayout
&DL
, ArrayRef
<Value
*> FunctionArgs
)
276 : UnsignedCS(FunctionArgs
), SignedCS(FunctionArgs
), DL(DL
) {
277 auto &Value2Index
= getValue2Index(false);
278 // Add Arg > -1 constraints to unsigned system for all function arguments.
279 for (Value
*Arg
: FunctionArgs
) {
280 ConstraintTy
VarPos(SmallVector
<int64_t, 8>(Value2Index
.size() + 1, 0),
281 false, false, false);
282 VarPos
.Coefficients
[Value2Index
[Arg
]] = -1;
283 UnsignedCS
.addVariableRow(VarPos
.Coefficients
);
287 DenseMap
<Value
*, unsigned> &getValue2Index(bool Signed
) {
288 return Signed
? SignedCS
.getValue2Index() : UnsignedCS
.getValue2Index();
290 const DenseMap
<Value
*, unsigned> &getValue2Index(bool Signed
) const {
291 return Signed
? SignedCS
.getValue2Index() : UnsignedCS
.getValue2Index();
294 ConstraintSystem
&getCS(bool Signed
) {
295 return Signed
? SignedCS
: UnsignedCS
;
297 const ConstraintSystem
&getCS(bool Signed
) const {
298 return Signed
? SignedCS
: UnsignedCS
;
301 void popLastConstraint(bool Signed
) { getCS(Signed
).popLastConstraint(); }
302 void popLastNVariables(bool Signed
, unsigned N
) {
303 getCS(Signed
).popLastNVariables(N
);
306 bool doesHold(CmpInst::Predicate Pred
, Value
*A
, Value
*B
) const;
308 void addFact(CmpInst::Predicate Pred
, Value
*A
, Value
*B
, unsigned NumIn
,
309 unsigned NumOut
, SmallVectorImpl
<StackEntry
> &DFSInStack
);
311 /// Turn a comparison of the form \p Op0 \p Pred \p Op1 into a vector of
312 /// constraints, using indices from the corresponding constraint system.
313 /// New variables that need to be added to the system are collected in
315 ConstraintTy
getConstraint(CmpInst::Predicate Pred
, Value
*Op0
, Value
*Op1
,
316 SmallVectorImpl
<Value
*> &NewVariables
) const;
318 /// Turns a comparison of the form \p Op0 \p Pred \p Op1 into a vector of
319 /// constraints using getConstraint. Returns an empty constraint if the result
320 /// cannot be used to query the existing constraint system, e.g. because it
321 /// would require adding new variables. Also tries to convert signed
322 /// predicates to unsigned ones if possible to allow using the unsigned system
323 /// which increases the effectiveness of the signed <-> unsigned transfer
325 ConstraintTy
getConstraintForSolving(CmpInst::Predicate Pred
, Value
*Op0
,
328 /// Try to add information from \p A \p Pred \p B to the unsigned/signed
329 /// system if \p Pred is signed/unsigned.
330 void transferToOtherSystem(CmpInst::Predicate Pred
, Value
*A
, Value
*B
,
331 unsigned NumIn
, unsigned NumOut
,
332 SmallVectorImpl
<StackEntry
> &DFSInStack
);
335 /// Represents a (Coefficient * Variable) entry after IR decomposition.
339 /// True if the variable is known positive in the current constraint.
340 bool IsKnownNonNegative
;
342 DecompEntry(int64_t Coefficient
, Value
*Variable
,
343 bool IsKnownNonNegative
= false)
344 : Coefficient(Coefficient
), Variable(Variable
),
345 IsKnownNonNegative(IsKnownNonNegative
) {}
348 /// Represents an Offset + Coefficient1 * Variable1 + ... decomposition.
349 struct Decomposition
{
351 SmallVector
<DecompEntry
, 3> Vars
;
353 Decomposition(int64_t Offset
) : Offset(Offset
) {}
354 Decomposition(Value
*V
, bool IsKnownNonNegative
= false) {
355 Vars
.emplace_back(1, V
, IsKnownNonNegative
);
357 Decomposition(int64_t Offset
, ArrayRef
<DecompEntry
> Vars
)
358 : Offset(Offset
), Vars(Vars
) {}
360 void add(int64_t OtherOffset
) {
361 Offset
= addWithOverflow(Offset
, OtherOffset
);
364 void add(const Decomposition
&Other
) {
366 append_range(Vars
, Other
.Vars
);
369 void sub(const Decomposition
&Other
) {
370 Decomposition Tmp
= Other
;
373 append_range(Vars
, Tmp
.Vars
);
376 void mul(int64_t Factor
) {
377 Offset
= multiplyWithOverflow(Offset
, Factor
);
378 for (auto &Var
: Vars
)
379 Var
.Coefficient
= multiplyWithOverflow(Var
.Coefficient
, Factor
);
383 // Variable and constant offsets for a chain of GEPs, with base pointer BasePtr.
384 struct OffsetResult
{
386 APInt ConstantOffset
;
387 MapVector
<Value
*, APInt
> VariableOffsets
;
390 OffsetResult() : BasePtr(nullptr), ConstantOffset(0, uint64_t(0)) {}
392 OffsetResult(GEPOperator
&GEP
, const DataLayout
&DL
)
393 : BasePtr(GEP
.getPointerOperand()), AllInbounds(GEP
.isInBounds()) {
394 ConstantOffset
= APInt(DL
.getIndexTypeSizeInBits(BasePtr
->getType()), 0);
399 // Try to collect variable and constant offsets for \p GEP, partly traversing
400 // nested GEPs. Returns an OffsetResult with nullptr as BasePtr of collecting
402 static OffsetResult
collectOffsets(GEPOperator
&GEP
, const DataLayout
&DL
) {
403 OffsetResult
Result(GEP
, DL
);
404 unsigned BitWidth
= Result
.ConstantOffset
.getBitWidth();
405 if (!GEP
.collectOffset(DL
, BitWidth
, Result
.VariableOffsets
,
406 Result
.ConstantOffset
))
409 // If we have a nested GEP, check if we can combine the constant offset of the
410 // inner GEP with the outer GEP.
411 if (auto *InnerGEP
= dyn_cast
<GetElementPtrInst
>(Result
.BasePtr
)) {
412 MapVector
<Value
*, APInt
> VariableOffsets2
;
413 APInt
ConstantOffset2(BitWidth
, 0);
414 bool CanCollectInner
= InnerGEP
->collectOffset(
415 DL
, BitWidth
, VariableOffsets2
, ConstantOffset2
);
416 // TODO: Support cases with more than 1 variable offset.
417 if (!CanCollectInner
|| Result
.VariableOffsets
.size() > 1 ||
418 VariableOffsets2
.size() > 1 ||
419 (Result
.VariableOffsets
.size() >= 1 && VariableOffsets2
.size() >= 1)) {
420 // More than 1 variable index, use outer result.
423 Result
.BasePtr
= InnerGEP
->getPointerOperand();
424 Result
.ConstantOffset
+= ConstantOffset2
;
425 if (Result
.VariableOffsets
.size() == 0 && VariableOffsets2
.size() == 1)
426 Result
.VariableOffsets
= VariableOffsets2
;
427 Result
.AllInbounds
&= InnerGEP
->isInBounds();
432 static Decomposition
decompose(Value
*V
,
433 SmallVectorImpl
<ConditionTy
> &Preconditions
,
434 bool IsSigned
, const DataLayout
&DL
);
436 static bool canUseSExt(ConstantInt
*CI
) {
437 const APInt
&Val
= CI
->getValue();
438 return Val
.sgt(MinSignedConstraintValue
) && Val
.slt(MaxConstraintValue
);
441 static Decomposition
decomposeGEP(GEPOperator
&GEP
,
442 SmallVectorImpl
<ConditionTy
> &Preconditions
,
443 bool IsSigned
, const DataLayout
&DL
) {
444 // Do not reason about pointers where the index size is larger than 64 bits,
445 // as the coefficients used to encode constraints are 64 bit integers.
446 if (DL
.getIndexTypeSizeInBits(GEP
.getPointerOperand()->getType()) > 64)
449 assert(!IsSigned
&& "The logic below only supports decomposition for "
450 "unsigned predicates at the moment.");
451 const auto &[BasePtr
, ConstantOffset
, VariableOffsets
, AllInbounds
] =
452 collectOffsets(GEP
, DL
);
453 if (!BasePtr
|| !AllInbounds
)
456 Decomposition
Result(ConstantOffset
.getSExtValue(), DecompEntry(1, BasePtr
));
457 for (auto [Index
, Scale
] : VariableOffsets
) {
458 auto IdxResult
= decompose(Index
, Preconditions
, IsSigned
, DL
);
459 IdxResult
.mul(Scale
.getSExtValue());
460 Result
.add(IdxResult
);
462 // If Op0 is signed non-negative, the GEP is increasing monotonically and
463 // can be de-composed.
464 if (!isKnownNonNegative(Index
, DL
, /*Depth=*/MaxAnalysisRecursionDepth
- 1))
465 Preconditions
.emplace_back(CmpInst::ICMP_SGE
, Index
,
466 ConstantInt::get(Index
->getType(), 0));
471 // Decomposes \p V into a constant offset + list of pairs { Coefficient,
472 // Variable } where Coefficient * Variable. The sum of the constant offset and
473 // pairs equals \p V.
474 static Decomposition
decompose(Value
*V
,
475 SmallVectorImpl
<ConditionTy
> &Preconditions
,
476 bool IsSigned
, const DataLayout
&DL
) {
478 auto MergeResults
= [&Preconditions
, IsSigned
, &DL
](Value
*A
, Value
*B
,
480 auto ResA
= decompose(A
, Preconditions
, IsSigned
, DL
);
481 auto ResB
= decompose(B
, Preconditions
, IsSignedB
, DL
);
486 Type
*Ty
= V
->getType()->getScalarType();
487 if (Ty
->isPointerTy() && !IsSigned
) {
488 if (auto *GEP
= dyn_cast
<GEPOperator
>(V
))
489 return decomposeGEP(*GEP
, Preconditions
, IsSigned
, DL
);
490 if (isa
<ConstantPointerNull
>(V
))
496 // Don't handle integers > 64 bit. Our coefficients are 64-bit large, so
497 // coefficient add/mul may wrap, while the operation in the full bit width
499 if (!Ty
->isIntegerTy() || Ty
->getIntegerBitWidth() > 64)
502 // Decompose \p V used with a signed predicate.
504 if (auto *CI
= dyn_cast
<ConstantInt
>(V
)) {
506 return CI
->getSExtValue();
510 if (match(V
, m_NSWAdd(m_Value(Op0
), m_Value(Op1
))))
511 return MergeResults(Op0
, Op1
, IsSigned
);
514 if (match(V
, m_NSWMul(m_Value(Op0
), m_ConstantInt(CI
))) && canUseSExt(CI
)) {
515 auto Result
= decompose(Op0
, Preconditions
, IsSigned
, DL
);
516 Result
.mul(CI
->getSExtValue());
520 // (shl nsw x, shift) is (mul nsw x, (1<<shift)), with the exception of
522 if (match(V
, m_NSWShl(m_Value(Op0
), m_ConstantInt(CI
)))) {
523 uint64_t Shift
= CI
->getValue().getLimitedValue();
524 if (Shift
< Ty
->getIntegerBitWidth() - 1) {
525 assert(Shift
< 64 && "Would overflow");
526 auto Result
= decompose(Op0
, Preconditions
, IsSigned
, DL
);
527 Result
.mul(int64_t(1) << Shift
);
535 if (auto *CI
= dyn_cast
<ConstantInt
>(V
)) {
536 if (CI
->uge(MaxConstraintValue
))
538 return int64_t(CI
->getZExtValue());
542 bool IsKnownNonNegative
= false;
543 if (match(V
, m_ZExt(m_Value(Op0
)))) {
544 IsKnownNonNegative
= true;
550 if (match(V
, m_NUWAdd(m_Value(Op0
), m_Value(Op1
)))) {
551 return MergeResults(Op0
, Op1
, IsSigned
);
553 if (match(V
, m_NSWAdd(m_Value(Op0
), m_Value(Op1
)))) {
554 if (!isKnownNonNegative(Op0
, DL
, /*Depth=*/MaxAnalysisRecursionDepth
- 1))
555 Preconditions
.emplace_back(CmpInst::ICMP_SGE
, Op0
,
556 ConstantInt::get(Op0
->getType(), 0));
557 if (!isKnownNonNegative(Op1
, DL
, /*Depth=*/MaxAnalysisRecursionDepth
- 1))
558 Preconditions
.emplace_back(CmpInst::ICMP_SGE
, Op1
,
559 ConstantInt::get(Op1
->getType(), 0));
561 return MergeResults(Op0
, Op1
, IsSigned
);
564 if (match(V
, m_Add(m_Value(Op0
), m_ConstantInt(CI
))) && CI
->isNegative() &&
566 Preconditions
.emplace_back(
567 CmpInst::ICMP_UGE
, Op0
,
568 ConstantInt::get(Op0
->getType(), CI
->getSExtValue() * -1));
569 return MergeResults(Op0
, CI
, true);
572 // Decompose or as an add if there are no common bits between the operands.
573 if (match(V
, m_DisjointOr(m_Value(Op0
), m_ConstantInt(CI
))))
574 return MergeResults(Op0
, CI
, IsSigned
);
576 if (match(V
, m_NUWShl(m_Value(Op1
), m_ConstantInt(CI
))) && canUseSExt(CI
)) {
577 if (CI
->getSExtValue() < 0 || CI
->getSExtValue() >= 64)
578 return {V
, IsKnownNonNegative
};
579 auto Result
= decompose(Op1
, Preconditions
, IsSigned
, DL
);
580 Result
.mul(int64_t{1} << CI
->getSExtValue());
584 if (match(V
, m_NUWMul(m_Value(Op1
), m_ConstantInt(CI
))) && canUseSExt(CI
) &&
585 (!CI
->isNegative())) {
586 auto Result
= decompose(Op1
, Preconditions
, IsSigned
, DL
);
587 Result
.mul(CI
->getSExtValue());
591 if (match(V
, m_NUWSub(m_Value(Op0
), m_Value(Op1
)))) {
592 auto ResA
= decompose(Op0
, Preconditions
, IsSigned
, DL
);
593 auto ResB
= decompose(Op1
, Preconditions
, IsSigned
, DL
);
598 return {V
, IsKnownNonNegative
};
602 ConstraintInfo::getConstraint(CmpInst::Predicate Pred
, Value
*Op0
, Value
*Op1
,
603 SmallVectorImpl
<Value
*> &NewVariables
) const {
604 assert(NewVariables
.empty() && "NewVariables must be empty when passed in");
608 // Try to convert Pred to one of ULE/SLT/SLE/SLT.
610 case CmpInst::ICMP_UGT
:
611 case CmpInst::ICMP_UGE
:
612 case CmpInst::ICMP_SGT
:
613 case CmpInst::ICMP_SGE
: {
614 Pred
= CmpInst::getSwappedPredicate(Pred
);
618 case CmpInst::ICMP_EQ
:
619 if (match(Op1
, m_Zero())) {
620 Pred
= CmpInst::ICMP_ULE
;
623 Pred
= CmpInst::ICMP_ULE
;
626 case CmpInst::ICMP_NE
:
627 if (match(Op1
, m_Zero())) {
628 Pred
= CmpInst::getSwappedPredicate(CmpInst::ICMP_UGT
);
632 Pred
= CmpInst::ICMP_ULE
;
639 if (Pred
!= CmpInst::ICMP_ULE
&& Pred
!= CmpInst::ICMP_ULT
&&
640 Pred
!= CmpInst::ICMP_SLE
&& Pred
!= CmpInst::ICMP_SLT
)
643 SmallVector
<ConditionTy
, 4> Preconditions
;
644 bool IsSigned
= CmpInst::isSigned(Pred
);
645 auto &Value2Index
= getValue2Index(IsSigned
);
646 auto ADec
= decompose(Op0
->stripPointerCastsSameRepresentation(),
647 Preconditions
, IsSigned
, DL
);
648 auto BDec
= decompose(Op1
->stripPointerCastsSameRepresentation(),
649 Preconditions
, IsSigned
, DL
);
650 int64_t Offset1
= ADec
.Offset
;
651 int64_t Offset2
= BDec
.Offset
;
654 auto &VariablesA
= ADec
.Vars
;
655 auto &VariablesB
= BDec
.Vars
;
657 // First try to look up \p V in Value2Index and NewVariables. Otherwise add a
658 // new entry to NewVariables.
659 SmallDenseMap
<Value
*, unsigned> NewIndexMap
;
660 auto GetOrAddIndex
= [&Value2Index
, &NewVariables
,
661 &NewIndexMap
](Value
*V
) -> unsigned {
662 auto V2I
= Value2Index
.find(V
);
663 if (V2I
!= Value2Index
.end())
666 NewIndexMap
.insert({V
, Value2Index
.size() + NewVariables
.size() + 1});
668 NewVariables
.push_back(V
);
669 return Insert
.first
->second
;
672 // Make sure all variables have entries in Value2Index or NewVariables.
673 for (const auto &KV
: concat
<DecompEntry
>(VariablesA
, VariablesB
))
674 GetOrAddIndex(KV
.Variable
);
676 // Build result constraint, by first adding all coefficients from A and then
677 // subtracting all coefficients from B.
679 SmallVector
<int64_t, 8>(Value2Index
.size() + NewVariables
.size() + 1, 0),
680 IsSigned
, IsEq
, IsNe
);
681 // Collect variables that are known to be positive in all uses in the
683 SmallDenseMap
<Value
*, bool> KnownNonNegativeVariables
;
684 auto &R
= Res
.Coefficients
;
685 for (const auto &KV
: VariablesA
) {
686 R
[GetOrAddIndex(KV
.Variable
)] += KV
.Coefficient
;
688 KnownNonNegativeVariables
.insert({KV
.Variable
, KV
.IsKnownNonNegative
});
689 I
.first
->second
&= KV
.IsKnownNonNegative
;
692 for (const auto &KV
: VariablesB
) {
693 if (SubOverflow(R
[GetOrAddIndex(KV
.Variable
)], KV
.Coefficient
,
694 R
[GetOrAddIndex(KV
.Variable
)]))
697 KnownNonNegativeVariables
.insert({KV
.Variable
, KV
.IsKnownNonNegative
});
698 I
.first
->second
&= KV
.IsKnownNonNegative
;
702 if (AddOverflow(Offset1
, Offset2
, OffsetSum
))
704 if (Pred
== (IsSigned
? CmpInst::ICMP_SLT
: CmpInst::ICMP_ULT
))
705 if (AddOverflow(OffsetSum
, int64_t(-1), OffsetSum
))
708 Res
.Preconditions
= std::move(Preconditions
);
710 // Remove any (Coefficient, Variable) entry where the Coefficient is 0 for new
712 while (!NewVariables
.empty()) {
713 int64_t Last
= R
.back();
717 Value
*RemovedV
= NewVariables
.pop_back_val();
718 NewIndexMap
.erase(RemovedV
);
721 // Add extra constraints for variables that are known positive.
722 for (auto &KV
: KnownNonNegativeVariables
) {
724 (!Value2Index
.contains(KV
.first
) && !NewIndexMap
.contains(KV
.first
)))
726 SmallVector
<int64_t, 8> C(Value2Index
.size() + NewVariables
.size() + 1, 0);
727 C
[GetOrAddIndex(KV
.first
)] = -1;
728 Res
.ExtraInfo
.push_back(C
);
733 ConstraintTy
ConstraintInfo::getConstraintForSolving(CmpInst::Predicate Pred
,
736 Constant
*NullC
= Constant::getNullValue(Op0
->getType());
737 // Handle trivially true compares directly to avoid adding V UGE 0 constraints
738 // for all variables in the unsigned system.
739 if ((Pred
== CmpInst::ICMP_ULE
&& Op0
== NullC
) ||
740 (Pred
== CmpInst::ICMP_UGE
&& Op1
== NullC
)) {
741 auto &Value2Index
= getValue2Index(false);
742 // Return constraint that's trivially true.
743 return ConstraintTy(SmallVector
<int64_t, 8>(Value2Index
.size(), 0), false,
747 // If both operands are known to be non-negative, change signed predicates to
748 // unsigned ones. This increases the reasoning effectiveness in combination
749 // with the signed <-> unsigned transfer logic.
750 if (CmpInst::isSigned(Pred
) &&
751 isKnownNonNegative(Op0
, DL
, /*Depth=*/MaxAnalysisRecursionDepth
- 1) &&
752 isKnownNonNegative(Op1
, DL
, /*Depth=*/MaxAnalysisRecursionDepth
- 1))
753 Pred
= CmpInst::getUnsignedPredicate(Pred
);
755 SmallVector
<Value
*> NewVariables
;
756 ConstraintTy R
= getConstraint(Pred
, Op0
, Op1
, NewVariables
);
757 if (!NewVariables
.empty())
762 bool ConstraintTy::isValid(const ConstraintInfo
&Info
) const {
763 return Coefficients
.size() > 0 &&
764 all_of(Preconditions
, [&Info
](const ConditionTy
&C
) {
765 return Info
.doesHold(C
.Pred
, C
.Op0
, C
.Op1
);
770 ConstraintTy::isImpliedBy(const ConstraintSystem
&CS
) const {
771 bool IsConditionImplied
= CS
.isConditionImplied(Coefficients
);
774 auto NegatedOrEqual
= ConstraintSystem::negateOrEqual(Coefficients
);
775 bool IsNegatedOrEqualImplied
=
776 !NegatedOrEqual
.empty() && CS
.isConditionImplied(NegatedOrEqual
);
778 // In order to check that `%a == %b` is true (equality), both conditions `%a
779 // >= %b` and `%a <= %b` must hold true. When checking for equality (`IsEq`
780 // is true), we return true if they both hold, false in the other cases.
781 if (IsConditionImplied
&& IsNegatedOrEqualImplied
)
784 auto Negated
= ConstraintSystem::negate(Coefficients
);
785 bool IsNegatedImplied
= !Negated
.empty() && CS
.isConditionImplied(Negated
);
787 auto StrictLessThan
= ConstraintSystem::toStrictLessThan(Coefficients
);
788 bool IsStrictLessThanImplied
=
789 !StrictLessThan
.empty() && CS
.isConditionImplied(StrictLessThan
);
791 // In order to check that `%a != %b` is true (non-equality), either
792 // condition `%a > %b` or `%a < %b` must hold true. When checking for
793 // non-equality (`IsNe` is true), we return true if one of the two holds,
794 // false in the other cases.
795 if (IsNegatedImplied
|| IsStrictLessThanImplied
)
801 if (IsConditionImplied
)
804 auto Negated
= ConstraintSystem::negate(Coefficients
);
805 auto IsNegatedImplied
= !Negated
.empty() && CS
.isConditionImplied(Negated
);
806 if (IsNegatedImplied
)
809 // Neither the condition nor its negated holds, did not prove anything.
813 bool ConstraintInfo::doesHold(CmpInst::Predicate Pred
, Value
*A
,
815 auto R
= getConstraintForSolving(Pred
, A
, B
);
816 return R
.isValid(*this) &&
817 getCS(R
.IsSigned
).isConditionImplied(R
.Coefficients
);
820 void ConstraintInfo::transferToOtherSystem(
821 CmpInst::Predicate Pred
, Value
*A
, Value
*B
, unsigned NumIn
,
822 unsigned NumOut
, SmallVectorImpl
<StackEntry
> &DFSInStack
) {
823 auto IsKnownNonNegative
= [this](Value
*V
) {
824 return doesHold(CmpInst::ICMP_SGE
, V
, ConstantInt::get(V
->getType(), 0)) ||
825 isKnownNonNegative(V
, DL
, /*Depth=*/MaxAnalysisRecursionDepth
- 1);
827 // Check if we can combine facts from the signed and unsigned systems to
828 // derive additional facts.
829 if (!A
->getType()->isIntegerTy())
831 // FIXME: This currently depends on the order we add facts. Ideally we
832 // would first add all known facts and only then try to add additional
837 case CmpInst::ICMP_ULT
:
838 case CmpInst::ICMP_ULE
:
839 // If B is a signed positive constant, then A >=s 0 and A <s (or <=s) B.
840 if (IsKnownNonNegative(B
)) {
841 addFact(CmpInst::ICMP_SGE
, A
, ConstantInt::get(B
->getType(), 0), NumIn
,
843 addFact(CmpInst::getSignedPredicate(Pred
), A
, B
, NumIn
, NumOut
,
847 case CmpInst::ICMP_UGE
:
848 case CmpInst::ICMP_UGT
:
849 // If A is a signed positive constant, then B >=s 0 and A >s (or >=s) B.
850 if (IsKnownNonNegative(A
)) {
851 addFact(CmpInst::ICMP_SGE
, B
, ConstantInt::get(B
->getType(), 0), NumIn
,
853 addFact(CmpInst::getSignedPredicate(Pred
), A
, B
, NumIn
, NumOut
,
857 case CmpInst::ICMP_SLT
:
858 if (IsKnownNonNegative(A
))
859 addFact(CmpInst::ICMP_ULT
, A
, B
, NumIn
, NumOut
, DFSInStack
);
861 case CmpInst::ICMP_SGT
: {
862 if (doesHold(CmpInst::ICMP_SGE
, B
, ConstantInt::get(B
->getType(), -1)))
863 addFact(CmpInst::ICMP_UGE
, A
, ConstantInt::get(B
->getType(), 0), NumIn
,
865 if (IsKnownNonNegative(B
))
866 addFact(CmpInst::ICMP_UGT
, A
, B
, NumIn
, NumOut
, DFSInStack
);
870 case CmpInst::ICMP_SGE
:
871 if (IsKnownNonNegative(B
))
872 addFact(CmpInst::ICMP_UGE
, A
, B
, NumIn
, NumOut
, DFSInStack
);
879 static void dumpConstraint(ArrayRef
<int64_t> C
,
880 const DenseMap
<Value
*, unsigned> &Value2Index
) {
881 ConstraintSystem
CS(Value2Index
);
882 CS
.addVariableRowFill(C
);
887 void State::addInfoForInductions(BasicBlock
&BB
) {
888 auto *L
= LI
.getLoopFor(&BB
);
889 if (!L
|| L
->getHeader() != &BB
)
894 CmpInst::Predicate Pred
;
896 if (!match(BB
.getTerminator(),
897 m_Br(m_ICmp(Pred
, m_Value(A
), m_Value(B
)), m_Value(), m_Value())))
899 PHINode
*PN
= dyn_cast
<PHINode
>(A
);
901 Pred
= CmpInst::getSwappedPredicate(Pred
);
903 PN
= dyn_cast
<PHINode
>(A
);
906 if (!PN
|| PN
->getParent() != &BB
|| PN
->getNumIncomingValues() != 2 ||
907 !SE
.isSCEVable(PN
->getType()))
910 BasicBlock
*InLoopSucc
= nullptr;
911 if (Pred
== CmpInst::ICMP_NE
)
912 InLoopSucc
= cast
<BranchInst
>(BB
.getTerminator())->getSuccessor(0);
913 else if (Pred
== CmpInst::ICMP_EQ
)
914 InLoopSucc
= cast
<BranchInst
>(BB
.getTerminator())->getSuccessor(1);
918 if (!L
->contains(InLoopSucc
) || !L
->isLoopExiting(&BB
) || InLoopSucc
== &BB
)
921 auto *AR
= dyn_cast_or_null
<SCEVAddRecExpr
>(SE
.getSCEV(PN
));
922 BasicBlock
*LoopPred
= L
->getLoopPredecessor();
923 if (!AR
|| AR
->getLoop() != L
|| !LoopPred
)
926 const SCEV
*StartSCEV
= AR
->getStart();
927 Value
*StartValue
= nullptr;
928 if (auto *C
= dyn_cast
<SCEVConstant
>(StartSCEV
)) {
929 StartValue
= C
->getValue();
931 StartValue
= PN
->getIncomingValueForBlock(LoopPred
);
932 assert(SE
.getSCEV(StartValue
) == StartSCEV
&& "inconsistent start value");
935 DomTreeNode
*DTN
= DT
.getNode(InLoopSucc
);
936 auto IncUnsigned
= SE
.getMonotonicPredicateType(AR
, CmpInst::ICMP_UGT
);
937 auto IncSigned
= SE
.getMonotonicPredicateType(AR
, CmpInst::ICMP_SGT
);
938 bool MonotonicallyIncreasingUnsigned
=
939 IncUnsigned
&& *IncUnsigned
== ScalarEvolution::MonotonicallyIncreasing
;
940 bool MonotonicallyIncreasingSigned
=
941 IncSigned
&& *IncSigned
== ScalarEvolution::MonotonicallyIncreasing
;
942 // If SCEV guarantees that AR does not wrap, PN >= StartValue can be added
944 if (MonotonicallyIncreasingUnsigned
)
946 FactOrCheck::getConditionFact(DTN
, CmpInst::ICMP_UGE
, PN
, StartValue
));
947 if (MonotonicallyIncreasingSigned
)
949 FactOrCheck::getConditionFact(DTN
, CmpInst::ICMP_SGE
, PN
, StartValue
));
952 if (auto *C
= dyn_cast
<SCEVConstant
>(AR
->getStepRecurrence(SE
)))
953 StepOffset
= C
->getAPInt();
957 // Make sure the bound B is loop-invariant.
958 if (!L
->isLoopInvariant(B
))
961 // Handle negative steps.
962 if (StepOffset
.isNegative()) {
963 // TODO: Extend to allow steps > -1.
964 if (!(-StepOffset
).isOne())
968 // Add StartValue >= PN conditional on B <= StartValue which guarantees that
969 // the loop exits before wrapping with a step of -1.
970 WorkList
.push_back(FactOrCheck::getConditionFact(
971 DTN
, CmpInst::ICMP_UGE
, StartValue
, PN
,
972 ConditionTy(CmpInst::ICMP_ULE
, B
, StartValue
)));
973 WorkList
.push_back(FactOrCheck::getConditionFact(
974 DTN
, CmpInst::ICMP_SGE
, StartValue
, PN
,
975 ConditionTy(CmpInst::ICMP_SLE
, B
, StartValue
)));
976 // Add PN > B conditional on B <= StartValue which guarantees that the loop
977 // exits when reaching B with a step of -1.
978 WorkList
.push_back(FactOrCheck::getConditionFact(
979 DTN
, CmpInst::ICMP_UGT
, PN
, B
,
980 ConditionTy(CmpInst::ICMP_ULE
, B
, StartValue
)));
981 WorkList
.push_back(FactOrCheck::getConditionFact(
982 DTN
, CmpInst::ICMP_SGT
, PN
, B
,
983 ConditionTy(CmpInst::ICMP_SLE
, B
, StartValue
)));
987 // Make sure AR either steps by 1 or that the value we compare against is a
988 // GEP based on the same start value and all offsets are a multiple of the
989 // step size, to guarantee that the induction will reach the value.
990 if (StepOffset
.isZero() || StepOffset
.isNegative())
993 if (!StepOffset
.isOne()) {
994 // Check whether B-Start is known to be a multiple of StepOffset.
995 const SCEV
*BMinusStart
= SE
.getMinusSCEV(SE
.getSCEV(B
), StartSCEV
);
996 if (isa
<SCEVCouldNotCompute
>(BMinusStart
) ||
997 !SE
.getConstantMultiple(BMinusStart
).urem(StepOffset
).isZero())
1001 // AR may wrap. Add PN >= StartValue conditional on StartValue <= B which
1002 // guarantees that the loop exits before wrapping in combination with the
1003 // restrictions on B and the step above.
1004 if (!MonotonicallyIncreasingUnsigned
)
1005 WorkList
.push_back(FactOrCheck::getConditionFact(
1006 DTN
, CmpInst::ICMP_UGE
, PN
, StartValue
,
1007 ConditionTy(CmpInst::ICMP_ULE
, StartValue
, B
)));
1008 if (!MonotonicallyIncreasingSigned
)
1009 WorkList
.push_back(FactOrCheck::getConditionFact(
1010 DTN
, CmpInst::ICMP_SGE
, PN
, StartValue
,
1011 ConditionTy(CmpInst::ICMP_SLE
, StartValue
, B
)));
1013 WorkList
.push_back(FactOrCheck::getConditionFact(
1014 DTN
, CmpInst::ICMP_ULT
, PN
, B
,
1015 ConditionTy(CmpInst::ICMP_ULE
, StartValue
, B
)));
1016 WorkList
.push_back(FactOrCheck::getConditionFact(
1017 DTN
, CmpInst::ICMP_SLT
, PN
, B
,
1018 ConditionTy(CmpInst::ICMP_SLE
, StartValue
, B
)));
1021 void State::addInfoFor(BasicBlock
&BB
) {
1022 addInfoForInductions(BB
);
1024 // True as long as long as the current instruction is guaranteed to execute.
1025 bool GuaranteedToExecute
= true;
1026 // Queue conditions and assumes.
1027 for (Instruction
&I
: BB
) {
1028 if (auto Cmp
= dyn_cast
<ICmpInst
>(&I
)) {
1029 for (Use
&U
: Cmp
->uses()) {
1030 auto *UserI
= getContextInstForUse(U
);
1031 auto *DTN
= DT
.getNode(UserI
->getParent());
1034 WorkList
.push_back(FactOrCheck::getCheck(DTN
, &U
));
1039 auto *II
= dyn_cast
<IntrinsicInst
>(&I
);
1040 Intrinsic::ID ID
= II
? II
->getIntrinsicID() : Intrinsic::not_intrinsic
;
1042 case Intrinsic::assume
: {
1044 CmpInst::Predicate Pred
;
1045 if (!match(I
.getOperand(0), m_ICmp(Pred
, m_Value(A
), m_Value(B
))))
1047 if (GuaranteedToExecute
) {
1048 // The assume is guaranteed to execute when BB is entered, hence Cond
1049 // holds on entry to BB.
1050 WorkList
.emplace_back(FactOrCheck::getConditionFact(
1051 DT
.getNode(I
.getParent()), Pred
, A
, B
));
1053 WorkList
.emplace_back(
1054 FactOrCheck::getInstFact(DT
.getNode(I
.getParent()), &I
));
1058 // Enqueue ssub_with_overflow for simplification.
1059 case Intrinsic::ssub_with_overflow
:
1061 FactOrCheck::getCheck(DT
.getNode(&BB
), cast
<CallInst
>(&I
)));
1063 // Enqueue the intrinsics to add extra info.
1064 case Intrinsic::umin
:
1065 case Intrinsic::umax
:
1066 case Intrinsic::smin
:
1067 case Intrinsic::smax
:
1068 // TODO: Check if it is possible to instead only added the min/max facts
1069 // when simplifying uses of the min/max intrinsics.
1070 if (!isGuaranteedNotToBePoison(&I
))
1073 case Intrinsic::abs
:
1074 WorkList
.push_back(FactOrCheck::getInstFact(DT
.getNode(&BB
), &I
));
1078 GuaranteedToExecute
&= isGuaranteedToTransferExecutionToSuccessor(&I
);
1081 if (auto *Switch
= dyn_cast
<SwitchInst
>(BB
.getTerminator())) {
1082 for (auto &Case
: Switch
->cases()) {
1083 BasicBlock
*Succ
= Case
.getCaseSuccessor();
1084 Value
*V
= Case
.getCaseValue();
1085 if (!canAddSuccessor(BB
, Succ
))
1087 WorkList
.emplace_back(FactOrCheck::getConditionFact(
1088 DT
.getNode(Succ
), CmpInst::ICMP_EQ
, Switch
->getCondition(), V
));
1093 auto *Br
= dyn_cast
<BranchInst
>(BB
.getTerminator());
1094 if (!Br
|| !Br
->isConditional())
1097 Value
*Cond
= Br
->getCondition();
1099 // If the condition is a chain of ORs/AND and the successor only has the
1100 // current block as predecessor, queue conditions for the successor.
1102 if (match(Cond
, m_LogicalOr(m_Value(Op0
), m_Value(Op1
))) ||
1103 match(Cond
, m_LogicalAnd(m_Value(Op0
), m_Value(Op1
)))) {
1104 bool IsOr
= match(Cond
, m_LogicalOr());
1105 bool IsAnd
= match(Cond
, m_LogicalAnd());
1106 // If there's a select that matches both AND and OR, we need to commit to
1107 // one of the options. Arbitrarily pick OR.
1111 BasicBlock
*Successor
= Br
->getSuccessor(IsOr
? 1 : 0);
1112 if (canAddSuccessor(BB
, Successor
)) {
1113 SmallVector
<Value
*> CondWorkList
;
1114 SmallPtrSet
<Value
*, 8> SeenCond
;
1115 auto QueueValue
= [&CondWorkList
, &SeenCond
](Value
*V
) {
1116 if (SeenCond
.insert(V
).second
)
1117 CondWorkList
.push_back(V
);
1121 while (!CondWorkList
.empty()) {
1122 Value
*Cur
= CondWorkList
.pop_back_val();
1123 if (auto *Cmp
= dyn_cast
<ICmpInst
>(Cur
)) {
1124 WorkList
.emplace_back(FactOrCheck::getConditionFact(
1125 DT
.getNode(Successor
),
1126 IsOr
? CmpInst::getInversePredicate(Cmp
->getPredicate())
1127 : Cmp
->getPredicate(),
1128 Cmp
->getOperand(0), Cmp
->getOperand(1)));
1131 if (IsOr
&& match(Cur
, m_LogicalOr(m_Value(Op0
), m_Value(Op1
)))) {
1136 if (IsAnd
&& match(Cur
, m_LogicalAnd(m_Value(Op0
), m_Value(Op1
)))) {
1146 auto *CmpI
= dyn_cast
<ICmpInst
>(Br
->getCondition());
1149 if (canAddSuccessor(BB
, Br
->getSuccessor(0)))
1150 WorkList
.emplace_back(FactOrCheck::getConditionFact(
1151 DT
.getNode(Br
->getSuccessor(0)), CmpI
->getPredicate(),
1152 CmpI
->getOperand(0), CmpI
->getOperand(1)));
1153 if (canAddSuccessor(BB
, Br
->getSuccessor(1)))
1154 WorkList
.emplace_back(FactOrCheck::getConditionFact(
1155 DT
.getNode(Br
->getSuccessor(1)),
1156 CmpInst::getInversePredicate(CmpI
->getPredicate()), CmpI
->getOperand(0),
1157 CmpI
->getOperand(1)));
1161 static void dumpUnpackedICmp(raw_ostream
&OS
, ICmpInst::Predicate Pred
,
1162 Value
*LHS
, Value
*RHS
) {
1163 OS
<< "icmp " << Pred
<< ' ';
1164 LHS
->printAsOperand(OS
, /*PrintType=*/true);
1166 RHS
->printAsOperand(OS
, /*PrintType=*/false);
1171 /// Helper to keep track of a condition and if it should be treated as negated
1172 /// for reproducer construction.
1173 /// Pred == Predicate::BAD_ICMP_PREDICATE indicates that this entry is a
1174 /// placeholder to keep the ReproducerCondStack in sync with DFSInStack.
1175 struct ReproducerEntry
{
1176 ICmpInst::Predicate Pred
;
1180 ReproducerEntry(ICmpInst::Predicate Pred
, Value
*LHS
, Value
*RHS
)
1181 : Pred(Pred
), LHS(LHS
), RHS(RHS
) {}
1185 /// Helper function to generate a reproducer function for simplifying \p Cond.
1186 /// The reproducer function contains a series of @llvm.assume calls, one for
1187 /// each condition in \p Stack. For each condition, the operand instruction are
1188 /// cloned until we reach operands that have an entry in \p Value2Index. Those
1189 /// will then be added as function arguments. \p DT is used to order cloned
1190 /// instructions. The reproducer function will get added to \p M, if it is
1191 /// non-null. Otherwise no reproducer function is generated.
1192 static void generateReproducer(CmpInst
*Cond
, Module
*M
,
1193 ArrayRef
<ReproducerEntry
> Stack
,
1194 ConstraintInfo
&Info
, DominatorTree
&DT
) {
1198 LLVMContext
&Ctx
= Cond
->getContext();
1200 LLVM_DEBUG(dbgs() << "Creating reproducer for " << *Cond
<< "\n");
1202 ValueToValueMapTy Old2New
;
1203 SmallVector
<Value
*> Args
;
1204 SmallPtrSet
<Value
*, 8> Seen
;
1205 // Traverse Cond and its operands recursively until we reach a value that's in
1206 // Value2Index or not an instruction, or not a operation that
1207 // ConstraintElimination can decompose. Such values will be considered as
1208 // external inputs to the reproducer, they are collected and added as function
1210 auto CollectArguments
= [&](ArrayRef
<Value
*> Ops
, bool IsSigned
) {
1211 auto &Value2Index
= Info
.getValue2Index(IsSigned
);
1212 SmallVector
<Value
*, 4> WorkList(Ops
);
1213 while (!WorkList
.empty()) {
1214 Value
*V
= WorkList
.pop_back_val();
1215 if (!Seen
.insert(V
).second
)
1217 if (Old2New
.find(V
) != Old2New
.end())
1219 if (isa
<Constant
>(V
))
1222 auto *I
= dyn_cast
<Instruction
>(V
);
1223 if (Value2Index
.contains(V
) || !I
||
1224 !isa
<CmpInst
, BinaryOperator
, GEPOperator
, CastInst
>(V
)) {
1227 LLVM_DEBUG(dbgs() << " found external input " << *V
<< "\n");
1229 append_range(WorkList
, I
->operands());
1234 for (auto &Entry
: Stack
)
1235 if (Entry
.Pred
!= ICmpInst::BAD_ICMP_PREDICATE
)
1236 CollectArguments({Entry
.LHS
, Entry
.RHS
}, ICmpInst::isSigned(Entry
.Pred
));
1237 CollectArguments(Cond
, ICmpInst::isSigned(Cond
->getPredicate()));
1239 SmallVector
<Type
*> ParamTys
;
1240 for (auto *P
: Args
)
1241 ParamTys
.push_back(P
->getType());
1243 FunctionType
*FTy
= FunctionType::get(Cond
->getType(), ParamTys
,
1244 /*isVarArg=*/false);
1245 Function
*F
= Function::Create(FTy
, Function::ExternalLinkage
,
1246 Cond
->getModule()->getName() +
1247 Cond
->getFunction()->getName() + "repro",
1249 // Add arguments to the reproducer function for each external value collected.
1250 for (unsigned I
= 0; I
< Args
.size(); ++I
) {
1251 F
->getArg(I
)->setName(Args
[I
]->getName());
1252 Old2New
[Args
[I
]] = F
->getArg(I
);
1255 BasicBlock
*Entry
= BasicBlock::Create(Ctx
, "entry", F
);
1256 IRBuilder
<> Builder(Entry
);
1257 Builder
.CreateRet(Builder
.getTrue());
1258 Builder
.SetInsertPoint(Entry
->getTerminator());
1260 // Clone instructions in \p Ops and their operands recursively until reaching
1261 // an value in Value2Index (external input to the reproducer). Update Old2New
1262 // mapping for the original and cloned instructions. Sort instructions to
1263 // clone by dominance, then insert the cloned instructions in the function.
1264 auto CloneInstructions
= [&](ArrayRef
<Value
*> Ops
, bool IsSigned
) {
1265 SmallVector
<Value
*, 4> WorkList(Ops
);
1266 SmallVector
<Instruction
*> ToClone
;
1267 auto &Value2Index
= Info
.getValue2Index(IsSigned
);
1268 while (!WorkList
.empty()) {
1269 Value
*V
= WorkList
.pop_back_val();
1270 if (Old2New
.find(V
) != Old2New
.end())
1273 auto *I
= dyn_cast
<Instruction
>(V
);
1274 if (!Value2Index
.contains(V
) && I
) {
1275 Old2New
[V
] = nullptr;
1276 ToClone
.push_back(I
);
1277 append_range(WorkList
, I
->operands());
1282 [&DT
](Instruction
*A
, Instruction
*B
) { return DT
.dominates(A
, B
); });
1283 for (Instruction
*I
: ToClone
) {
1284 Instruction
*Cloned
= I
->clone();
1285 Old2New
[I
] = Cloned
;
1286 Old2New
[I
]->setName(I
->getName());
1287 Cloned
->insertBefore(&*Builder
.GetInsertPoint());
1288 Cloned
->dropUnknownNonDebugMetadata();
1289 Cloned
->setDebugLoc({});
1293 // Materialize the assumptions for the reproducer using the entries in Stack.
1294 // That is, first clone the operands of the condition recursively until we
1295 // reach an external input to the reproducer and add them to the reproducer
1296 // function. Then add an ICmp for the condition (with the inverse predicate if
1297 // the entry is negated) and an assert using the ICmp.
1298 for (auto &Entry
: Stack
) {
1299 if (Entry
.Pred
== ICmpInst::BAD_ICMP_PREDICATE
)
1302 LLVM_DEBUG(dbgs() << " Materializing assumption ";
1303 dumpUnpackedICmp(dbgs(), Entry
.Pred
, Entry
.LHS
, Entry
.RHS
);
1305 CloneInstructions({Entry
.LHS
, Entry
.RHS
}, CmpInst::isSigned(Entry
.Pred
));
1307 auto *Cmp
= Builder
.CreateICmp(Entry
.Pred
, Entry
.LHS
, Entry
.RHS
);
1308 Builder
.CreateAssumption(Cmp
);
1311 // Finally, clone the condition to reproduce and remap instruction operands in
1312 // the reproducer using Old2New.
1313 CloneInstructions(Cond
, CmpInst::isSigned(Cond
->getPredicate()));
1314 Entry
->getTerminator()->setOperand(0, Cond
);
1315 remapInstructionsInBlocks({Entry
}, Old2New
);
1317 assert(!verifyFunction(*F
, &dbgs()));
1320 static std::optional
<bool> checkCondition(CmpInst::Predicate Pred
, Value
*A
,
1321 Value
*B
, Instruction
*CheckInst
,
1322 ConstraintInfo
&Info
) {
1323 LLVM_DEBUG(dbgs() << "Checking " << *CheckInst
<< "\n");
1325 auto R
= Info
.getConstraintForSolving(Pred
, A
, B
);
1326 if (R
.empty() || !R
.isValid(Info
)){
1327 LLVM_DEBUG(dbgs() << " failed to decompose condition\n");
1328 return std::nullopt
;
1331 auto &CSToUse
= Info
.getCS(R
.IsSigned
);
1333 // If there was extra information collected during decomposition, apply
1334 // it now and remove it immediately once we are done with reasoning
1335 // about the constraint.
1336 for (auto &Row
: R
.ExtraInfo
)
1337 CSToUse
.addVariableRow(Row
);
1338 auto InfoRestorer
= make_scope_exit([&]() {
1339 for (unsigned I
= 0; I
< R
.ExtraInfo
.size(); ++I
)
1340 CSToUse
.popLastConstraint();
1343 if (auto ImpliedCondition
= R
.isImpliedBy(CSToUse
)) {
1344 if (!DebugCounter::shouldExecute(EliminatedCounter
))
1345 return std::nullopt
;
1348 dbgs() << "Condition ";
1350 dbgs(), *ImpliedCondition
? Pred
: CmpInst::getInversePredicate(Pred
),
1352 dbgs() << " implied by dominating constraints\n";
1355 return ImpliedCondition
;
1358 return std::nullopt
;
1361 static bool checkAndReplaceCondition(
1362 CmpInst
*Cmp
, ConstraintInfo
&Info
, unsigned NumIn
, unsigned NumOut
,
1363 Instruction
*ContextInst
, Module
*ReproducerModule
,
1364 ArrayRef
<ReproducerEntry
> ReproducerCondStack
, DominatorTree
&DT
,
1365 SmallVectorImpl
<Instruction
*> &ToRemove
) {
1366 auto ReplaceCmpWithConstant
= [&](CmpInst
*Cmp
, bool IsTrue
) {
1367 generateReproducer(Cmp
, ReproducerModule
, ReproducerCondStack
, Info
, DT
);
1368 Constant
*ConstantC
= ConstantInt::getBool(
1369 CmpInst::makeCmpResultType(Cmp
->getType()), IsTrue
);
1370 Cmp
->replaceUsesWithIf(ConstantC
, [&DT
, NumIn
, NumOut
,
1371 ContextInst
](Use
&U
) {
1372 auto *UserI
= getContextInstForUse(U
);
1373 auto *DTN
= DT
.getNode(UserI
->getParent());
1374 if (!DTN
|| DTN
->getDFSNumIn() < NumIn
|| DTN
->getDFSNumOut() > NumOut
)
1376 if (UserI
->getParent() == ContextInst
->getParent() &&
1377 UserI
->comesBefore(ContextInst
))
1380 // Conditions in an assume trivially simplify to true. Skip uses
1381 // in assume calls to not destroy the available information.
1382 auto *II
= dyn_cast
<IntrinsicInst
>(U
.getUser());
1383 return !II
|| II
->getIntrinsicID() != Intrinsic::assume
;
1386 if (Cmp
->use_empty())
1387 ToRemove
.push_back(Cmp
);
1391 if (auto ImpliedCondition
=
1392 checkCondition(Cmp
->getPredicate(), Cmp
->getOperand(0),
1393 Cmp
->getOperand(1), Cmp
, Info
))
1394 return ReplaceCmpWithConstant(Cmp
, *ImpliedCondition
);
1399 removeEntryFromStack(const StackEntry
&E
, ConstraintInfo
&Info
,
1400 Module
*ReproducerModule
,
1401 SmallVectorImpl
<ReproducerEntry
> &ReproducerCondStack
,
1402 SmallVectorImpl
<StackEntry
> &DFSInStack
) {
1403 Info
.popLastConstraint(E
.IsSigned
);
1404 // Remove variables in the system that went out of scope.
1405 auto &Mapping
= Info
.getValue2Index(E
.IsSigned
);
1406 for (Value
*V
: E
.ValuesToRelease
)
1408 Info
.popLastNVariables(E
.IsSigned
, E
.ValuesToRelease
.size());
1409 DFSInStack
.pop_back();
1410 if (ReproducerModule
)
1411 ReproducerCondStack
.pop_back();
1414 /// Check if either the first condition of an AND or OR is implied by the
1415 /// (negated in case of OR) second condition or vice versa.
1416 static bool checkOrAndOpImpliedByOther(
1417 FactOrCheck
&CB
, ConstraintInfo
&Info
, Module
*ReproducerModule
,
1418 SmallVectorImpl
<ReproducerEntry
> &ReproducerCondStack
,
1419 SmallVectorImpl
<StackEntry
> &DFSInStack
) {
1421 CmpInst::Predicate Pred
;
1423 Instruction
*JoinOp
= CB
.getContextInst();
1424 CmpInst
*CmpToCheck
= cast
<CmpInst
>(CB
.getInstructionToSimplify());
1425 unsigned OtherOpIdx
= JoinOp
->getOperand(0) == CmpToCheck
? 1 : 0;
1427 // Don't try to simplify the first condition of a select by the second, as
1428 // this may make the select more poisonous than the original one.
1429 // TODO: check if the first operand may be poison.
1430 if (OtherOpIdx
!= 0 && isa
<SelectInst
>(JoinOp
))
1433 if (!match(JoinOp
->getOperand(OtherOpIdx
),
1434 m_ICmp(Pred
, m_Value(A
), m_Value(B
))))
1437 // For OR, check if the negated condition implies CmpToCheck.
1438 bool IsOr
= match(JoinOp
, m_LogicalOr());
1440 Pred
= CmpInst::getInversePredicate(Pred
);
1442 // Optimistically add fact from first condition.
1443 unsigned OldSize
= DFSInStack
.size();
1444 Info
.addFact(Pred
, A
, B
, CB
.NumIn
, CB
.NumOut
, DFSInStack
);
1445 if (OldSize
== DFSInStack
.size())
1448 bool Changed
= false;
1449 // Check if the second condition can be simplified now.
1450 if (auto ImpliedCondition
=
1451 checkCondition(CmpToCheck
->getPredicate(), CmpToCheck
->getOperand(0),
1452 CmpToCheck
->getOperand(1), CmpToCheck
, Info
)) {
1453 if (IsOr
&& isa
<SelectInst
>(JoinOp
)) {
1455 OtherOpIdx
== 0 ? 2 : 0,
1456 ConstantInt::getBool(JoinOp
->getType(), *ImpliedCondition
));
1460 ConstantInt::getBool(JoinOp
->getType(), *ImpliedCondition
));
1465 // Remove entries again.
1466 while (OldSize
< DFSInStack
.size()) {
1467 StackEntry E
= DFSInStack
.back();
1468 removeEntryFromStack(E
, Info
, ReproducerModule
, ReproducerCondStack
,
1474 void ConstraintInfo::addFact(CmpInst::Predicate Pred
, Value
*A
, Value
*B
,
1475 unsigned NumIn
, unsigned NumOut
,
1476 SmallVectorImpl
<StackEntry
> &DFSInStack
) {
1477 // If the constraint has a pre-condition, skip the constraint if it does not
1479 SmallVector
<Value
*> NewVariables
;
1480 auto R
= getConstraint(Pred
, A
, B
, NewVariables
);
1482 // TODO: Support non-equality for facts as well.
1483 if (!R
.isValid(*this) || R
.isNe())
1486 LLVM_DEBUG(dbgs() << "Adding '"; dumpUnpackedICmp(dbgs(), Pred
, A
, B
);
1489 auto &CSToUse
= getCS(R
.IsSigned
);
1490 if (R
.Coefficients
.empty())
1493 Added
|= CSToUse
.addVariableRowFill(R
.Coefficients
);
1495 // If R has been added to the system, add the new variables and queue it for
1496 // removal once it goes out-of-scope.
1498 SmallVector
<Value
*, 2> ValuesToRelease
;
1499 auto &Value2Index
= getValue2Index(R
.IsSigned
);
1500 for (Value
*V
: NewVariables
) {
1501 Value2Index
.insert({V
, Value2Index
.size() + 1});
1502 ValuesToRelease
.push_back(V
);
1506 dbgs() << " constraint: ";
1507 dumpConstraint(R
.Coefficients
, getValue2Index(R
.IsSigned
));
1511 DFSInStack
.emplace_back(NumIn
, NumOut
, R
.IsSigned
,
1512 std::move(ValuesToRelease
));
1515 for (Value
*V
: NewVariables
) {
1516 ConstraintTy
VarPos(SmallVector
<int64_t, 8>(Value2Index
.size() + 1, 0),
1517 false, false, false);
1518 VarPos
.Coefficients
[Value2Index
[V
]] = -1;
1519 CSToUse
.addVariableRow(VarPos
.Coefficients
);
1520 DFSInStack
.emplace_back(NumIn
, NumOut
, R
.IsSigned
,
1521 SmallVector
<Value
*, 2>());
1526 // Also add the inverted constraint for equality constraints.
1527 for (auto &Coeff
: R
.Coefficients
)
1529 CSToUse
.addVariableRowFill(R
.Coefficients
);
1531 DFSInStack
.emplace_back(NumIn
, NumOut
, R
.IsSigned
,
1532 SmallVector
<Value
*, 2>());
1537 static bool replaceSubOverflowUses(IntrinsicInst
*II
, Value
*A
, Value
*B
,
1538 SmallVectorImpl
<Instruction
*> &ToRemove
) {
1539 bool Changed
= false;
1540 IRBuilder
<> Builder(II
->getParent(), II
->getIterator());
1541 Value
*Sub
= nullptr;
1542 for (User
*U
: make_early_inc_range(II
->users())) {
1543 if (match(U
, m_ExtractValue
<0>(m_Value()))) {
1545 Sub
= Builder
.CreateSub(A
, B
);
1546 U
->replaceAllUsesWith(Sub
);
1548 } else if (match(U
, m_ExtractValue
<1>(m_Value()))) {
1549 U
->replaceAllUsesWith(Builder
.getFalse());
1554 if (U
->use_empty()) {
1555 auto *I
= cast
<Instruction
>(U
);
1556 ToRemove
.push_back(I
);
1557 I
->setOperand(0, PoisonValue::get(II
->getType()));
1562 if (II
->use_empty()) {
1563 II
->eraseFromParent();
1570 tryToSimplifyOverflowMath(IntrinsicInst
*II
, ConstraintInfo
&Info
,
1571 SmallVectorImpl
<Instruction
*> &ToRemove
) {
1572 auto DoesConditionHold
= [](CmpInst::Predicate Pred
, Value
*A
, Value
*B
,
1573 ConstraintInfo
&Info
) {
1574 auto R
= Info
.getConstraintForSolving(Pred
, A
, B
);
1575 if (R
.size() < 2 || !R
.isValid(Info
))
1578 auto &CSToUse
= Info
.getCS(R
.IsSigned
);
1579 return CSToUse
.isConditionImplied(R
.Coefficients
);
1582 bool Changed
= false;
1583 if (II
->getIntrinsicID() == Intrinsic::ssub_with_overflow
) {
1584 // If A s>= B && B s>= 0, ssub.with.overflow(a, b) should not overflow and
1585 // can be simplified to a regular sub.
1586 Value
*A
= II
->getArgOperand(0);
1587 Value
*B
= II
->getArgOperand(1);
1588 if (!DoesConditionHold(CmpInst::ICMP_SGE
, A
, B
, Info
) ||
1589 !DoesConditionHold(CmpInst::ICMP_SGE
, B
,
1590 ConstantInt::get(A
->getType(), 0), Info
))
1592 Changed
= replaceSubOverflowUses(II
, A
, B
, ToRemove
);
1597 static bool eliminateConstraints(Function
&F
, DominatorTree
&DT
, LoopInfo
&LI
,
1598 ScalarEvolution
&SE
,
1599 OptimizationRemarkEmitter
&ORE
) {
1600 bool Changed
= false;
1601 DT
.updateDFSNumbers();
1602 SmallVector
<Value
*> FunctionArgs
;
1603 for (Value
&Arg
: F
.args())
1604 FunctionArgs
.push_back(&Arg
);
1605 ConstraintInfo
Info(F
.getParent()->getDataLayout(), FunctionArgs
);
1606 State
S(DT
, LI
, SE
);
1607 std::unique_ptr
<Module
> ReproducerModule(
1608 DumpReproducers
? new Module(F
.getName(), F
.getContext()) : nullptr);
1610 // First, collect conditions implied by branches and blocks with their
1611 // Dominator DFS in and out numbers.
1612 for (BasicBlock
&BB
: F
) {
1613 if (!DT
.getNode(&BB
))
1618 // Next, sort worklist by dominance, so that dominating conditions to check
1619 // and facts come before conditions and facts dominated by them. If a
1620 // condition to check and a fact have the same numbers, conditional facts come
1621 // first. Assume facts and checks are ordered according to their relative
1622 // order in the containing basic block. Also make sure conditions with
1623 // constant operands come before conditions without constant operands. This
1624 // increases the effectiveness of the current signed <-> unsigned fact
1626 stable_sort(S
.WorkList
, [](const FactOrCheck
&A
, const FactOrCheck
&B
) {
1627 auto HasNoConstOp
= [](const FactOrCheck
&B
) {
1628 Value
*V0
= B
.isConditionFact() ? B
.Cond
.Op0
: B
.Inst
->getOperand(0);
1629 Value
*V1
= B
.isConditionFact() ? B
.Cond
.Op1
: B
.Inst
->getOperand(1);
1630 return !isa
<ConstantInt
>(V0
) && !isa
<ConstantInt
>(V1
);
1632 // If both entries have the same In numbers, conditional facts come first.
1633 // Otherwise use the relative order in the basic block.
1634 if (A
.NumIn
== B
.NumIn
) {
1635 if (A
.isConditionFact() && B
.isConditionFact()) {
1636 bool NoConstOpA
= HasNoConstOp(A
);
1637 bool NoConstOpB
= HasNoConstOp(B
);
1638 return NoConstOpA
< NoConstOpB
;
1640 if (A
.isConditionFact())
1642 if (B
.isConditionFact())
1644 auto *InstA
= A
.getContextInst();
1645 auto *InstB
= B
.getContextInst();
1646 return InstA
->comesBefore(InstB
);
1648 return A
.NumIn
< B
.NumIn
;
1651 SmallVector
<Instruction
*> ToRemove
;
1653 // Finally, process ordered worklist and eliminate implied conditions.
1654 SmallVector
<StackEntry
, 16> DFSInStack
;
1655 SmallVector
<ReproducerEntry
> ReproducerCondStack
;
1656 for (FactOrCheck
&CB
: S
.WorkList
) {
1657 // First, pop entries from the stack that are out-of-scope for CB. Remove
1658 // the corresponding entry from the constraint system.
1659 while (!DFSInStack
.empty()) {
1660 auto &E
= DFSInStack
.back();
1661 LLVM_DEBUG(dbgs() << "Top of stack : " << E
.NumIn
<< " " << E
.NumOut
1663 LLVM_DEBUG(dbgs() << "CB: " << CB
.NumIn
<< " " << CB
.NumOut
<< "\n");
1664 assert(E
.NumIn
<= CB
.NumIn
);
1665 if (CB
.NumOut
<= E
.NumOut
)
1668 dbgs() << "Removing ";
1669 dumpConstraint(Info
.getCS(E
.IsSigned
).getLastConstraint(),
1670 Info
.getValue2Index(E
.IsSigned
));
1673 removeEntryFromStack(E
, Info
, ReproducerModule
.get(), ReproducerCondStack
,
1677 // For a block, check if any CmpInsts become known based on the current set
1680 Instruction
*Inst
= CB
.getInstructionToSimplify();
1683 LLVM_DEBUG(dbgs() << "Processing condition to simplify: " << *Inst
1685 if (auto *II
= dyn_cast
<WithOverflowInst
>(Inst
)) {
1686 Changed
|= tryToSimplifyOverflowMath(II
, Info
, ToRemove
);
1687 } else if (auto *Cmp
= dyn_cast
<ICmpInst
>(Inst
)) {
1688 bool Simplified
= checkAndReplaceCondition(
1689 Cmp
, Info
, CB
.NumIn
, CB
.NumOut
, CB
.getContextInst(),
1690 ReproducerModule
.get(), ReproducerCondStack
, S
.DT
, ToRemove
);
1692 match(CB
.getContextInst(), m_LogicalOp(m_Value(), m_Value()))) {
1694 checkOrAndOpImpliedByOther(CB
, Info
, ReproducerModule
.get(),
1695 ReproducerCondStack
, DFSInStack
);
1697 Changed
|= Simplified
;
1702 auto AddFact
= [&](CmpInst::Predicate Pred
, Value
*A
, Value
*B
) {
1703 LLVM_DEBUG(dbgs() << "Processing fact to add to the system: ";
1704 dumpUnpackedICmp(dbgs(), Pred
, A
, B
); dbgs() << "\n");
1705 if (Info
.getCS(CmpInst::isSigned(Pred
)).size() > MaxRows
) {
1708 << "Skip adding constraint because system has too many rows.\n");
1712 Info
.addFact(Pred
, A
, B
, CB
.NumIn
, CB
.NumOut
, DFSInStack
);
1713 if (ReproducerModule
&& DFSInStack
.size() > ReproducerCondStack
.size())
1714 ReproducerCondStack
.emplace_back(Pred
, A
, B
);
1716 Info
.transferToOtherSystem(Pred
, A
, B
, CB
.NumIn
, CB
.NumOut
, DFSInStack
);
1717 if (ReproducerModule
&& DFSInStack
.size() > ReproducerCondStack
.size()) {
1718 // Add dummy entries to ReproducerCondStack to keep it in sync with
1720 for (unsigned I
= 0,
1721 E
= (DFSInStack
.size() - ReproducerCondStack
.size());
1723 ReproducerCondStack
.emplace_back(ICmpInst::BAD_ICMP_PREDICATE
,
1729 ICmpInst::Predicate Pred
;
1730 if (!CB
.isConditionFact()) {
1732 if (match(CB
.Inst
, m_Intrinsic
<Intrinsic::abs
>(m_Value(X
)))) {
1733 // TODO: Add CB.Inst >= 0 fact.
1734 AddFact(CmpInst::ICMP_SGE
, CB
.Inst
, X
);
1738 if (auto *MinMax
= dyn_cast
<MinMaxIntrinsic
>(CB
.Inst
)) {
1739 Pred
= ICmpInst::getNonStrictPredicate(MinMax
->getPredicate());
1740 AddFact(Pred
, MinMax
, MinMax
->getLHS());
1741 AddFact(Pred
, MinMax
, MinMax
->getRHS());
1746 Value
*A
= nullptr, *B
= nullptr;
1747 if (CB
.isConditionFact()) {
1748 Pred
= CB
.Cond
.Pred
;
1751 if (CB
.DoesHold
.Pred
!= CmpInst::BAD_ICMP_PREDICATE
&&
1752 !Info
.doesHold(CB
.DoesHold
.Pred
, CB
.DoesHold
.Op0
, CB
.DoesHold
.Op1
)) {
1754 dbgs() << "Not adding fact ";
1755 dumpUnpackedICmp(dbgs(), Pred
, A
, B
);
1756 dbgs() << " because precondition ";
1757 dumpUnpackedICmp(dbgs(), CB
.DoesHold
.Pred
, CB
.DoesHold
.Op0
,
1759 dbgs() << " does not hold.\n";
1764 bool Matched
= match(CB
.Inst
, m_Intrinsic
<Intrinsic::assume
>(
1765 m_ICmp(Pred
, m_Value(A
), m_Value(B
))));
1767 assert(Matched
&& "Must have an assume intrinsic with a icmp operand");
1769 AddFact(Pred
, A
, B
);
1772 if (ReproducerModule
&& !ReproducerModule
->functions().empty()) {
1774 raw_string_ostream
StringS(S
);
1775 ReproducerModule
->print(StringS
, nullptr);
1777 OptimizationRemark
Rem(DEBUG_TYPE
, "Reproducer", &F
);
1778 Rem
<< ore::NV("module") << S
;
1783 unsigned SignedEntries
=
1784 count_if(DFSInStack
, [](const StackEntry
&E
) { return E
.IsSigned
; });
1785 assert(Info
.getCS(false).size() - FunctionArgs
.size() ==
1786 DFSInStack
.size() - SignedEntries
&&
1787 "updates to CS and DFSInStack are out of sync");
1788 assert(Info
.getCS(true).size() == SignedEntries
&&
1789 "updates to CS and DFSInStack are out of sync");
1792 for (Instruction
*I
: ToRemove
)
1793 I
->eraseFromParent();
1797 PreservedAnalyses
ConstraintEliminationPass::run(Function
&F
,
1798 FunctionAnalysisManager
&AM
) {
1799 auto &DT
= AM
.getResult
<DominatorTreeAnalysis
>(F
);
1800 auto &LI
= AM
.getResult
<LoopAnalysis
>(F
);
1801 auto &SE
= AM
.getResult
<ScalarEvolutionAnalysis
>(F
);
1802 auto &ORE
= AM
.getResult
<OptimizationRemarkEmitterAnalysis
>(F
);
1803 if (!eliminateConstraints(F
, DT
, LI
, SE
, ORE
))
1804 return PreservedAnalyses::all();
1806 PreservedAnalyses PA
;
1807 PA
.preserve
<DominatorTreeAnalysis
>();
1808 PA
.preserve
<LoopAnalysis
>();
1809 PA
.preserve
<ScalarEvolutionAnalysis
>();
1810 PA
.preserveSet
<CFGAnalyses
>();