Bug 66838

Summary: [5 Regression] Calling multiple SYSV AMD64 ABI functions from MS x64 ABI one results in clobbered parameters
Product: gcc Reporter: Michal Růžička <michal.ruza>
Component: rtl-optimizationAssignee: Uroš Bizjak <ubizjak>
Status: RESOLVED FIXED    
Severity: normal CC: austinenglish, law, marcus, ubizjak
Priority: P3    
Version: 5.1.1   
Target Milestone: 5.3   
Host: Target: x86_64
Build: Known to work:
Known to fail: Last reconfirmed: 2015-07-12 00:00:00
Attachments: clobber_repro.c
Untested patch

Description Michal Růžička 2015-07-11 00:59:00 UTC
Created attachment 35951 [details]
clobber_repro.c

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)
Comment 1 Uroš Bizjak 2015-07-12 15:21:23 UTC
Confirmed, this one is in postreload pass. The testcase from Comment #0, when compiled with -O2 creates following dumps:

Register allocator creates correct sequence, _.reload dump shows for ms_abi_func:

    2: NOTE_INSN_FUNCTION_BEG
    5: si:DI=`global'
    6: di:DI=`*.LC2'
    7: call [`sysv_abi_func'] argc:0
      REG_EH_REGION 0
    8: si:DI=`global'
    9: di:DI=`*.LC3'
   10: call [`sysv_abi_func'] argc:0
      REG_EH_REGION 0
   11: si:DI=`global'
   12: di:DI=`*.LC4'
   13: call [`sysv_abi_func'] argc:0
      REG_EH_REGION 0
   16: NOTE_INSN_DELETED

and _.postreload shows:

    2: NOTE_INSN_FUNCTION_BEG
    5: si:DI=`global'
    6: di:DI=`*.LC2'
    7: call [`sysv_abi_func'] argc:0
      REG_EH_REGION 0
    8: si:DI=si:DI
    9: di:DI=`*.LC3'
   10: call [`sysv_abi_func'] argc:0
      REG_EH_REGION 0
   11: si:DI=si:DI
   12: di:DI=`*.LC4'
   13: call [`sysv_abi_func'] argc:0
      REG_EH_REGION 0
   16: NOTE_INSN_DELETED

Please note invalid SI register propagation through function call to (insn 8) and (insn 11).

Confirmed as rtl-optimization problem, CC added.
Comment 2 Uroš Bizjak 2015-07-12 15:27:21 UTC
*** Bug 66845 has been marked as a duplicate of this bug. ***
Comment 3 Uroš Bizjak 2015-07-12 16:42:40 UTC
Created attachment 35961 [details]
Untested patch

Patch that adds missing CALL_INSN_FUNCTION_USAGE processing to postreload.c/reload_cse_move2add.
Comment 4 uros 2015-07-15 07:29:04 UTC
Author: uros
Date: Wed Jul 15 07:28:33 2015
New Revision: 225806

URL: https://gcc.gnu.org/viewcvs?rev=225806&root=gcc&view=rev
Log:
	PR rtl-optimization/66838
	* postreload.c (reload_cse_move2add): Also process
	CALL_INSN_FUNCTION_USAGE when resetting information of
	call-clobbered registers.

testsuite/ChangeLog:

	PR rtl-optimization/66838
	* gcc.target/i386/pr66838.c: New test.


Added:
    trunk/gcc/testsuite/gcc.target/i386/pr66838.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/postreload.c
    trunk/gcc/testsuite/ChangeLog
Comment 5 Uroš Bizjak 2015-07-15 08:41:37 UTC
Fixed for mainline, needs backport to gcc-5 branch.
Comment 6 Richard Biener 2015-07-16 09:12:18 UTC
GCC 5.2 is being released, adjusting target milestone to 5.3.
Comment 7 uros 2015-07-17 13:51:09 UTC
Author: uros
Date: Fri Jul 17 13:50:38 2015
New Revision: 225935

URL: https://gcc.gnu.org/viewcvs?rev=225935&root=gcc&view=rev
Log:
	Backport from mainline:
	2015-07-15  Uros Bizjak  <ubizjak@gmail.com>

	PR rtl-optimization/66838
	* postreload.c (reload_cse_move2add): Also process
	CALL_INSN_FUNCTION_USAGE when resetting information of
	call-clobbered registers.

testsuite/ChangeLog:

	Backport from mainline:
	2015-07-15  Uros Bizjak  <ubizjak@gmail.com>

	PR rtl-optimization/66838
	* gcc.target/i386/pr66838.c: New test.


Added:
    branches/gcc-5-branch/gcc/testsuite/gcc.target/i386/pr66838.c
Modified:
    branches/gcc-5-branch/gcc/ChangeLog
    branches/gcc-5-branch/gcc/postreload.c
    branches/gcc-5-branch/gcc/testsuite/ChangeLog
Comment 8 Uroš Bizjak 2015-07-17 14:06:24 UTC
Fixed.