Re: [patch, Fortran] Fix PR 125914, suboptimal code for (-1.0)**integer(8)
Harald Anlauf <[email protected]> Sun, 21 Jun 2026 21:53:25 +0200
| Newsgroups | gmane.comp.gcc.patches,gmane.comp.gcc.fortran |
|---|---|
| Message-ID | <[email protected]> |
Hi Thomas!
Am 21.06.26 um 4:46 PM schrieb Thomas Koenig:
> Hello world,
>
> what it says in the ChangeLog entry. Regression-tested (and the test
> case makes sure there is no wrong-code regression).
>
> OK for trunk?
>
> Best regards
>
> Thomas
>
> Rewrite (-1.0)**n to (real) (1 - (n & 1) << 1)).
>
> The problem was that the optimization done for PR 57073 uses powi and
> friends, so it only applied to default integer exponent. The test
> case has an integer(kind=8) exponent, which is is calculated by
> calling a gfortran library function.
>
> There are two possible approaches: One would be to convert all
> integer types to default integer (because only the lowest-value
> bit matters to the result) and call the right __builtin_powi function.
> However, the generated code is suboptimal, see PR 125919. I therefore
> chose the variant which currently generates the best code.
This is OK.
> This requires the change to the power_6.f90 test case.
I am somewhat confused by the dg-pattern here. It is
! { dg-final { scan-tree-dump-not "__builtin_powif" "optimized" } }
In principle you do not want to see the __builtin_powif in the
original dump. If someone chose to add an optimization that expands
the __builtin_powif to something else, you do not realize it.
(This is not your fault, though.)
I find your testcase power_10.f90 quite interesting. It rather tests
floating-point arithmetic and may fail at different optimization levels
because of tests like
+ if (s4 /= 2.30965209) stop 11
(plus several more).
Please convince yourself and also test with other compilers.
Either add a suitable tolerance, or just test what needs to be
tested.
(One option: one can compare compile-time with run-time results,
which possibly makes it easier to trace testsuite fallout.)
Maybe use something like
real, parameter :: expected(*) = [((-1.0)**i,i=-10,10)]
etc.
The patch is OK with the above suitably considered.
Thanks,
Harald
> gcc/fortran/ChangeLog:
>
> PR fortran/125914
> * trans-expr.cc (gfc_conv_power_op): Rewrite (-1.0)**n into
> (real) (1 - (n & 1) << 1)).
>
> gcc/testsuite/ChangeLog:
>
> PR fortran/125914
> * gfortran.dg/power_6.f90: Remove scans for powi.
> * gfortran.dg/power_10.f90: New test.