This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Restricting arguments to intrinsic functions


On Thu, Oct 23, 2014 at 11:00 AM, Andrew Pinski <pinskia@gmail.com> wrote:
> On Thu, Oct 23, 2014 at 10:52 AM, Charles Baylis
> <charles.baylis@linaro.org> wrote:
>> Hi
>>
>> ( tl;dr: How do I handle intrinsic or builtin functions where there
>> are restrictions on the arguments which can't be represented in a C
>> function prototype? Do other ports have this problem, how do they
>> solve it? Language extension for C++98 to provide static_assert?)
>
> The attribute __artificial__ .

Long example:
extern __inline void __attribute__((__gnu_inline__, __always_inline__,
__artificial__))
_mm_stream_sd (double * __P, __m128d __Y)
{
  __builtin_ia32_movntsd (__P, (__v2df) __Y);
}

Don't use static inline either because it is not valid thing to do
from a template in C++98.

Thanks,
Andrew


>
> Thanks,
> Andrew
>
>
>>
>> I'm trying to resolve some problems with error reporting for NEON (ARM
>> SIMD/vector) intrinsics.
>> eg https://bugs.linaro.org/show_bug.cgi?id=418
>>
>> The NEON intrinsics are defined in a header file, arm_neon.h, which
>> includes type definitions and inline functions which implement the
>> intrinsics in terms of __builtin functions provided by gcc.
>>
>> A number of these intrinsics (eg shift by a constant, set/get Nth lane
>> of vector) are defined to take a compile-time integer constant as one
>> of their arguments. For example:
>>
>> The vshrn_n_s16 (narrowing vector shift right by a constant) intrinsic
>> is defined as:
>>     __extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
>>     vshrn_n_s16 (int16x8_t __a, const int __b)
>>     {
>>       return (int8x8_t)__builtin_neon_vshrn_nv8hi (__a, __b, 1);
>>     }
>>
>> These examples demonstrate some valid and invalid use
>>     int8x16_t v = vshrn_n_u16(v1, 5); // valid
>>
>>     int8x16_t v = vshrn_n_u16(v1, 20); // invalid, constant is out of range
>>
>>     int x = 5;
>>     int8x16_t v = vshrn_n_u16(v1, x); // invalid, shift amount is not
>> a compile-time constant
>>
>>
>> Presently, the ARM/Aarch64 backends include some checks, but this
>> doesn't work very well, as it allows invalid operations to persist too
>> long. By the time the error is raised, the original source position is
>> lost. Therefore, I would like to add some error checking at an earlier
>> stage, with various options coming to mind:
>>
>> 1. Somehow arrange for __builtin_neon_vshrn_nv8hi to require a
>> constant integer in the prescribed range as the 2nd argument.
>>
>> 2. Redefine the intrinsic function in arm_neon.h to include
>>    _Static_assert(__b >= 1 && __b <=8, "Shift amount out of range");
>>
>> 3. Put a static assert into a macro
>> #define vshrn_n_s16(a,b) \
>>    ({ _Static_assert(__b >= 1 && __b <=8, "Shift amount out of
>> range"); _vshrn_n_s16(a,b); })
>>
>> 4. Some sort of language extension so that inline functions can
>> require compile-time constants for suitably annotated arguments.
>> eg
>>     static __inline int8x8_t __attribute__ ((__always_inline__))
>>     vshrn_n_s16 (int16x8_t __a, const int
>> __attribute((constant_range(1,8))) __b)
>>
>>
>> Pros/cons of each approach:
>> 1. somewhat complex to implement, errors are reported in arm_neon.h,
>> rather than at the source line in the user's code.
>>
>> 2. Easy to implement. Can be adapted to support C++11 using
>> static_assert, but doesn't work for C++98 (maybe a language extension
>> is possible to provide the same functionality as __static_assert in
>> C++98?) . Errors are reported in arm_neon.h, rather than user's code.
>>
>> 3. Easy to implement, the compiler will indicate the source line where
>> the macro was used, so that the user can find the location of their
>> error easily. Can also be adapted to support C++11 using
>> static_assert, but doesn't work for C++98.
>>
>> 4. Results in high quality error messages, but is complex to implement.
>>
>> In my view, options 1&4 are potentially complex to implement. I favour
>> one of 2 or 3, with an extension to C++98 to provide
>> static_assert-like functionality. This is not unprecedented, as
>> _Static_assert is provided in all C language dialects.
>>
>> I am interested in views on the relative merits of these approaches.
>>
>> Thanks
>> Charles


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]