__builtin_constant_p and floating-point constants


please consider the following (not very useful) program:

inline int foo(float a, int b)
  if (__builtin_constant_p(a))
    return int(a) * b;
    return a * b;

int bar(int b)
  return foo(23.0f, b);

int main(int, char**)

If <a> is a constant when <foo> is called, only its integer part should be multiplied with <b>, resulting
in an integer multiplication. If <a> is not constant, <b> should be converted to a float, multiplied with
<a> and truncated back to an <int> instead.

Apple's GCC 4.2.1 handles this as expected ("gcc RandomTest.cpp -S -O3 -o -", small cleanups of the output):

  pushq %rbp
  movq %rsp, %rbp
  imull $23, %edi, %eax

Clang r132676 on the other hand ("clang RandomTest.cpp -S -O3 -o -", again slightly cleaned output):

  pushq %rbp
  movq %rsp, %rbp
  cvtsi2ss %edi, %xmm0
  mulss LCPI0_0(%rip), %xmm0
  cvttss2si %xmm0, %eax
  popq %rbp

It seems that clang does not evaluate __builtin_constant_p in the same way as GCC does. Is this a bug
or intentional? (personally, I would think the latter, as there does not seem to exist a reason why
__builtin_constant_p should not work with floating-point constants)

With many thanks in advance,

P.S:: Apple's LLVM-GCC 4.2 produces the same result as clang.


Essentially, the issue here is that we fold __builtin_constant_p
before the inliner runs.