https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128278
--- Comment #3 from Peter Knowles <KnowlesPJ at Cardiff dot ac.uk> ---
Agreed with comment 1: this is a back-end/calling-convention problem, and
IPA-SRA only exposes it. A LOGICAL(8) dummy with the VALUE attribute that is
passed on the stack (5th or later argument under the Windows x64 convention)
is mis-passed in the same way without IPA-SRA, at -O0 too.
Re comment 2: neither test case uses -fdefault-integer-8. Both declare
LOGICAL(8) explicitly and fail with plain gfortran. The flag is only how the
original application (Molpro) gets 8-byte default logicals.
Attached pr2.f90 (self-contained, no INCLUDE or preprocessing). The expected
output is OK:
$ gfortran -O0 -Wall -Wextra pr2.f90 -o pr2.exe && ./pr2.exe
WRONG 4
$ gfortran -O2 -fno-inline pr2.f90 -o pr2.exe && ./pr2.exe
WRONG 4
$ gfortran -O2 -fno-inline -fno-ipa-sra -fno-ipa-cp pr2.f90 -o pr2.exe &&
./pr2.exe
WRONG 4
It also prints WRONG with -O1 -fno-inline. Without -fno-inline, TAKE is
inlined at -O1 and above and the program prints OK.
At -O0 the caller (from gfortran -O0 -S pr2.f90) stores the 5th argument
with a 4-byte store:
movl %ecx, 32(%rsp)
movq %rax, %rcx
call __m_MOD_take
and TAKE compares all 8 bytes:
cmpq $0, 496(%rbp)
With -O2 -fno-inline even the constant .false. is stored as
movl $0, 32(%rsp)
The upper half of the slot still holds part of the address of S5 that the
preceding call to SINK passed in the same slot, so FLAG is read as .true..
Arguments passed in registers (the first four) are not affected, since a
32-bit register write zero-extends.
Same compiler as in the original report (MSYS2 gfortran 16.2.0 Rev6,
x86_64-w64-mingw32).