Hi,
I noticed gcc generates inconsistent codes for same function for builtin calls.

compile following program:
----------------------------------------------
#include <math.h>
int a(float x) {
      return sqrtf(x);
}
int b(float x) {
      return sqrtf(x);
}

With command:
arm-none-eabi-gcc -mthumb -mhard-float -mfpu=fpv4-sp-d16
-mcpu=cortex-m4 -O0 -S a.c -o a.S

The generated assembly codes is like:
----------------------------------------------
a:
        @ args = 0, pretend = 0, frame = 8
        @ frame_needed = 1, uses_anonymous_args = 0
        push    {r7, lr}
        sub     sp, sp, #8
        add     r7, sp, #0
        fsts    s0, [r7, #4]
        flds    s15, [r7, #4]
        fsqrts  s15, s15
        fcmps   s15, s15
        fmstat
        beq     .L2
        flds    s0, [r7, #4]
        bl      sqrtf
        fcpys   s15, s0
.L2:
        ftosizs s15, s15
        fmrs    r3, s15 @ int
        mov     r0, r3
        add     r7, r7, #8
        mov     sp, r7
        pop     {r7, pc}
        .size   a, .-a
        .align  2
        .global b
        .thumb
        .thumb_func
        .type   b, %function
b:
        @ args = 0, pretend = 0, frame = 8
        @ frame_needed = 1, uses_anonymous_args = 0
        push    {r7, lr}
        sub     sp, sp, #8
        add     r7, sp, #0
        fsts    s0, [r7, #4]
        flds    s0, [r7, #4]
        bl      sqrtf
        fcpys   s15, s0
        ftosizs s15, s15
        fmrs    r3, s15 @ int
        mov     r0, r3
        add     r7, r7, #8
        mov     sp, r7
        pop     {r7, pc}
        .size   b, .-b


The cause is in function expand_builtin, gcc checks following conditions:
----------------------------------------------
  /* When not optimizing, generate calls to library functions for a certain
     set of builtins.  */
  if (!optimize
      && !called_as_built_in (fndecl)
      && DECL_ASSEMBLER_NAME_SET_P (fndecl)
      && fcode != BUILT_IN_ALLOCA
      && fcode != BUILT_IN_ALLOCA_WITH_ALIGN
      && fcode != BUILT_IN_FREE)
    return expand_call (exp, target, ignore);

The control flow is:
1, DECL_ASSEMBLER_NAME_SET_P (fndecl) is false at the first time when
compiling a;
2, It is then set in following codes when expanding sqrtf call in function a;
3, When compiling function b, gcc checks DECL_ASSEMBLER_NAME_SET_P (fndecl)
     again and this time it's true;

I am a little confused why we check DECL_ASSEMBLER_NAME_SET_P here.
Does it have special meaning?

Thanks in advance.

-- 
Best Regards.

Reply via email to