[llvm] [ConstantRange] Implement union/intersect with exact union/intersect (NFC) (PR #91397)
via llvm-commits
llvm-commits at lists.llvm.org
Tue May 7 13:55:42 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-ir
Author: Andreas Jonson (andjo403)
<details>
<summary>Changes</summary>
Was thinking about using exactIntersectWith for range attributes as it feels like a fault if eg. the range at the declaration and call do not give one range as the intersection, and noticed the TODO.
Think that this is a simple solution to reuse the code and get some better performance.
CC @<!-- -->nikic
---
Full diff: https://github.com/llvm/llvm-project/pull/91397.diff
1 Files Affected:
- (modified) llvm/lib/IR/ConstantRange.cpp (+23-27)
``````````diff
diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp
index 59e7a9f5eb111..a9def5dd03b65 100644
--- a/llvm/lib/IR/ConstantRange.cpp
+++ b/llvm/lib/IR/ConstantRange.cpp
@@ -521,8 +521,8 @@ static ConstantRange getPreferredRange(
return CR2;
}
-ConstantRange ConstantRange::intersectWith(const ConstantRange &CR,
- PreferredRangeType Type) const {
+std::optional<ConstantRange>
+ConstantRange::exactIntersectWith(const ConstantRange &CR) const {
assert(getBitWidth() == CR.getBitWidth() &&
"ConstantRange types don't agree!");
@@ -531,7 +531,7 @@ ConstantRange ConstantRange::intersectWith(const ConstantRange &CR,
if (CR.isEmptySet() || isFullSet()) return CR;
if (!isUpperWrapped() && CR.isUpperWrapped())
- return CR.intersectWith(*this, Type);
+ return CR.exactIntersectWith(*this);
if (!isUpperWrapped() && !CR.isUpperWrapped()) {
if (Lower.ult(CR.Lower)) {
@@ -578,7 +578,7 @@ ConstantRange ConstantRange::intersectWith(const ConstantRange &CR,
// ------U L--- : this
// L----------U : CR
- return getPreferredRange(*this, CR, Type);
+ return std::nullopt;
}
if (CR.Lower.ult(Lower)) {
// --U L---- : this
@@ -600,7 +600,7 @@ ConstantRange ConstantRange::intersectWith(const ConstantRange &CR,
// ------U L-- : this
// --U L------ : CR
if (CR.Lower.ult(Upper))
- return getPreferredRange(*this, CR, Type);
+ return std::nullopt;
// ----U L-- : this
// --U L---- : CR
@@ -624,11 +624,11 @@ ConstantRange ConstantRange::intersectWith(const ConstantRange &CR,
// --U L------ : this
// ------U L-- : CR
- return getPreferredRange(*this, CR, Type);
+ return std::nullopt;
}
-ConstantRange ConstantRange::unionWith(const ConstantRange &CR,
- PreferredRangeType Type) const {
+std::optional<ConstantRange>
+ConstantRange::exactUnionWith(const ConstantRange &CR) const {
assert(getBitWidth() == CR.getBitWidth() &&
"ConstantRange types don't agree!");
@@ -636,7 +636,7 @@ ConstantRange ConstantRange::unionWith(const ConstantRange &CR,
if (CR.isFullSet() || isEmptySet()) return CR;
if (!isUpperWrapped() && CR.isUpperWrapped())
- return CR.unionWith(*this, Type);
+ return CR.exactUnionWith(*this);
if (!isUpperWrapped() && !CR.isUpperWrapped()) {
// L---U and L---U : this
@@ -645,8 +645,7 @@ ConstantRange ConstantRange::unionWith(const ConstantRange &CR,
// L---------U
// -----U L-----
if (CR.Upper.ult(Lower) || Upper.ult(CR.Lower))
- return getPreferredRange(
- ConstantRange(Lower, CR.Upper), ConstantRange(CR.Lower, Upper), Type);
+ return std::nullopt;
APInt L = CR.Lower.ult(Lower) ? CR.Lower : Lower;
APInt U = (CR.Upper - 1).ugt(Upper - 1) ? CR.Upper : Upper;
@@ -674,8 +673,7 @@ ConstantRange ConstantRange::unionWith(const ConstantRange &CR,
// ----------U L----
// ----U L----------
if (Upper.ult(CR.Lower) && CR.Upper.ult(Lower))
- return getPreferredRange(
- ConstantRange(Lower, CR.Upper), ConstantRange(CR.Lower, Upper), Type);
+ return std::nullopt;
// ----U L----- : this
// L----U : CR
@@ -700,22 +698,20 @@ ConstantRange ConstantRange::unionWith(const ConstantRange &CR,
return ConstantRange(std::move(L), std::move(U));
}
-std::optional<ConstantRange>
-ConstantRange::exactIntersectWith(const ConstantRange &CR) const {
- // TODO: This can be implemented more efficiently.
- ConstantRange Result = intersectWith(CR);
- if (Result == inverse().unionWith(CR.inverse()).inverse())
- return Result;
- return std::nullopt;
+ConstantRange ConstantRange::intersectWith(const ConstantRange &CR,
+ PreferredRangeType Type) const {
+ if (std::optional<ConstantRange> Result = exactIntersectWith(CR))
+ return *Result;
+ return getPreferredRange(*this, CR, Type);
+ ;
}
-std::optional<ConstantRange>
-ConstantRange::exactUnionWith(const ConstantRange &CR) const {
- // TODO: This can be implemented more efficiently.
- ConstantRange Result = unionWith(CR);
- if (Result == inverse().intersectWith(CR.inverse()).inverse())
- return Result;
- return std::nullopt;
+ConstantRange ConstantRange::unionWith(const ConstantRange &CR,
+ PreferredRangeType Type) const {
+ if (std::optional<ConstantRange> Result = exactUnionWith(CR))
+ return *Result;
+ return getPreferredRange(ConstantRange(Lower, CR.Upper),
+ ConstantRange(CR.Lower, Upper), Type);
}
ConstantRange ConstantRange::castOp(Instruction::CastOps CastOp,
``````````
</details>
https://github.com/llvm/llvm-project/pull/91397
More information about the llvm-commits
mailing list