From: Craig Topper Date: Fri, 31 Mar 2017 06:30:25 +0000 (+0000) Subject: [APInt] Add unittests that demonstrate how very broken APIntOps::isShiftedMask is. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=dbf64c9e9746d560e59baa7ca6bd4e0c66014a1e;p=llvm [APInt] Add unittests that demonstrate how very broken APIntOps::isShiftedMask is. Did you know that 0 is a shifted mask? But 0x0000ff00 and 0x000000ff aren't? At least we get 0xff000000 right. I only see one usage of this function in the code base today and its in InstCombine. I think its protected against 0 being misreported as a mask. I guess we just don't have tests for the missed cases. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@299187 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/unittests/ADT/APIntTest.cpp b/unittests/ADT/APIntTest.cpp index 2148d4fd7e5..f05cbb9d915 100644 --- a/unittests/ADT/APIntTest.cpp +++ b/unittests/ADT/APIntTest.cpp @@ -1575,6 +1575,31 @@ TEST(APIntTest, isMask) { } } +TEST(APIntTest, isShiftedMask) { + EXPECT_FALSE(APIntOps::isShiftedMask(32, APInt(32, 0x01010101))); + EXPECT_TRUE(APIntOps::isShiftedMask(32, APInt(32, 0xf0000000))); + EXPECT_TRUE(APIntOps::isShiftedMask(32, APInt(32, 0xffff0000))); + EXPECT_FALSE(APIntOps::isShiftedMask(32, APInt(32, 0xff << 1))); // BUG + + for (int N : { 1, 2, 3, 4, 7, 8, 16, 32, 64, 127, 128, 129, 256 }) { + EXPECT_TRUE(APIntOps::isShiftedMask(N, APInt(N, 0))); // BUG + + APInt One(N, 1); + for (int I = 1; I < N; ++I) { + APInt MaskVal = One.shl(I) - 1; + EXPECT_FALSE(APIntOps::isShiftedMask(N, MaskVal)); // BUG + } + for (int I = 1; I < N - 1; ++I) { + APInt MaskVal = One.shl(I); + EXPECT_FALSE(APIntOps::isShiftedMask(N, MaskVal)); // BUG + } + for (int I = 1; I < N; ++I) { + APInt MaskVal = APInt::getHighBitsSet(N, I); + EXPECT_TRUE(APIntOps::isShiftedMask(N, MaskVal)); + } + } +} + #if defined(__clang__) // Disable the pragma warning from versions of Clang without -Wself-move #pragma clang diagnostic push