[llvm] r300710 - [Support] Add some helpers to generate bitmasks.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 19 11:52:05 PDT 2017


Can you elaborate?  What's UB about the branch-free version?

On Wed, Apr 19, 2017 at 11:13 AM Benjamin Kramer <benny.kra at gmail.com>
wrote:

> On Wed, Apr 19, 2017 at 5:45 PM, Zachary Turner via llvm-commits
> <llvm-commits at lists.llvm.org> wrote:
> > Author: zturner
> > Date: Wed Apr 19 10:45:31 2017
> > New Revision: 300710
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=300710&view=rev
> > Log:
> > [Support] Add some helpers to generate bitmasks.
> >
> > Frequently you you want a bitmask consisting of a specified
> > number of 1s, either at the beginning or end of a word.
> >
> > The naive way to do this is to write
> >
> > template<typename T>
> > T leadingBitMask(unsigned N) {
> >   return (T(1) << N) - 1;
> > }
> >
> > but using this function you cannot produce a word with every
> > bit set to 1 (i.e. leadingBitMask<uint8_t>(8)) because left
> > shift is undefined when N is greater than or equal to the
> > number of bits in the word.
> >
> > This patch provides an efficient, branch-free implementation
> > that works for all values of N in [0, CHAR_BIT*sizeof(T)]
> >
> > Differential Revision: https://reviews.llvm.org/D32212
> >
> > Modified:
> >     llvm/trunk/include/llvm/Support/MathExtras.h
> >     llvm/trunk/unittests/Support/MathExtrasTest.cpp
> >
> > Modified: llvm/trunk/include/llvm/Support/MathExtras.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/MathExtras.h?rev=300710&r1=300709&r2=300710&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/include/llvm/Support/MathExtras.h (original)
> > +++ llvm/trunk/include/llvm/Support/MathExtras.h Wed Apr 19 10:45:31 2017
> > @@ -198,6 +198,21 @@ template <typename T> T findFirstSet(T V
> >    return countTrailingZeros(Val, ZB_Undefined);
> >  }
> >
> > +/// \brief Create a bitmask with the N right-most bits set to 1, and
> all other
> > +/// bits set to 0.  Only unsigned types are allowed.
> > +template <typename T> T maskTrailingOnes(unsigned N) {
> > +  static_assert(std::is_unsigned<T>::value, "Invalid type!");
> > +  const unsigned Bits = CHAR_BIT * sizeof(T);
> > +  assert(N <= Bits && "Invalid bit index");
> > +  return -T(N != 0) & (T(-1) >> (Bits - N));
>
> This would be safe with LLVM's definition of UB, but not with C++'s.
> Changed it to branchy in r300721.
>
> > +}
> > +
> > +/// \brief Create a bitmask with the N left-most bits set to 1, and all
> other
> > +/// bits set to 0.  Only unsigned types are allowed.
> > +template <typename T> T maskLeadingOnes(unsigned N) {
> > +  return ~maskTrailingOnes<T>(CHAR_BIT * sizeof(T) - N);
> > +}
> > +
> >  /// \brief Get the index of the last set bit starting from the least
> >  ///   significant bit.
> >  ///
> >
> > Modified: llvm/trunk/unittests/Support/MathExtrasTest.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/MathExtrasTest.cpp?rev=300710&r1=300709&r2=300710&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/unittests/Support/MathExtrasTest.cpp (original)
> > +++ llvm/trunk/unittests/Support/MathExtrasTest.cpp Wed Apr 19 10:45:31
> 2017
> > @@ -66,6 +66,26 @@ TEST(MathExtras, countLeadingZeros) {
> >    }
> >  }
> >
> > +TEST(MathExtras, onesMask) {
> > +  EXPECT_EQ(0U, maskLeadingOnes<uint8_t>(0));
> > +  EXPECT_EQ(0U, maskTrailingOnes<uint8_t>(0));
> > +  EXPECT_EQ(0U, maskLeadingOnes<uint16_t>(0));
> > +  EXPECT_EQ(0U, maskTrailingOnes<uint16_t>(0));
> > +  EXPECT_EQ(0U, maskLeadingOnes<uint32_t>(0));
> > +  EXPECT_EQ(0U, maskTrailingOnes<uint32_t>(0));
> > +  EXPECT_EQ(0U, maskLeadingOnes<uint64_t>(0));
> > +  EXPECT_EQ(0U, maskTrailingOnes<uint64_t>(0));
> > +
> > +  EXPECT_EQ(0x00000003U, maskTrailingOnes<uint32_t>(2U));
> > +  EXPECT_EQ(0xC0000000U, maskLeadingOnes<uint32_t>(2U));
> > +
> > +  EXPECT_EQ(0x000007FFU, maskTrailingOnes<uint32_t>(11U));
> > +  EXPECT_EQ(0xFFE00000U, maskLeadingOnes<uint32_t>(11U));
> > +
> > +  EXPECT_EQ(0xFFFFFFFFU, maskTrailingOnes<uint32_t>(32U));
> > +  EXPECT_EQ(0xFFFFFFFFU, maskLeadingOnes<uint32_t>(32U));
> > +}
> > +
> >  TEST(MathExtras, findFirstSet) {
> >    uint8_t Z8 = 0;
> >    uint16_t Z16 = 0;
> >
> >
> > _______________________________________________
> > llvm-commits mailing list
> > llvm-commits at lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170419/a05db2c1/attachment.html>


More information about the llvm-commits mailing list