aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/ConstantRange.cpp
diff options
context:
space:
mode:
authorRoman Lebedev <lebedev.ri@gmail.com>2020-11-06 14:06:00 +0300
committerRoman Lebedev <lebedev.ri@gmail.com>2021-10-31 22:53:17 +0300
commit03a4f1f3b8a0e3acc6ac1f786446c9abcffe1f89 (patch)
tree76959734b99b285048e2f974ceceb57de108b0aa /llvm/lib/IR/ConstantRange.cpp
parent164194a5af0b3f8b571f64a830963ad256ece0aa (diff)
downloadllvm-03a4f1f3b8a0e3acc6ac1f786446c9abcffe1f89.zip
llvm-03a4f1f3b8a0e3acc6ac1f786446c9abcffe1f89.tar.gz
llvm-03a4f1f3b8a0e3acc6ac1f786446c9abcffe1f89.tar.bz2
[ConstantRange] Sign-flipping of signedness-invariant comparisons
For certain combination of LHS and RHS constant ranges, the signedness of the relational comparison predicate is irrelevant. This implements complete and precise model for all predicates, as confirmed by the brute-force tests. I'm not sure if there are some more cases that we can handle here. In a follow-up, CVP will make use of this. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D90924
Diffstat (limited to 'llvm/lib/IR/ConstantRange.cpp')
-rw-r--r--llvm/lib/IR/ConstantRange.cpp36
1 files changed, 36 insertions, 0 deletions
diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp
index a37790d..d37c969 100644
--- a/llvm/lib/IR/ConstantRange.cpp
+++ b/llvm/lib/IR/ConstantRange.cpp
@@ -147,6 +147,42 @@ ConstantRange ConstantRange::makeExactICmpRegion(CmpInst::Predicate Pred,
return makeAllowedICmpRegion(Pred, C);
}
+bool ConstantRange::areInsensitiveToSignednessOfICmpPredicate(
+ const ConstantRange &CR1, const ConstantRange &CR2) {
+ if (CR1.isEmptySet() || CR2.isEmptySet())
+ return true;
+
+ return (CR1.isAllNonNegative() && CR2.isAllNonNegative()) ||
+ (CR1.isAllNegative() && CR2.isAllNegative());
+}
+
+bool ConstantRange::areInsensitiveToSignednessOfInvertedICmpPredicate(
+ const ConstantRange &CR1, const ConstantRange &CR2) {
+ if (CR1.isEmptySet() || CR2.isEmptySet())
+ return true;
+
+ return (CR1.isAllNonNegative() && CR2.isAllNegative()) ||
+ (CR1.isAllNegative() && CR2.isAllNonNegative());
+}
+
+CmpInst::Predicate ConstantRange::getEquivalentPredWithFlippedSignedness(
+ CmpInst::Predicate Pred, const ConstantRange &CR1,
+ const ConstantRange &CR2) {
+ assert(CmpInst::isIntPredicate(Pred) && CmpInst::isRelational(Pred) &&
+ "Only for relational integer predicates!");
+
+ CmpInst::Predicate FlippedSignednessPred =
+ CmpInst::getFlippedSignednessPredicate(Pred);
+
+ if (areInsensitiveToSignednessOfICmpPredicate(CR1, CR2))
+ return FlippedSignednessPred;
+
+ if (areInsensitiveToSignednessOfInvertedICmpPredicate(CR1, CR2))
+ return CmpInst::getInversePredicate(FlippedSignednessPred);
+
+ return CmpInst::Predicate::BAD_ICMP_PREDICATE;
+}
+
bool ConstantRange::getEquivalentICmp(CmpInst::Predicate &Pred,
APInt &RHS) const {
bool Success = false;