We noticed that __builtin_constant_p() sometimes fails to recognise a function that always returns 0 as being constant.
The code snippet below shows that gcc can work it out if we force the evaluation into an inline function. It looks like this postpones the evaluation of __builtin_constant_p to a later stage when we know the function always returns 0.
static inline int baz(void)
void inline foo(int A)
Confirmed, the problem is:
/* If this expression has side effects, show we don't know it to be a
constant. Likewise if it's a pointer or aggregate type since in
those case we only want literals, since those are only optimized
when generating RTL, not later.
And finally, if we are compiling an initializer, not code, we
need to return a definite result now; there's not going to be any
more optimization done. */
if (TREE_SIDE_EFFECTS (arglist)
|| AGGREGATE_TYPE_P (TREE_TYPE (arglist))
|| POINTER_TYPE_P (TREE_TYPE (arglist))
|| cfun == 0)
I don't know much about anything else but a work around is using a variable to store the results (yes this is stupid and it should not dependent on that).