This is the mail archive of the 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 10:52 AM, Charles Baylis
<> 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__ .


> I'm trying to resolve some problems with error reporting for NEON (ARM
> SIMD/vector) intrinsics.
> eg
> 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]