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

--- Comment #5 from Peter Knowles <KnowlesPJ at Cardiff dot ac.uk> ---
This is not specific to MinGW, and it is a regression in GCC 16. It happens
on x86_64-linux-gnu too whenever outgoing stack arguments are stored with mov
(accumulate-outgoing-args) rather than pushed. MinGW always does that, which
is why it showed up there first.

Attached pr3.f90 (self-contained). The LOGICAL(8), VALUE dummy is the 10th
argument, so it is on the stack under both the SysV and the Windows x64
conventions. Expected output: OK. Results on x86_64-linux-gnu (Compiler
Explorer, PIE executables):

  gfortran -O0 -fPIE -pie -maccumulate-outgoing-args pr3.f90   16.2, trunk:
WRONG
  gfortran -O2 -fno-inline -fPIE -pie -mtune=intel pr3.f90      16.1, 16.2,
trunk: WRONG
  same with -march=k8, bonnell, silvermont or goldmont (16.2):  WRONG
  same with 13.4, 14.3, 15.1, 15.2:                             OK
  default tuning, -march=x86-64-v3/v4, znver4, etc. (push):     OK

Store of the 10th argument by the caller with -O2 -fno-inline -mtune=intel:

  13.4, 14.3, 15.1, 15.2:   movq    $0, 24(%rsp)
  16.1, 16.2, trunk:        movl    $0, 24(%rsp)

The callee reads 8 bytes in every version (16.2: cmpq $0, 632(%rsp)). The
preceding call to SINK leaves the address of S10 in that slot, and in a PIE
executable that address has non-zero upper bytes, so FLAG reads as .true..
In a non-PIE executable the leftover upper bytes are usually zero, which hides
the bug.

AArch64 (gfortran 16.1) is not affected: the argument is stored with an
8-byte str/stp and loaded with ldr x0.

Suggested summary:
[16/17 Regression] x86-64: LOGICAL(8) stack argument stored with 4-byte movl
when outgoing args are accumulated

Reply via email to