[Bug fortran/120099] [16 regression] gfortran.dg/specifics_1.f90 FAILs since r16-372-g064cac730f88dc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120099 anlauf at gcc dot gnu.org changed: What|Removed |Added Resolution|--- |FIXED Status|NEW |RESOLVED --- Comment #23 from anlauf at gcc dot gnu.org --- Fixed.
[Bug fortran/120099] [16 regression] gfortran.dg/specifics_1.f90 FAILs since r16-372-g064cac730f88dc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120099 --- Comment #22 from GCC Commits --- The master branch has been updated by Harald Anlauf : https://gcc.gnu.org/g:bf98b735ae01c652f641b824a7c4e1d575b5b6d8 commit r16-734-gbf98b735ae01c652f641b824a7c4e1d575b5b6d8 Author: Harald Anlauf Date: Sun May 18 22:42:26 2025 +0200 Fortran: fix FAIL of gfortran.dg/specifics_1.f90 after r16-372 [PR120099] After commit r16-372, testcase gfortran.dg/specifics_1.f90 started to FAIL at -O2 and higher, as DCE lead to elimination of evaluations of Fortran specific intrinsics returning complex results and with -ff2c. As the Fortran runtime library is compiled with -fno-f2c, the frontend generates calls to wrapper subroutines _gfortran_f2c_specific_* that return their result by reference via their first argument when this is needed. This is e.g. the case when specific names of the intrinsics are used for passing as actual argument to procedures. These wrappers are not pure in the GCC IR sense, even if the Fortran intrinsics are. Therefore gfc_return_by_reference must return true for these. PR fortran/120099 gcc/fortran/ChangeLog: * trans-types.cc (gfc_return_by_reference): Intrinsic functions returning complex numbers may return their result by reference with -ff2c.
[Bug fortran/120099] [16 regression] gfortran.dg/specifics_1.f90 FAILs since r16-372-g064cac730f88dc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120099 --- Comment #21 from anlauf at gcc dot gnu.org --- Patch from comment#16 submitted: https://gcc.gnu.org/pipermail/fortran/2025-May/062180.html I hope I got the description of the issue right in the changelog.
[Bug fortran/120099] [16 regression] gfortran.dg/specifics_1.f90 FAILs since r16-372-g064cac730f88dc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120099 --- Comment #20 from anlauf at gcc dot gnu.org --- Does anybody know why there is the following comment preceding the suspcious block: /* Possibly return complex numbers by reference for g77 compatibility. We don't do this for calls to intrinsics (as the library uses the -fno-f2c calling convention), nor for calls to functions which always require an explicit interface, as no compatibility problems can arise there. */ In view of the current observations this seems wrong.
[Bug fortran/120099] [16 regression] gfortran.dg/specifics_1.f90 FAILs since r16-372-g064cac730f88dc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120099 --- Comment #19 from Andrew Pinski --- (In reply to anlauf from comment #18) > (In reply to Thomas Koenig from comment #17) > > (In reply to Andrew Pinski from comment #15) > > > (In reply to anlauf from comment #14) > > > > This fixes the reduced testcase for me, but gfortran.dg/specifics_1.f90 > > > > still fails here. > > > > > > Which means there are many more intrinsics here that need this treatment. > > > The testcase has just subroutine test_* calls in the "program" (main) in > > > it > > > which you can narrow down which ones are failing ones are failing. > > > > The following tests fail (checked with a quick&dirty perl script): > > > > call test_c (conjg, (1.2,-4.), conjg((1.2,-4.))) > > call test_c (ccos, (1.2,-4.), ccos((1.2,-4.))) > > call test_c (cexp, (1.2,-4.), cexp((1.2,-4.))) > > call test_c (clog, (1.2,-4.), clog((1.2,-4.))) > > call test_c (csin, (1.2,-4.), csin((1.2,-4.))) > > call test_c (csqrt, (1.2,-4.), csqrt((1.2,-4.))) > > call test_z (dconjg, (1.2d0,-4.d0), dconjg((1.2d0,-4.d0))) > > call test_z (cdcos, (1.2d0,-4.d0), cdcos((1.2d0,-4.d0))) > > call test_z (zcos, (1.2d0,-4.d0), zcos((1.2d0,-4.d0))) > > call test_z (cdexp, (1.2d0,-4.d0), cdexp((1.2d0,-4.d0))) > > call test_z (zexp, (1.2d0,-4.d0), zexp((1.2d0,-4.d0))) > > call test_z (cdlog, (1.2d0,-4.d0), cdlog((1.2d0,-4.d0))) > > call test_z (zlog, (1.2d0,-4.d0), zlog((1.2d0,-4.d0))) > > call test_z (cdsin, (1.2d0,-4.d0), cdsin((1.2d0,-4.d0))) > > call test_z (zsin, (1.2d0,-4.d0), zsin((1.2d0,-4.d0))) > > call test_z (cdsqrt, (1.2d0,-4.d0), cdsqrt((1.2d0,-4.d0))) > > call test_z (zsqrt, (1.2d0,-4.d0), zsqrt((1.2d0,-4.d0))) > > Isn't that the full list of intrinsics returning complex results? I think so.
[Bug fortran/120099] [16 regression] gfortran.dg/specifics_1.f90 FAILs since r16-372-g064cac730f88dc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120099 --- Comment #18 from anlauf at gcc dot gnu.org --- (In reply to Thomas Koenig from comment #17) > (In reply to Andrew Pinski from comment #15) > > (In reply to anlauf from comment #14) > > > This fixes the reduced testcase for me, but gfortran.dg/specifics_1.f90 > > > still fails here. > > > > Which means there are many more intrinsics here that need this treatment. > > The testcase has just subroutine test_* calls in the "program" (main) in it > > which you can narrow down which ones are failing ones are failing. > > The following tests fail (checked with a quick&dirty perl script): > > call test_c (conjg, (1.2,-4.), conjg((1.2,-4.))) > call test_c (ccos, (1.2,-4.), ccos((1.2,-4.))) > call test_c (cexp, (1.2,-4.), cexp((1.2,-4.))) > call test_c (clog, (1.2,-4.), clog((1.2,-4.))) > call test_c (csin, (1.2,-4.), csin((1.2,-4.))) > call test_c (csqrt, (1.2,-4.), csqrt((1.2,-4.))) > call test_z (dconjg, (1.2d0,-4.d0), dconjg((1.2d0,-4.d0))) > call test_z (cdcos, (1.2d0,-4.d0), cdcos((1.2d0,-4.d0))) > call test_z (zcos, (1.2d0,-4.d0), zcos((1.2d0,-4.d0))) > call test_z (cdexp, (1.2d0,-4.d0), cdexp((1.2d0,-4.d0))) > call test_z (zexp, (1.2d0,-4.d0), zexp((1.2d0,-4.d0))) > call test_z (cdlog, (1.2d0,-4.d0), cdlog((1.2d0,-4.d0))) > call test_z (zlog, (1.2d0,-4.d0), zlog((1.2d0,-4.d0))) > call test_z (cdsin, (1.2d0,-4.d0), cdsin((1.2d0,-4.d0))) > call test_z (zsin, (1.2d0,-4.d0), zsin((1.2d0,-4.d0))) > call test_z (cdsqrt, (1.2d0,-4.d0), cdsqrt((1.2d0,-4.d0))) > call test_z (zsqrt, (1.2d0,-4.d0), zsqrt((1.2d0,-4.d0))) Isn't that the full list of intrinsics returning complex results?
[Bug fortran/120099] [16 regression] gfortran.dg/specifics_1.f90 FAILs since r16-372-g064cac730f88dc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120099 Thomas Koenig changed: What|Removed |Added CC||tkoenig at gcc dot gnu.org --- Comment #17 from Thomas Koenig --- (In reply to Andrew Pinski from comment #15) > (In reply to anlauf from comment #14) > > This fixes the reduced testcase for me, but gfortran.dg/specifics_1.f90 > > still fails here. > > Which means there are many more intrinsics here that need this treatment. > The testcase has just subroutine test_* calls in the "program" (main) in it > which you can narrow down which ones are failing ones are failing. The following tests fail (checked with a quick&dirty perl script): call test_c (conjg, (1.2,-4.), conjg((1.2,-4.))) call test_c (ccos, (1.2,-4.), ccos((1.2,-4.))) call test_c (cexp, (1.2,-4.), cexp((1.2,-4.))) call test_c (clog, (1.2,-4.), clog((1.2,-4.))) call test_c (csin, (1.2,-4.), csin((1.2,-4.))) call test_c (csqrt, (1.2,-4.), csqrt((1.2,-4.))) call test_z (dconjg, (1.2d0,-4.d0), dconjg((1.2d0,-4.d0))) call test_z (cdcos, (1.2d0,-4.d0), cdcos((1.2d0,-4.d0))) call test_z (zcos, (1.2d0,-4.d0), zcos((1.2d0,-4.d0))) call test_z (cdexp, (1.2d0,-4.d0), cdexp((1.2d0,-4.d0))) call test_z (zexp, (1.2d0,-4.d0), zexp((1.2d0,-4.d0))) call test_z (cdlog, (1.2d0,-4.d0), cdlog((1.2d0,-4.d0))) call test_z (zlog, (1.2d0,-4.d0), zlog((1.2d0,-4.d0))) call test_z (cdsin, (1.2d0,-4.d0), cdsin((1.2d0,-4.d0))) call test_z (zsin, (1.2d0,-4.d0), zsin((1.2d0,-4.d0))) call test_z (cdsqrt, (1.2d0,-4.d0), cdsqrt((1.2d0,-4.d0))) call test_z (zsqrt, (1.2d0,-4.d0), zsqrt((1.2d0,-4.d0)))
[Bug fortran/120099] [16 regression] gfortran.dg/specifics_1.f90 FAILs since r16-372-g064cac730f88dc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120099 --- Comment #16 from anlauf at gcc dot gnu.org --- (In reply to Andrew Pinski from comment #15) > (In reply to anlauf from comment #14) > > This fixes the reduced testcase for me, but gfortran.dg/specifics_1.f90 > > still fails here. > > Which means there are many more intrinsics here that need this treatment. > The testcase has just subroutine test_* calls in the "program" (main) in it > which you can narrow down which ones are failing ones are failing. The following works: diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc index f8980754685..eb45abe97d5 100644 --- a/gcc/fortran/trans-types.cc +++ b/gcc/fortran/trans-types.cc @@ -3237,7 +3237,7 @@ gfc_return_by_reference (gfc_symbol * sym) if (flag_f2c && sym->ts.type == BT_COMPLEX && !sym->attr.pointer && !sym->attr.allocatable - && !sym->attr.intrinsic && !sym->attr.always_explicit) + && !sym->attr.always_explicit) return 1; return 0; I wonder whether the 20 year old comment before this block was ever correct.
[Bug fortran/120099] [16 regression] gfortran.dg/specifics_1.f90 FAILs since r16-372-g064cac730f88dc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120099 --- Comment #15 from Andrew Pinski --- (In reply to anlauf from comment #14) > This fixes the reduced testcase for me, but gfortran.dg/specifics_1.f90 > still fails here. Which means there are many more intrinsics here that need this treatment. The testcase has just subroutine test_* calls in the "program" (main) in it which you can narrow down which ones are failing ones are failing.
[Bug fortran/120099] [16 regression] gfortran.dg/specifics_1.f90 FAILs since r16-372-g064cac730f88dc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120099 --- Comment #14 from anlauf at gcc dot gnu.org --- (In reply to anlauf from comment #12) > Good point. Tentative patch which excepts (d)conjg: > > diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc > index f8980754685..e1e4f1604cd 100644 > --- a/gcc/fortran/trans-types.cc > +++ b/gcc/fortran/trans-types.cc > @@ -3237,7 +3237,10 @@ gfc_return_by_reference (gfc_symbol * sym) >if (flag_f2c && sym->ts.type == BT_COMPLEX >&& !sym->attr.pointer >&& !sym->attr.allocatable > - && !sym->attr.intrinsic && !sym->attr.always_explicit) > + && (!sym->attr.intrinsic > + || strcmp (sym->name, "conjg") == 0 > + || strcmp (sym->name, "dconjg") == 0) > + && !sym->attr.always_explicit) > return 1; > >return 0; This fixes the reduced testcase for me, but gfortran.dg/specifics_1.f90 still fails here. :-(
[Bug fortran/120099] [16 regression] gfortran.dg/specifics_1.f90 FAILs since r16-372-g064cac730f88dc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120099 --- Comment #13 from Andrew Pinski --- (In reply to anlauf from comment #12) > (In reply to Andrew Pinski from comment #11) > > I wonder why gfc_return_by_reference is not returning true here because I > > think that would be idea here. > > Good point. Tentative patch which excepts (d)conjg: > > diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc > index f8980754685..e1e4f1604cd 100644 > --- a/gcc/fortran/trans-types.cc > +++ b/gcc/fortran/trans-types.cc > @@ -3237,7 +3237,10 @@ gfc_return_by_reference (gfc_symbol * sym) >if (flag_f2c && sym->ts.type == BT_COMPLEX >&& !sym->attr.pointer >&& !sym->attr.allocatable > - && !sym->attr.intrinsic && !sym->attr.always_explicit) > + && (!sym->attr.intrinsic > + || strcmp (sym->name, "conjg") == 0 > + || strcmp (sym->name, "dconjg") == 0) > + && !sym->attr.always_explicit) > return 1; > >return 0; Does it fix the whole original testcase? Because I just tried to reduce it into one of the failures
[Bug fortran/120099] [16 regression] gfortran.dg/specifics_1.f90 FAILs since r16-372-g064cac730f88dc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120099 --- Comment #12 from anlauf at gcc dot gnu.org --- (In reply to Andrew Pinski from comment #11) > I wonder why gfc_return_by_reference is not returning true here because I > think that would be idea here. Good point. Tentative patch which excepts (d)conjg: diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc index f8980754685..e1e4f1604cd 100644 --- a/gcc/fortran/trans-types.cc +++ b/gcc/fortran/trans-types.cc @@ -3237,7 +3237,10 @@ gfc_return_by_reference (gfc_symbol * sym) if (flag_f2c && sym->ts.type == BT_COMPLEX && !sym->attr.pointer && !sym->attr.allocatable - && !sym->attr.intrinsic && !sym->attr.always_explicit) + && (!sym->attr.intrinsic + || strcmp (sym->name, "conjg") == 0 + || strcmp (sym->name, "dconjg") == 0) + && !sym->attr.always_explicit) return 1; return 0;
[Bug fortran/120099] [16 regression] gfortran.dg/specifics_1.f90 FAILs since r16-372-g064cac730f88dc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120099 --- Comment #11 from Andrew Pinski --- (In reply to anlauf from comment #10) > (In reply to Andrew Pinski from comment #9) > > Can't be done for the f2c functions. > > libgfortran/intrinsics/f2c_specifics.F90 has: > > subroutine _gfortran_f2c_specific__conjg_4 (res, parm) > COMPLEX, intent (in) :: parm > COMPLEX, intent (out) :: res > res = conjg (parm) > end subroutine > > So this is actually really a pure subroutine with no side-effects in the > fortran sense (the normal non-f2c counterpart is a pure elemental function). > 'parm' is input, 'res' is output. > > What is the expected way to do this? It might be pure in the fortran sense but it is not pure in the GCC IR sense since it stores to the first argument. I wonder why gfc_return_by_reference is not returning true here because I think that would be idea here.
[Bug fortran/120099] [16 regression] gfortran.dg/specifics_1.f90 FAILs since r16-372-g064cac730f88dc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120099 anlauf at gcc dot gnu.org changed: What|Removed |Added CC||anlauf at gcc dot gnu.org --- Comment #10 from anlauf at gcc dot gnu.org --- (In reply to Andrew Pinski from comment #9) > Can't be done for the f2c functions. libgfortran/intrinsics/f2c_specifics.F90 has: subroutine _gfortran_f2c_specific__conjg_4 (res, parm) COMPLEX, intent (in) :: parm COMPLEX, intent (out) :: res res = conjg (parm) end subroutine So this is actually really a pure subroutine with no side-effects in the fortran sense (the normal non-f2c counterpart is a pure elemental function). 'parm' is input, 'res' is output. What is the expected way to do this?
[Bug fortran/120099] [16 regression] gfortran.dg/specifics_1.f90 FAILs since r16-372-g064cac730f88dc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120099
Andrew Pinski changed:
What|Removed |Added
Component|ipa |fortran
--- Comment #9 from Andrew Pinski ---
I think this is a front-end issue with gfortran_f2c functions:
```
/* Set attributes for PURE functions. A call to PURE function in the
Fortran 95 sense is both pure and without side effects in the C
sense. */
if (sym->attr.pure || sym->attr.implicit_pure)
{
if (sym->attr.function && !gfc_return_by_reference (sym))
DECL_PURE_P (fndecl) = 1;
/* TODO: check if pure SUBROUTINEs don't have INTENT(OUT)
parameters and don't use alternate returns (is this
allowed?). In that case, calls to them are meaningless, and
can be optimized away. See also in build_function_decl(). */
TREE_SIDE_EFFECTS (fndecl) = 0;
}
```
Can't be done for the f2c functions.
