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

            Bug ID: 108878
           Summary: Mis-optimization with splitting floating point into a
                    significand and exponent.
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: kargl at gcc dot gnu.org
  Target Milestone: ---

Fortran does not have an equivalent to C's frexp(), which splits a floating
point value into its significand and exponent.  Fortran has exponent() and
fraction() to grab the exponent and significand, respectively.  Consider,

% cat a.f90
subroutine foo(x, f, m)
   real, intent(in) :: x
   real, intent(out) :: f
   integer, intent(out) :: m
   m = exponent(x)
   f = fraction(x)
end subroutine

% gfortran -Ofast -fdump-tree-optimized -S a.f90
% more a.f90.254t.optimized
...
  <bb 2> [local count: 1073741824]:
  _5 = *x_4(D);
  __builtin_frexpf (_5, &D.4261);
  _1 = D.4261;
  *m_7(D) = _1;
  D.4261 ={v} {CLOBBER(eol)};
  _2 = __builtin_frexpf (_5, &D.4263);
  *f_11(D) = _2;
  D.4263 ={v} {CLOBBER(eol)};
  return;

As can be seen, __builtin_frexpf() is called twice.  The generated assembly
also shows two calls to frexpf().


% more a.s
...
        .cfi_offset 3, -32
        movq    %rsi, %rbx
        subq    $32, %rsp
        movss   (%rdi), %xmm1
        leaq    -20(%rbp), %rdi
        movaps  %xmm1, %xmm0
        movss   %xmm1, -36(%rbp)
        call    frexpf
        movl    -20(%rbp), %eax
        movss   -36(%rbp), %xmm1
        leaq    -20(%rbp), %rdi
        movl    %eax, (%r12)
        movaps  %xmm1, %xmm0
        call    frexpf
        movss   %xmm0, (%rbx)
        addq    $32, %rsp
        popq    %rbx
        popq    %r12
        popq    %rbp
        .cfi_def_cfa 7, 8
...

Reply via email to