summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/ADT/APInt.h7
-rw-r--r--llvm/unittests/ADT/APIntTest.cpp17
2 files changed, 24 insertions, 0 deletions
diff --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h
index 1e10253ffe1..ff32e3aa3cd 100644
--- a/llvm/include/llvm/ADT/APInt.h
+++ b/llvm/include/llvm/ADT/APInt.h
@@ -1782,6 +1782,13 @@ inline bool isMask(unsigned numBits, const APInt &APIVal) {
APIVal == APInt::getLowBitsSet(APIVal.getBitWidth(), numBits);
}
+/// \returns true if the argument is a non-empty sequence of ones starting at
+/// the least significant bit with the remainder zero (32 bit version).
+/// Ex. isMask(0x0000FFFFU) == true.
+inline bool isMask(const APInt &Value) {
+ return (Value != 0) && ((Value + 1) & Value) == 0;
+}
+
/// \brief Return true if the argument APInt value contains a sequence of ones
/// with the remainder zero.
inline bool isShiftedMask(unsigned numBits, const APInt &APIVal) {
diff --git a/llvm/unittests/ADT/APIntTest.cpp b/llvm/unittests/ADT/APIntTest.cpp
index c59e695b04e..4ae70251d4e 100644
--- a/llvm/unittests/ADT/APIntTest.cpp
+++ b/llvm/unittests/ADT/APIntTest.cpp
@@ -994,6 +994,23 @@ TEST(APIntTest, IsSplat) {
EXPECT_TRUE(E.isSplat(32));
}
+TEST(APIntTest, isMask) {
+ EXPECT_FALSE(APIntOps::isMask(APInt(32, 0x01010101)));
+ EXPECT_FALSE(APIntOps::isMask(APInt(32, 0xf0000000)));
+ EXPECT_FALSE(APIntOps::isMask(APInt(32, 0xffff0000)));
+ EXPECT_FALSE(APIntOps::isMask(APInt(32, 0xff << 1)));
+
+ for (int N : { 1, 2, 3, 4, 7, 8, 16, 32, 64, 127, 128, 129, 256 }) {
+ EXPECT_FALSE(APIntOps::isMask(APInt(N, 0)));
+
+ APInt One(N, 1);
+ for (int I = 1; I <= N; ++I) {
+ APInt MaskVal = One.shl(I) - 1;
+ EXPECT_TRUE(APIntOps::isMask(MaskVal));
+ }
+ }
+}
+
#if defined(__clang__)
// Disable the pragma warning from versions of Clang without -Wself-move
#pragma clang diagnostic push
OpenPOWER on IntegriCloud