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

            Bug ID: 128030
           Summary: FP state saved/restored in a procedure with no access
                    to the IEEE modules
           Product: gcc
           Version: 16.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: T.J.R.Bending at exeter dot ac.uk
  Target Milestone: ---

Created attachment 65905
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65905&action=edit
Reproducible

Target: x86_64-pc-linux-gnu
Keywords: missed-optimization
Attachments: repro5.f90 (test case + timing)

Description
----------------------------------------------------------------------------------
In repro5.f90 (attached) module a uses ieee_arithmetic privately and exports
only a function fa.  Modules b1 and b2 each wrap fa in a function; the only
difference is where "use a, only: fa" is placed:

    module b1                          module b2
     use a, only:fa                     implicit none
     implicit none                     contains
    contains                            real function g2(x)
     real function g1(x)                 use a, only:fa
      real, intent(in) :: x               real, intent(in) :: x
      g1 = fa(x)                          g2 = fa(x)
     end function g1                    end function g2
    end module b1                      end module b2

    $ gfortran -O2 -S repro5.f90
    __b1_MOD_g1:   no IEEE calls
    __b2_MOD_g2:   call _gfortran_ieee_procedure_entry ... _exit
    MAIN__:        wrapped as well (it uses b2)

g2 gets the FP-environment save/restore although nothing from
IEEE_ARITHMETIC, IEEE_EXCEPTIONS or IEEE_FEATURES is accessible in it.
Expected: g2 compiled like g1.  Cost (./a.out, EPYC 7773X): fa and g1
1.5 ns/call, g2 221-227 ns/call, with 10.2.0, 13.1.0 and 16.2.0 alike.

Not specific to ieee_is_nan: the same happens whatever module a takes from
the IEEE modules, including a bare "use, intrinsic :: ieee_arithmetic" with
nothing referenced, ieee_get_status from IEEE_EXCEPTIONS, and ieee_datatype
from IEEE_FEATURES, which holds only named constants.  No IEEE use in a:
no wrap.

Mechanism: is_ieee_module_used() in gcc/fortran/trans-decl.cc flags any
symbol in the procedure's own namespace whose from_intmod is an IEEE module.
A procedure-level USE of a brings a's private IEEE symbols into that
namespace, so the test fires without any access.  Conversely, symbols reached
by host association are in the parent namespace and are not traversed: a
procedure that does call ieee_is_nan through its host's USE (an internal
function, say) gets no save/restore, which by PR 91690 comment 8 it should.
The test should look at what is accessible to the procedure.

Environment: gcc version 16.2.0 (GCC), x86_64-pc-linux-gnu, Rocky Linux 9,
"Configured with: ../configure --prefix=/cosma/local/gcc/16.2.0
--enable-languages=c,c++,fortran --disable-multilib".  Also 10.2.0, 11.1.0,
11.5.0 (Red Hat), 13.1.0, 14.1.0, 15.2.0; not tried on trunk.  Same at -O0
and -O3; -Wall -Wextra gives no warning; single self-contained file, so no
preprocessed source.  ifort, ifx, flang and nvfortran emit no save/restore
in any of these procedures.

Reply via email to