aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp75
1 files changed, 60 insertions, 15 deletions
diff --git a/contrib/llvm-project/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/contrib/llvm-project/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 18266ba07898..899d7e0a11e6 100644
--- a/contrib/llvm-project/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/contrib/llvm-project/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -273,7 +273,16 @@ class ConstraintInfo {
public:
ConstraintInfo(const DataLayout &DL, ArrayRef<Value *> FunctionArgs)
- : UnsignedCS(FunctionArgs), SignedCS(FunctionArgs), DL(DL) {}
+ : UnsignedCS(FunctionArgs), SignedCS(FunctionArgs), DL(DL) {
+ auto &Value2Index = getValue2Index(false);
+ // Add Arg > -1 constraints to unsigned system for all function arguments.
+ for (Value *Arg : FunctionArgs) {
+ ConstraintTy VarPos(SmallVector<int64_t, 8>(Value2Index.size() + 1, 0),
+ false, false, false);
+ VarPos.Coefficients[Value2Index[Arg]] = -1;
+ UnsignedCS.addVariableRow(VarPos.Coefficients);
+ }
+ }
DenseMap<Value *, unsigned> &getValue2Index(bool Signed) {
return Signed ? SignedCS.getValue2Index() : UnsignedCS.getValue2Index();
@@ -1365,18 +1374,34 @@ removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info,
ReproducerCondStack.pop_back();
}
-/// Check if the first condition for an AND implies the second.
-static bool checkAndSecondOpImpliedByFirst(
+/// Check if either the first condition of an AND or OR is implied by the
+/// (negated in case of OR) second condition or vice versa.
+static bool checkOrAndOpImpliedByOther(
FactOrCheck &CB, ConstraintInfo &Info, Module *ReproducerModule,
SmallVectorImpl<ReproducerEntry> &ReproducerCondStack,
SmallVectorImpl<StackEntry> &DFSInStack) {
CmpInst::Predicate Pred;
Value *A, *B;
- Instruction *And = CB.getContextInst();
- if (!match(And->getOperand(0), m_ICmp(Pred, m_Value(A), m_Value(B))))
+ Instruction *JoinOp = CB.getContextInst();
+ CmpInst *CmpToCheck = cast<CmpInst>(CB.getInstructionToSimplify());
+ unsigned OtherOpIdx = JoinOp->getOperand(0) == CmpToCheck ? 1 : 0;
+
+ // Don't try to simplify the first condition of a select by the second, as
+ // this may make the select more poisonous than the original one.
+ // TODO: check if the first operand may be poison.
+ if (OtherOpIdx != 0 && isa<SelectInst>(JoinOp))
return false;
+ if (!match(JoinOp->getOperand(OtherOpIdx),
+ m_ICmp(Pred, m_Value(A), m_Value(B))))
+ return false;
+
+ // For OR, check if the negated condition implies CmpToCheck.
+ bool IsOr = match(JoinOp, m_LogicalOr());
+ if (IsOr)
+ Pred = CmpInst::getInversePredicate(Pred);
+
// Optimistically add fact from first condition.
unsigned OldSize = DFSInStack.size();
Info.addFact(Pred, A, B, CB.NumIn, CB.NumOut, DFSInStack);
@@ -1385,11 +1410,19 @@ static bool checkAndSecondOpImpliedByFirst(
bool Changed = false;
// Check if the second condition can be simplified now.
- ICmpInst *Cmp = cast<ICmpInst>(And->getOperand(1));
- if (auto ImpliedCondition = checkCondition(
- Cmp->getPredicate(), Cmp->getOperand(0), Cmp->getOperand(1), Cmp,
- Info, CB.NumIn, CB.NumOut, CB.getContextInst())) {
- And->setOperand(1, ConstantInt::getBool(And->getType(), *ImpliedCondition));
+ if (auto ImpliedCondition =
+ checkCondition(CmpToCheck->getPredicate(), CmpToCheck->getOperand(0),
+ CmpToCheck->getOperand(1), CmpToCheck, Info, CB.NumIn,
+ CB.NumOut, CB.getContextInst())) {
+ if (IsOr && isa<SelectInst>(JoinOp)) {
+ JoinOp->setOperand(
+ OtherOpIdx == 0 ? 2 : 0,
+ ConstantInt::getBool(JoinOp->getType(), *ImpliedCondition));
+ } else
+ JoinOp->setOperand(
+ 1 - OtherOpIdx,
+ ConstantInt::getBool(JoinOp->getType(), *ImpliedCondition));
+
Changed = true;
}
@@ -1442,6 +1475,17 @@ void ConstraintInfo::addFact(CmpInst::Predicate Pred, Value *A, Value *B,
DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
std::move(ValuesToRelease));
+ if (!R.IsSigned) {
+ for (Value *V : NewVariables) {
+ ConstraintTy VarPos(SmallVector<int64_t, 8>(Value2Index.size() + 1, 0),
+ false, false, false);
+ VarPos.Coefficients[Value2Index[V]] = -1;
+ CSToUse.addVariableRow(VarPos.Coefficients);
+ DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned,
+ SmallVector<Value *, 2>());
+ }
+ }
+
if (R.isEq()) {
// Also add the inverted constraint for equality constraints.
for (auto &Coeff : R.Coefficients)
@@ -1609,11 +1653,11 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI,
bool Simplified = checkAndReplaceCondition(
Cmp, Info, CB.NumIn, CB.NumOut, CB.getContextInst(),
ReproducerModule.get(), ReproducerCondStack, S.DT, ToRemove);
- if (!Simplified && match(CB.getContextInst(),
- m_LogicalAnd(m_Value(), m_Specific(Inst)))) {
+ if (!Simplified &&
+ match(CB.getContextInst(), m_LogicalOp(m_Value(), m_Value()))) {
Simplified =
- checkAndSecondOpImpliedByFirst(CB, Info, ReproducerModule.get(),
- ReproducerCondStack, DFSInStack);
+ checkOrAndOpImpliedByOther(CB, Info, ReproducerModule.get(),
+ ReproducerCondStack, DFSInStack);
}
Changed |= Simplified;
}
@@ -1687,7 +1731,8 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI,
#ifndef NDEBUG
unsigned SignedEntries =
count_if(DFSInStack, [](const StackEntry &E) { return E.IsSigned; });
- assert(Info.getCS(false).size() == DFSInStack.size() - SignedEntries &&
+ assert(Info.getCS(false).size() - FunctionArgs.size() ==
+ DFSInStack.size() - SignedEntries &&
"updates to CS and DFSInStack are out of sync");
assert(Info.getCS(true).size() == SignedEntries &&
"updates to CS and DFSInStack are out of sync");