diff options
author | Roman Lebedev <lebedev.ri@gmail.com> | 2020-09-22 11:50:25 +0300 |
---|---|---|
committer | Roman Lebedev <lebedev.ri@gmail.com> | 2020-09-22 21:37:29 +0300 |
commit | b38d897e802664034c7e6e4654328256ed370a61 (patch) | |
tree | e1292e468f28378accd63d4542c5c4439ca7128a /llvm/lib/IR/ConstantRange.cpp | |
parent | 4eeeb356fc41babf46797b062f74f978b818622b (diff) | |
download | llvm-b38d897e802664034c7e6e4654328256ed370a61.zip llvm-b38d897e802664034c7e6e4654328256ed370a61.tar.gz llvm-b38d897e802664034c7e6e4654328256ed370a61.tar.bz2 |
[ConstantRange] binaryXor(): special-case binary complement case - the result is precise
Use the fact that `~X` is equivalent to `-1 - X`, which gives us
fully-precise answer, and we only need to special-handle the wrapped case.
This fires ~16k times for vanilla llvm test-suite + RawSpeed.
Diffstat (limited to 'llvm/lib/IR/ConstantRange.cpp')
-rw-r--r-- | llvm/lib/IR/ConstantRange.cpp | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp index 396c39b..7b8dd66 100644 --- a/llvm/lib/IR/ConstantRange.cpp +++ b/llvm/lib/IR/ConstantRange.cpp @@ -1240,6 +1240,16 @@ ConstantRange ConstantRange::srem(const ConstantRange &RHS) const { return ConstantRange(std::move(Lower), std::move(Upper)); } +ConstantRange ConstantRange::binaryNot() const { + if (isEmptySet()) + return getEmpty(); + + if (isWrappedSet()) + return getFull(); + + return ConstantRange(APInt::getAllOnesValue(getBitWidth())).sub(*this); +} + ConstantRange ConstantRange::binaryAnd(const ConstantRange &Other) const { if (isEmptySet() || Other.isEmptySet()) @@ -1278,6 +1288,12 @@ ConstantRange ConstantRange::binaryXor(const ConstantRange &Other) const { if (isSingleElement() && Other.isSingleElement()) return {*getSingleElement() ^ *Other.getSingleElement()}; + // Special-case binary complement, since we can give a precise answer. + if (Other.isSingleElement() && Other.getSingleElement()->isAllOnesValue()) + return binaryNot(); + if (isSingleElement() && getSingleElement()->isAllOnesValue()) + return Other.binaryNot(); + // TODO: replace this with something less conservative return getFull(); } |