https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119086

            Bug ID: 119086
           Summary: __builtin_constant_p is missing opportunities
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: gjl at gcc dot gnu.org
  Target Milestone: ---

Created attachment 60634
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=60634&action=edit
bic.c: C test case

In the attached test case bic.c, there is this function:

static inline __attribute__((always_inline))
unsigned root2 (unsigned x)
{
  if (__builtin_constant_p ((unsigned) __builtin_sqrtf ((float) x)))
      return (unsigned) __builtin_sqrtf ((float) x);

  X = __builtin_constant_p ((unsigned) __builtin_sqrtf ((float) x));

  return expensive_root2 (x);
}

int main (void)
{
    X = root2 (15);
    return 0;
}

It tries to use constant folding when a compile-time constant is passed to
root2.

$ gcc -O2 bic.c -S -dp

Even though constant 15 is passed to root2, __builtin_constant_p ((unsigned)
__builtin_sqrtf ((float) x)) evaluates to false, AND that exact same argument
expression IS folded to a constant. main.s:

main:
.LFB2:
        .cfi_startproc
        subq    $8, %rsp        # 20    [c=4 l=4] 
pro_epilogue_adjust_stack_add_di/0
        .cfi_def_cfa_offset 16
# __builtin_constant_p(...) is false, so GCC takes the expensive path.
        movl    $15, %edi       # 6     [c=4 l=5]  *movsi_internal/0
# Even though __builtin_constant_p(...) is false, the compiler CAN fold the
expression
# to a compile-time constant: It sets X = 3 = (unsigned) sqrtf (15).
        movl    $3, X(%rip)     # 5     [c=4 l=10]  *movsi_internal/1
        call    expensive_root2 # 7     [c=9 l=5]  *call_value
        movl    %eax, X(%rip)   # 10    [c=4 l=6]  *movsi_internal/1
        xorl    %eax, %eax      # 28    [c=4 l=2]  *movdi_xor
        addq    $8, %rsp        # 23    [c=4 l=4] 
pro_epilogue_adjust_stack_add_di/0
        .cfi_def_cfa_offset 8
        ret             # 24    [c=0 l=1]  simple_return_internal

So it would be great if  __builtin_constant would return true in such cases.

I see this with v13.3 on x86_64 and also on current trunk for other targets
(and where sqrtf doesn't throw).

Notice that the behaviour is the same with
extern float sqrtf (float) __attribute__((nothrow));
and with sqrtf instead of __builtin_sqrtf.

Reply via email to