[llvm] [ConstraintElim] Add min/max bounds from KnownBits (PR #176607)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 18 06:08:25 PST 2026
https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/176607
>From e7a3dab7819d73e4ae75494753c73274adf39713 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Sat, 17 Jan 2026 22:49:52 +0000
Subject: [PATCH 1/3] [ConstraintElim] Add min/max bounds from KnownBits
Co-authored-by: John Regehr <regehr at cs.utah.edu>
---
.../Scalar/ConstraintElimination.cpp | 103 +++++++++++-------
.../monotonic-int-phis-signed.ll | 12 +-
.../Transforms/ConstraintElimination/trunc.ll | 3 +-
3 files changed, 75 insertions(+), 43 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 480ab8b822595..457c500e3acb2 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -335,13 +335,16 @@ class ConstraintInfo {
struct DecompEntry {
int64_t Coefficient;
Value *Variable;
- /// True if the variable is known positive in the current constraint.
- bool IsKnownNonNegative;
+ /// Value is always greater than or equal to this value.
+ std::optional<APInt> MinValue;
+ /// Value is always less than or equal to this value.
+ std::optional<APInt> MaxValue;
DecompEntry(int64_t Coefficient, Value *Variable,
- bool IsKnownNonNegative = false)
- : Coefficient(Coefficient), Variable(Variable),
- IsKnownNonNegative(IsKnownNonNegative) {}
+ std::optional<APInt> MinValue = {},
+ std::optional<APInt> MaxValue = {})
+ : Coefficient(Coefficient), Variable(Variable), MinValue(MinValue),
+ MaxValue(MaxValue) {}
};
/// Represents an Offset + Coefficient1 * Variable1 + ... decomposition.
@@ -350,8 +353,10 @@ struct Decomposition {
SmallVector<DecompEntry, 3> Vars;
Decomposition(int64_t Offset) : Offset(Offset) {}
- Decomposition(Value *V, bool IsKnownNonNegative = false) {
- Vars.emplace_back(1, V, IsKnownNonNegative);
+ Decomposition(Value *V) { Vars.emplace_back(1, V); }
+ Decomposition(Value *V, std::optional<APInt> MinValue,
+ std::optional<APInt> MaxValue) {
+ Vars.emplace_back(1, V, MinValue, MaxValue);
}
Decomposition(int64_t Offset, ArrayRef<DecompEntry> Vars)
: Offset(Offset), Vars(Vars) {}
@@ -522,7 +527,12 @@ static Decomposition decompose(Value *V,
if (!Ty->isIntegerTy() || Ty->getIntegerBitWidth() > 64)
return V;
- bool IsKnownNonNegative = false;
+ std::optional<APInt> MinValue, MaxValue;
+ KnownBits Known = computeKnownBits(V, DL);
+ if (!Known.isUnknown()) {
+ MinValue = IsSigned ? Known.getSignedMinValue() : Known.getMinValue();
+ MaxValue = IsSigned ? Known.getSignedMaxValue() : Known.getMaxValue();
+ }
// Decompose \p V used with a signed predicate.
if (IsSigned) {
@@ -537,7 +547,6 @@ static Decomposition decompose(Value *V,
V = Op0;
else if (match(V, m_NNegZExt(m_Value(Op0)))) {
V = Op0;
- IsKnownNonNegative = true;
} else if (match(V, m_NSWTrunc(m_Value(Op0)))) {
if (Op0->getType()->getScalarSizeInBits() <= 64)
V = Op0;
@@ -546,7 +555,7 @@ static Decomposition decompose(Value *V,
if (match(V, m_NSWAdd(m_Value(Op0), m_Value(Op1)))) {
if (auto Decomp = MergeResults(Op0, Op1, IsSigned))
return *Decomp;
- return {V, IsKnownNonNegative};
+ return {V, MinValue, MaxValue};
}
if (match(V, m_NSWSub(m_Value(Op0), m_Value(Op1)))) {
@@ -554,7 +563,7 @@ static Decomposition decompose(Value *V,
auto ResB = decompose(Op1, Preconditions, IsSigned, DL);
if (!ResA.sub(ResB))
return ResA;
- return {V, IsKnownNonNegative};
+ return {V, MinValue, MaxValue};
}
ConstantInt *CI;
@@ -562,7 +571,7 @@ static Decomposition decompose(Value *V,
auto Result = decompose(Op0, Preconditions, IsSigned, DL);
if (!Result.mul(CI->getSExtValue()))
return Result;
- return {V, IsKnownNonNegative};
+ return {V, MinValue, MaxValue};
}
// (shl nsw x, shift) is (mul nsw x, (1<<shift)), with the exception of
@@ -574,11 +583,11 @@ static Decomposition decompose(Value *V,
auto Result = decompose(Op0, Preconditions, IsSigned, DL);
if (!Result.mul(int64_t(1) << Shift))
return Result;
- return {V, IsKnownNonNegative};
+ return {V, MinValue, MaxValue};
}
}
- return {V, IsKnownNonNegative};
+ return {V, MinValue, MaxValue};
}
if (auto *CI = dyn_cast<ConstantInt>(V)) {
@@ -589,7 +598,6 @@ static Decomposition decompose(Value *V,
Value *Op0;
if (match(V, m_ZExt(m_Value(Op0)))) {
- IsKnownNonNegative = true;
V = Op0;
} else if (match(V, m_SExt(m_Value(Op0)))) {
V = Op0;
@@ -611,7 +619,7 @@ static Decomposition decompose(Value *V,
if (match(V, m_NUWAdd(m_Value(Op0), m_Value(Op1)))) {
if (auto Decomp = MergeResults(Op0, Op1, IsSigned))
return *Decomp;
- return {V, IsKnownNonNegative};
+ return {V, MinValue, MaxValue};
}
if (match(V, m_Add(m_Value(Op0), m_ConstantInt(CI))) && CI->isNegative() &&
@@ -621,7 +629,7 @@ static Decomposition decompose(Value *V,
ConstantInt::get(Op0->getType(), CI->getSExtValue() * -1));
if (auto Decomp = MergeResults(Op0, CI, true))
return *Decomp;
- return {V, IsKnownNonNegative};
+ return {V, MinValue, MaxValue};
}
if (match(V, m_NSWAdd(m_Value(Op0), m_Value(Op1)))) {
@@ -634,23 +642,23 @@ static Decomposition decompose(Value *V,
if (auto Decomp = MergeResults(Op0, Op1, IsSigned))
return *Decomp;
- return {V, IsKnownNonNegative};
+ return {V, MinValue, MaxValue};
}
// Decompose or as an add if there are no common bits between the operands.
if (match(V, m_DisjointOr(m_Value(Op0), m_ConstantInt(CI)))) {
if (auto Decomp = MergeResults(Op0, CI, IsSigned))
return *Decomp;
- return {V, IsKnownNonNegative};
+ return {V, MinValue, MaxValue};
}
if (match(V, m_NUWShl(m_Value(Op1), m_ConstantInt(CI))) && canUseSExt(CI)) {
if (CI->getSExtValue() < 0 || CI->getSExtValue() >= 64)
- return {V, IsKnownNonNegative};
+ return {V, MinValue, MaxValue};
auto Result = decompose(Op1, Preconditions, IsSigned, DL);
if (!Result.mul(int64_t{1} << CI->getSExtValue()))
return Result;
- return {V, IsKnownNonNegative};
+ return {V, MinValue, MaxValue};
}
if (match(V, m_NUWMul(m_Value(Op1), m_ConstantInt(CI))) && canUseSExt(CI) &&
@@ -658,7 +666,7 @@ static Decomposition decompose(Value *V,
auto Result = decompose(Op1, Preconditions, IsSigned, DL);
if (!Result.mul(CI->getSExtValue()))
return Result;
- return {V, IsKnownNonNegative};
+ return {V, MinValue, MaxValue};
}
if (match(V, m_NUWSub(m_Value(Op0), m_Value(Op1)))) {
@@ -666,10 +674,10 @@ static Decomposition decompose(Value *V,
auto ResB = decompose(Op1, Preconditions, IsSigned, DL);
if (!ResA.sub(ResB))
return ResA;
- return {V, IsKnownNonNegative};
+ return {V, MinValue, MaxValue};
}
- return {V, IsKnownNonNegative};
+ return {V, MinValue, MaxValue};
}
ConstraintTy
@@ -758,22 +766,30 @@ ConstraintInfo::getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
IsSigned, IsEq, IsNe);
// Collect variables that are known to be positive in all uses in the
// constraint.
- SmallDenseMap<Value *, bool> KnownNonNegativeVariables;
+ SmallDenseMap<Value *, std::pair<std::optional<APInt>, std::optional<APInt>>>
+ VariableBounds;
auto &R = Res.Coefficients;
+ auto MergeMinMax = [&](const DecompEntry &KV) {
+ auto [It, _] = VariableBounds.try_emplace(
+ KV.Variable, std::make_pair(KV.MinValue, KV.MaxValue));
+ auto &[Min, Max] = It->second;
+ if (!Min || (KV.MinValue && IsSigned ? Min->slt(*KV.MinValue)
+ : Min->ult(*KV.MinValue)))
+ Min = KV.MinValue;
+ if (!Max || (KV.MaxValue && IsSigned ? Max->sgt(*KV.MaxValue)
+ : Max->ugt(*KV.MaxValue)))
+ Max = KV.MaxValue;
+ };
for (const auto &KV : VariablesA) {
R[GetOrAddIndex(KV.Variable)] += KV.Coefficient;
- auto I =
- KnownNonNegativeVariables.insert({KV.Variable, KV.IsKnownNonNegative});
- I.first->second &= KV.IsKnownNonNegative;
+ MergeMinMax(KV);
}
for (const auto &KV : VariablesB) {
auto &Coeff = R[GetOrAddIndex(KV.Variable)];
if (SubOverflow(Coeff, KV.Coefficient, Coeff))
return {};
- auto I =
- KnownNonNegativeVariables.insert({KV.Variable, KV.IsKnownNonNegative});
- I.first->second &= KV.IsKnownNonNegative;
+ MergeMinMax(KV);
}
int64_t OffsetSum;
@@ -796,14 +812,25 @@ ConstraintInfo::getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
NewIndexMap.erase(RemovedV);
}
- // Add extra constraints for variables that are known positive.
- for (auto &KV : KnownNonNegativeVariables) {
- if (!KV.second ||
- (!Value2Index.contains(KV.first) && !NewIndexMap.contains(KV.first)))
+ // Add extra constraints for Min and Max values of variables.
+ for (auto &KV : VariableBounds) {
+ auto &[Min, Max] = KV.second;
+ if (!Value2Index.contains(KV.first) && !NewIndexMap.contains(KV.first))
continue;
- auto &C = Res.ExtraInfo.emplace_back(
- Value2Index.size() + NewVariables.size() + 1, 0);
- C[GetOrAddIndex(KV.first)] = -1;
+
+ if (Min) {
+ auto &C = Res.ExtraInfo.emplace_back(
+ Value2Index.size() + NewVariables.size() + 1, 0);
+ C[0] = (IsSigned ? (-*Min).getSExtValue() : (-*Min).getZExtValue());
+ C[GetOrAddIndex(KV.first)] = -1;
+ }
+
+ if (Max) {
+ auto &C = Res.ExtraInfo.emplace_back(
+ Value2Index.size() + NewVariables.size() + 1, 0);
+ C[0] = (IsSigned ? Max->getSExtValue() : Max->getZExtValue());
+ C[GetOrAddIndex(KV.first)] = 1;
+ }
}
return Res;
}
diff --git a/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-signed.ll b/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-signed.ll
index 7273469fc59e8..5ee1d5e68f968 100644
--- a/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-signed.ll
+++ b/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-signed.ll
@@ -55,8 +55,10 @@ define void @signed_iv_step_4(i64 %count) {
; CHECK-NEXT: [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]]
; CHECK-NEXT: br i1 [[CMP_I_NOT]], label [[EXIT]], label [[LOOP_LATCH]]
; CHECK: loop.latch:
-; CHECK-NEXT: call void @use(i1 true)
-; CHECK-NEXT: call void @use(i1 true)
+; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[IV]], [[END]]
+; CHECK-NEXT: call void @use(i1 [[CMP2]])
+; CHECK-NEXT: [[CMP3:%.*]] = icmp sge i64 [[IV]], 0
+; CHECK-NEXT: call void @use(i1 [[CMP3]])
; CHECK-NEXT: br label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: ret void
@@ -139,8 +141,10 @@ define void @signed_iv_step_4_start_4(i64 %count) {
; CHECK-NEXT: [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]]
; CHECK-NEXT: br i1 [[CMP_I_NOT]], label [[EXIT]], label [[LOOP_LATCH]]
; CHECK: loop.latch:
-; CHECK-NEXT: call void @use(i1 true)
-; CHECK-NEXT: call void @use(i1 true)
+; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[IV]], [[END]]
+; CHECK-NEXT: call void @use(i1 [[CMP2]])
+; CHECK-NEXT: [[CMP3:%.*]] = icmp sge i64 [[IV]], 4
+; CHECK-NEXT: call void @use(i1 [[CMP3]])
; CHECK-NEXT: br label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: ret void
diff --git a/llvm/test/Transforms/ConstraintElimination/trunc.ll b/llvm/test/Transforms/ConstraintElimination/trunc.ll
index 620d978149874..c33b65aa3247c 100644
--- a/llvm/test/Transforms/ConstraintElimination/trunc.ll
+++ b/llvm/test/Transforms/ConstraintElimination/trunc.ll
@@ -99,7 +99,8 @@ define i1 @test2(i32 %n) {
; CHECK-NEXT: br i1 [[COND2]], label %[[FOR_BODY]], label %[[FOR_END:.*]]
; CHECK: [[FOR_END]]:
; CHECK-NEXT: [[TRUNC:%.*]] = trunc nsw i64 [[INDVAR_NEXT]] to i32
-; CHECK-NEXT: ret i1 true
+; CHECK-NEXT: [[RES:%.*]] = icmp sgt i32 [[N]], [[TRUNC]]
+; CHECK-NEXT: ret i1 [[RES]]
; CHECK: [[IF_ELSE]]:
; CHECK-NEXT: ret i1 false
;
>From 51e53594463a655287643d4f4483aa70f209515f Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Sun, 18 Jan 2026 01:30:13 +0000
Subject: [PATCH 2/3] [ConstraintElim] Fix some issues
---
.../Scalar/ConstraintElimination.cpp | 39 ++++++++++---------
.../monotonic-int-phis-signed.ll | 6 +--
.../Transforms/ConstraintElimination/trunc.ll | 3 +-
3 files changed, 23 insertions(+), 25 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 457c500e3acb2..567d726df0654 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -336,13 +336,13 @@ struct DecompEntry {
int64_t Coefficient;
Value *Variable;
/// Value is always greater than or equal to this value.
- std::optional<APInt> MinValue;
+ int64_t MinValue = MinSignedConstraintValue;
/// Value is always less than or equal to this value.
- std::optional<APInt> MaxValue;
+ int64_t MaxValue = MaxConstraintValue;
DecompEntry(int64_t Coefficient, Value *Variable,
- std::optional<APInt> MinValue = {},
- std::optional<APInt> MaxValue = {})
+ int64_t MinValue = MinSignedConstraintValue,
+ int64_t MaxValue = MaxConstraintValue)
: Coefficient(Coefficient), Variable(Variable), MinValue(MinValue),
MaxValue(MaxValue) {}
};
@@ -354,8 +354,7 @@ struct Decomposition {
Decomposition(int64_t Offset) : Offset(Offset) {}
Decomposition(Value *V) { Vars.emplace_back(1, V); }
- Decomposition(Value *V, std::optional<APInt> MinValue,
- std::optional<APInt> MaxValue) {
+ Decomposition(Value *V, int64_t MinValue, int64_t MaxValue) {
Vars.emplace_back(1, V, MinValue, MaxValue);
}
Decomposition(int64_t Offset, ArrayRef<DecompEntry> Vars)
@@ -527,11 +526,14 @@ static Decomposition decompose(Value *V,
if (!Ty->isIntegerTy() || Ty->getIntegerBitWidth() > 64)
return V;
- std::optional<APInt> MinValue, MaxValue;
+ int64_t MinValue = MinSignedConstraintValue;
+ int64_t MaxValue = MaxConstraintValue;
KnownBits Known = computeKnownBits(V, DL);
if (!Known.isUnknown()) {
- MinValue = IsSigned ? Known.getSignedMinValue() : Known.getMinValue();
- MaxValue = IsSigned ? Known.getSignedMaxValue() : Known.getMaxValue();
+ MinValue = IsSigned ? Known.getSignedMinValue().getSExtValue()
+ : Known.getMinValue().getZExtValue();
+ MaxValue = IsSigned ? Known.getSignedMaxValue().getSExtValue()
+ : Known.getMaxValue().getZExtValue();
}
// Decompose \p V used with a signed predicate.
@@ -547,6 +549,7 @@ static Decomposition decompose(Value *V,
V = Op0;
else if (match(V, m_NNegZExt(m_Value(Op0)))) {
V = Op0;
+ MinValue = std::max<int64_t>(MinValue, 0);
} else if (match(V, m_NSWTrunc(m_Value(Op0)))) {
if (Op0->getType()->getScalarSizeInBits() <= 64)
V = Op0;
@@ -598,6 +601,7 @@ static Decomposition decompose(Value *V,
Value *Op0;
if (match(V, m_ZExt(m_Value(Op0)))) {
+ MinValue = std::max<int64_t>(MinValue, 0);
V = Op0;
} else if (match(V, m_SExt(m_Value(Op0)))) {
V = Op0;
@@ -766,18 +770,15 @@ ConstraintInfo::getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
IsSigned, IsEq, IsNe);
// Collect variables that are known to be positive in all uses in the
// constraint.
- SmallDenseMap<Value *, std::pair<std::optional<APInt>, std::optional<APInt>>>
- VariableBounds;
+ SmallDenseMap<Value *, std::pair<int64_t, int64_t>> VariableBounds;
auto &R = Res.Coefficients;
auto MergeMinMax = [&](const DecompEntry &KV) {
auto [It, _] = VariableBounds.try_emplace(
KV.Variable, std::make_pair(KV.MinValue, KV.MaxValue));
auto &[Min, Max] = It->second;
- if (!Min || (KV.MinValue && IsSigned ? Min->slt(*KV.MinValue)
- : Min->ult(*KV.MinValue)))
+ if (Min < KV.MinValue)
Min = KV.MinValue;
- if (!Max || (KV.MaxValue && IsSigned ? Max->sgt(*KV.MaxValue)
- : Max->ugt(*KV.MaxValue)))
+ if (Max > KV.MaxValue)
Max = KV.MaxValue;
};
for (const auto &KV : VariablesA) {
@@ -818,17 +819,17 @@ ConstraintInfo::getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
if (!Value2Index.contains(KV.first) && !NewIndexMap.contains(KV.first))
continue;
- if (Min) {
+ if (Min != MinSignedConstraintValue) {
auto &C = Res.ExtraInfo.emplace_back(
Value2Index.size() + NewVariables.size() + 1, 0);
- C[0] = (IsSigned ? (-*Min).getSExtValue() : (-*Min).getZExtValue());
+ C[0] = -Min;
C[GetOrAddIndex(KV.first)] = -1;
}
- if (Max) {
+ if (Max != MaxConstraintValue) {
auto &C = Res.ExtraInfo.emplace_back(
Value2Index.size() + NewVariables.size() + 1, 0);
- C[0] = (IsSigned ? Max->getSExtValue() : Max->getZExtValue());
+ C[0] = Max;
C[GetOrAddIndex(KV.first)] = 1;
}
}
diff --git a/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-signed.ll b/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-signed.ll
index 5ee1d5e68f968..75f31ea97ed0f 100644
--- a/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-signed.ll
+++ b/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-signed.ll
@@ -57,8 +57,7 @@ define void @signed_iv_step_4(i64 %count) {
; CHECK: loop.latch:
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[IV]], [[END]]
; CHECK-NEXT: call void @use(i1 [[CMP2]])
-; CHECK-NEXT: [[CMP3:%.*]] = icmp sge i64 [[IV]], 0
-; CHECK-NEXT: call void @use(i1 [[CMP3]])
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: br label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: ret void
@@ -143,8 +142,7 @@ define void @signed_iv_step_4_start_4(i64 %count) {
; CHECK: loop.latch:
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[IV]], [[END]]
; CHECK-NEXT: call void @use(i1 [[CMP2]])
-; CHECK-NEXT: [[CMP3:%.*]] = icmp sge i64 [[IV]], 4
-; CHECK-NEXT: call void @use(i1 [[CMP3]])
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: br label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: ret void
diff --git a/llvm/test/Transforms/ConstraintElimination/trunc.ll b/llvm/test/Transforms/ConstraintElimination/trunc.ll
index c33b65aa3247c..620d978149874 100644
--- a/llvm/test/Transforms/ConstraintElimination/trunc.ll
+++ b/llvm/test/Transforms/ConstraintElimination/trunc.ll
@@ -99,8 +99,7 @@ define i1 @test2(i32 %n) {
; CHECK-NEXT: br i1 [[COND2]], label %[[FOR_BODY]], label %[[FOR_END:.*]]
; CHECK: [[FOR_END]]:
; CHECK-NEXT: [[TRUNC:%.*]] = trunc nsw i64 [[INDVAR_NEXT]] to i32
-; CHECK-NEXT: [[RES:%.*]] = icmp sgt i32 [[N]], [[TRUNC]]
-; CHECK-NEXT: ret i1 [[RES]]
+; CHECK-NEXT: ret i1 true
; CHECK: [[IF_ELSE]]:
; CHECK-NEXT: ret i1 false
;
>From c66df6c03ed9255ed358898dda00d5892b710b8a Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Sun, 18 Jan 2026 14:02:35 +0000
Subject: [PATCH 3/3] [ConstraintElim] Fix final error
---
.../Transforms/Scalar/ConstraintElimination.cpp | 17 ++++++++---------
.../monotonic-int-phis-signed.ll | 6 ++----
2 files changed, 10 insertions(+), 13 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 567d726df0654..1ba44e6d6a6e8 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -340,9 +340,10 @@ struct DecompEntry {
/// Value is always less than or equal to this value.
int64_t MaxValue = MaxConstraintValue;
- DecompEntry(int64_t Coefficient, Value *Variable,
- int64_t MinValue = MinSignedConstraintValue,
- int64_t MaxValue = MaxConstraintValue)
+ DecompEntry(int64_t Coefficient, Value *Variable)
+ : Coefficient(Coefficient), Variable(Variable) {}
+ DecompEntry(int64_t Coefficient, Value *Variable, int64_t MinValue,
+ int64_t MaxValue)
: Coefficient(Coefficient), Variable(Variable), MinValue(MinValue),
MaxValue(MaxValue) {}
};
@@ -532,8 +533,8 @@ static Decomposition decompose(Value *V,
if (!Known.isUnknown()) {
MinValue = IsSigned ? Known.getSignedMinValue().getSExtValue()
: Known.getMinValue().getZExtValue();
- MaxValue = IsSigned ? Known.getSignedMaxValue().getSExtValue()
- : Known.getMaxValue().getZExtValue();
+ MaxValue = IsSigned ? Known.getMaxValue().getSExtValue()
+ : Known.getSignedMaxValue().getZExtValue();
}
// Decompose \p V used with a signed predicate.
@@ -776,10 +777,8 @@ ConstraintInfo::getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
auto [It, _] = VariableBounds.try_emplace(
KV.Variable, std::make_pair(KV.MinValue, KV.MaxValue));
auto &[Min, Max] = It->second;
- if (Min < KV.MinValue)
- Min = KV.MinValue;
- if (Max > KV.MaxValue)
- Max = KV.MaxValue;
+ Min = std::max(Min, KV.MinValue);
+ Max = std::min(Max, KV.MaxValue);
};
for (const auto &KV : VariablesA) {
R[GetOrAddIndex(KV.Variable)] += KV.Coefficient;
diff --git a/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-signed.ll b/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-signed.ll
index 75f31ea97ed0f..7273469fc59e8 100644
--- a/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-signed.ll
+++ b/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-signed.ll
@@ -55,8 +55,7 @@ define void @signed_iv_step_4(i64 %count) {
; CHECK-NEXT: [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]]
; CHECK-NEXT: br i1 [[CMP_I_NOT]], label [[EXIT]], label [[LOOP_LATCH]]
; CHECK: loop.latch:
-; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[IV]], [[END]]
-; CHECK-NEXT: call void @use(i1 [[CMP2]])
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: br label [[LOOP]]
; CHECK: exit:
@@ -140,8 +139,7 @@ define void @signed_iv_step_4_start_4(i64 %count) {
; CHECK-NEXT: [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]]
; CHECK-NEXT: br i1 [[CMP_I_NOT]], label [[EXIT]], label [[LOOP_LATCH]]
; CHECK: loop.latch:
-; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[IV]], [[END]]
-; CHECK-NEXT: call void @use(i1 [[CMP2]])
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: br label [[LOOP]]
; CHECK: exit:
More information about the llvm-commits
mailing list