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.