Bug 66838 - [5 Regression] Calling multiple SYSV AMD64 ABI functions from MS x64 ABI one results in clobbered parameters
Summary: [5 Regression] Calling multiple SYSV AMD64 ABI functions from MS x64 ABI one ...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 5.1.1
: P3 normal
Target Milestone: 5.3
Assignee: Uroš Bizjak
URL:
Keywords:
: 66845 (view as bug list)
Depends on:
Blocks:
 
Reported: 2015-07-11 00:59 UTC by Michal Růžička
Modified: 2015-07-17 14:06 UTC (History)
4 users (show)

See Also:
Host:
Target: x86_64
Build:
Known to work:
Known to fail:
Last reconfirmed: 2015-07-12 00:00:00


Attachments
clobber_repro.c (236 bytes, text/plain)
2015-07-11 00:59 UTC, Michal Růžička
Details
Untested patch (499 bytes, patch)
2015-07-12 16:42 UTC, Uroš Bizjak
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
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.