> On Wed, 4 Aug 2021 at 03:27, Segher Boessenkool > <seg...@kernel.crashing.org> wrote: > > > > Hi! > > > > On Fri, Jul 23, 2021 at 04:23:42PM +0530, Prathamesh Kulkarni via Gcc wrote: > > > The constraint here is that, vshl_n<type> intrinsics require that the > > > second arg (__b), > > > should be an immediate value. > > > > Something that matches the "n" constraint, not necessarily a literal, > > but stricter than just "immediate". It probably is a good idea to allow > > only "integer constant expression"s, so that the validity of the source > > code does not depend on what the optimisers do with the code. > > > > > As Richard suggested, sth like: > > > void foo(int x __attribute__((literal_constant (min_val, max_val))); > > > > The Linux kernel has a macro __is_constexpr to test if something is an > > integer constant expression, see <linux/const.h> . That is a much > > better idea imo. There could be a builtin for that of course, but an > > attribute is less powerful, less usable, less useful. > Hi Segher, > Thanks for the suggestions. I am not sure tho if we could use a macro > similar to __is_constexpr > to check if parameter is constant inside an inline function (which is > the case for intrinsics) ? > > For eg: > #define __is_constexpr(x) \ > (sizeof(int) == sizeof(*(8 ? ((void *)((long)(x) * 0l)) : (int *)8))) > > inline int foo(const int x) > { > _Static_assert (__is_constexpr (x)); > return x; > } > > int main() > { > return foo (1); > } > > results in: > foo.c: In function ‘foo’: > foo.c:8:3: error: static assertion failed > 8 | _Static_assert (__is_constexpr (x)); > > Initially we tried to use __Static_assert (__builtin_constant_p (arg)) > for the same purpose but that did not work > because while parsing the intrinsic function, the FE cannot determine > if the arg is indeed a constant. > I guess the static assertion or __is_constexpr would work only if the > intrinsic were defined as a macro instead of an inline function ? > Or am I misunderstanding ?
You have to use it at the call site: #define __is_constexpr(x) \ (sizeof(int) == sizeof(*(8 ? ((void *)((long)(x) * 0l)) : (int *)8))) #define foo(x) foo(({ _Static_assert(__is_constexpr(x), "no ICE"); (x); })) inline int (foo)(const int x) { return x; } int main() { foo(1); int n = 1; foo(n); // error } --Martin