User account creation filtered due to spam.

Bug 26724 - __builtin_constant_p fails to recognise function with constant return
Summary: __builtin_constant_p fails to recognise function with constant return
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.2.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
Keywords: missed-optimization
Depends on:
Reported: 2006-03-17 07:06 UTC by Anton Blanchard
Modified: 2015-12-04 05:41 UTC (History)
1 user (show)

See Also:
Known to work:
Known to fail:
Last reconfirmed: 2015-12-04 00:00:00


Note You need to log in before you can comment on or make changes to this bug.
Description Anton Blanchard 2006-03-17 07:06:26 UTC
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)
        return 0;

void inline foo(int A)
        if (!__builtin_constant_p(A))

void good()

void bad()
        if (!__builtin_constant_p(baz()))
Comment 1 Andrew Pinski 2006-03-17 15:20:33 UTC
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)
    return integer_zero_node;

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).
Comment 2 Anton Blanchard 2015-12-04 05:12:26 UTC
This issue is still present. The workaround Andrew suggests is good:

static inline int baz(void)
        return 0;

void bad()
        int i = baz();
        if (!__builtin_constant_p(i))