aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/ConstantRange.cpp
diff options
context:
space:
mode:
authorYingwei Zheng <dtcxzyw2333@gmail.com>2024-02-08 22:34:52 +0800
committerGitHub <noreply@github.com>2024-02-08 22:34:52 +0800
commitd9e92765c5f9b0fa7adafa769dd13d37b6bca038 (patch)
tree0db2be537237db745aed3d8030b8f51a2955bef6 /llvm/lib/IR/ConstantRange.cpp
parent3ad63593dac390e320808f3de0e1906c5fa45c8a (diff)
downloadllvm-d9e92765c5f9b0fa7adafa769dd13d37b6bca038.zip
llvm-d9e92765c5f9b0fa7adafa769dd13d37b6bca038.tar.gz
llvm-d9e92765c5f9b0fa7adafa769dd13d37b6bca038.tar.bz2
[ConstantRange] Improve ConstantRange::binaryXor (#80146)
`ConstantRange::binaryXor` gives poor results as it currently depends on `KnownBits::operator^`. Since `sub A, B` is canonicalized into `xor A, B` if `B` is the subset of `A`, this patch reverts the transform in `ConstantRange::binaryXor`, which will give better results. Alive2: https://alive2.llvm.org/ce/z/bmTMV9 Fixes #79696.
Diffstat (limited to 'llvm/lib/IR/ConstantRange.cpp')
-rw-r--r--llvm/lib/IR/ConstantRange.cpp17
1 files changed, 16 insertions, 1 deletions
diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp
index cbb64b2..3394a1e 100644
--- a/llvm/lib/IR/ConstantRange.cpp
+++ b/llvm/lib/IR/ConstantRange.cpp
@@ -1467,7 +1467,22 @@ ConstantRange ConstantRange::binaryXor(const ConstantRange &Other) const {
if (isSingleElement() && getSingleElement()->isAllOnes())
return Other.binaryNot();
- return fromKnownBits(toKnownBits() ^ Other.toKnownBits(), /*IsSigned*/false);
+ KnownBits LHSKnown = toKnownBits();
+ KnownBits RHSKnown = Other.toKnownBits();
+ KnownBits Known = LHSKnown ^ RHSKnown;
+ ConstantRange CR = fromKnownBits(Known, /*IsSigned*/ false);
+ // Typically the following code doesn't improve the result if BW = 1.
+ if (getBitWidth() == 1)
+ return CR;
+
+ // If LHS is known to be the subset of RHS, treat LHS ^ RHS as RHS -nuw/nsw
+ // LHS. If RHS is known to be the subset of LHS, treat LHS ^ RHS as LHS
+ // -nuw/nsw RHS.
+ if ((~LHSKnown.Zero).isSubsetOf(RHSKnown.One))
+ CR = CR.intersectWith(Other.sub(*this), PreferredRangeType::Unsigned);
+ else if ((~RHSKnown.Zero).isSubsetOf(LHSKnown.One))
+ CR = CR.intersectWith(this->sub(Other), PreferredRangeType::Unsigned);
+ return CR;
}
ConstantRange