aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/ConstantRange.cpp
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2021-11-07 21:14:21 +0100
committerNikita Popov <nikita.ppv@gmail.com>2021-11-07 21:46:06 +0100
commit2060895c9ce71bba5a950827167f23ae9eb6eef5 (patch)
tree70fb7311b7406554ab29bc12b99e68911eb07349 /llvm/lib/IR/ConstantRange.cpp
parentcf71a5ea8f95be423ebd381d21d0f9a05edc5018 (diff)
downloadllvm-2060895c9ce71bba5a950827167f23ae9eb6eef5.zip
llvm-2060895c9ce71bba5a950827167f23ae9eb6eef5.tar.gz
llvm-2060895c9ce71bba5a950827167f23ae9eb6eef5.tar.bz2
[ConstantRange] Add exact union/intersect (NFC)
For some optimizations on comparisons it's necessary that the union/intersect is exact and not a superset. Add methods that return Optional<ConstantRange> only if the result is exact. For the sake of simplicity this is implemented by comparing the subset and superset approximations for now, but it should be possible to do this more directly, as unionWith() and intersectWith() already distinguish the cases where the result is imprecise for the preferred range type functionality.
Diffstat (limited to 'llvm/lib/IR/ConstantRange.cpp')
-rw-r--r--llvm/lib/IR/ConstantRange.cpp18
1 files changed, 18 insertions, 0 deletions
diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp
index bbb07bf..a0f2179 100644
--- a/llvm/lib/IR/ConstantRange.cpp
+++ b/llvm/lib/IR/ConstantRange.cpp
@@ -681,6 +681,24 @@ ConstantRange ConstantRange::unionWith(const ConstantRange &CR,
return ConstantRange(std::move(L), std::move(U));
}
+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 None;
+}
+
+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 None;
+}
+
ConstantRange ConstantRange::castOp(Instruction::CastOps CastOp,
uint32_t ResultBitWidth) const {
switch (CastOp) {