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 ...