https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66838
Bug ID: 66838
Summary: Calling multiple SYSV AMD64 ABI functions from MS x64
ABI one results in clobbered parameters
Product: gcc
Version: 5.1.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: michal.ruza at gmail dot com
Target Milestone: ---
Created attachment 35951
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=35951&action=edit
source code demonstrating the problem
This seems to be yet another corner case of bug 57003.
Description:
Calling a sequence of SYSV AMD64 ABI functions from an __attribute__((ms_abi))
function while passing an address of the same global variable to them results
in all but the first one in the sequence receiving clobbered values instead of
the expected address.
In code:
__attribute__((ms_abi, noinline, noclone)) void ms_abi_func() {
sysv_abi_func("1st call", &global);
sysv_abi_func("2nd call", &global);
sysv_abi_func("3rd call", &global);
}
In this example only the first call of the "sysv_abi_func" is passed the
address of the global variable "global". All the other calls of the function
are passed clobbered values.
To see the problem:
- generate assembly for the attached "clobber_repro.c" for the x86_64
architecture as follows:
gcc -S -O1 -m64 -o clobber_repro.S clobber_repro.c
- inspect the assembly code for the "ms_abi_func" fucntion
- you should see something like this after the function's prologue code:
movl $global, %esi
movl $.LC2, %edi
call sysv_abi_func
movl $.LC3, %edi
call sysv_abi_func
movl $.LC4, %edi
call sysv_abi_func
This apparently cannot work if "sysv_abi_func" clobbers %esi - and it is free
to do so as it is a SYSV AMD64 ABI function.
Additional notes:
- this doesn't happen when the "ms_abi_func" is NOT declared as
__attribute__((ms_abi))
- this doesn't happen when the "sysv_abi_func" IS declared as
__attribute__((ms_abi))
- this doesn't happen when the "global" is not a global variable - i.e. it
works when all of the calls are passed an address of the same local variable
- this doesn't happen when optimization is disabled (-O0)