[cfe-dev] __attribute__((enable_if(...))) for de-macroifying the builtin headers

Nick Lewycky nlewycky at google.com
Wed Apr 15 10:46:07 PDT 2015


On 15 April 2015 at 10:27, Sean Silva <chisophugis at gmail.com> wrote:

> In the post-commit of r231792, I suggested the idea of using
> __attribute__((enable_if(...))) for avoiding the mess of the macros in the
> builtin headers. AFAIK, the macros are currently used to make sure that the
> "immediates" are constant expressions, piggybacking on the constant
> expression check in the __builtin_* call.
>
> I've attached a file with a proof-of-concept for using
> __attribute__((enable_if(...))) for this purpose. I originally though using
> __builtin_constant_p in the enable_if, but that turns out to not be
> necessary (see the docs:
> http://clang.llvm.org/docs/AttributeReference.html#enable-if ; the
> enable_if condition fails for non-constant expressions anyway). The core is:
>
> // Current builtin headers:
> //
> //#define _mm256_insertf128_si256(V1, V2, M) __extension__ ({ \
> //  (__m256i)__builtin_shufflevector( \
> //    (__v4di)(V1), \
> //    (__v4di)_mm256_castsi128_si256((__m128i)(V2)), \
> //    (((M) & 1) ? 0 : 4), \
> //    (((M) & 1) ? 1 : 5), \
> //    (((M) & 1) ? 4 : 2), \
> //    (((M) & 1) ? 5 : 3) );})
>
> // A bit cleaner.
> static __inline __attribute__((__always_inline__, __nodebug__))
> __m256i _mm256_insertf128_si256(__m256i __a, __m128i __b, int __imm8)
> __attribute__((enable_if(__imm8, "'__imm8' must be a constant")))
> {
>   if (__imm8 & 1)
>     return __builtin_shufflevector(__a, _mm256_castsi128_si256(__b), 0, 1,
> 4, 5);
>   else
>     return __builtin_shufflevector(__a, _mm256_castsi128_si256(__b), 4, 5,
> 2, 3);
> }
>

I think:

static __inline __attribute__((__always_inline__, __nodebug__))
__m256i _mm256_insertf128_si256(__m256i __a, __m128i __b, int __imm8)
__attribute__((enable_if(__imm8 & 1 == 1, "'__imm8' must be a constant")))
{
  return __builtin_shufflevector(__a, _mm256_castsi128_si256(__b), 0, 1, 4,
5);
}

static __inline __attribute__((__always_inline__, __nodebug__))
__m256i _mm256_insertf128_si256(__m256i __a, __m128i __b, int __imm8)
__attribute__((enable_if(__imm8 & 1 == 0, "'__imm8' must be a constant")))
{
  return __builtin_shufflevector(__a, _mm256_castsi128_si256(__b), 4, 5, 2,
3);
}

>
Nick, are you okay using enable_if for this? It's sort of a hack but if we
> are going to be carrying this attribute around forever (has it reached that
> level of compatibility guarantee yet?), we might as well use it to solve
> this problem for us.
>

Attribute enable_if is here to stay, though it may change meaning in corner
cases (notably multiple enable_if's on a single function). Using it in the
compiler's own header files is fine. Does anyone ever try to take the
address of _mm256_insertf128_si256 (I assume not if it's a macro)?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20150415/d9e6842e/attachment.html>


More information about the cfe-dev mailing list