[hjl@gnu-mic-2 tmp]$ cat /tmp/testf.c void test (float x1, float x2, float x3, float x4, float x5, float x6, float x7, float x8, float x9, float x10, float x11, float x12, float x13, float x14, float x15, float x16) { if (x1 != 91) __builtin_abort (); if (x15 != 105) __builtin_abort (); } float x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16; int main () { x1 = 91; x2 = 92; x3 = 93; x4 = 94; x5 = 95; x6 = 96; x7 = 97; x8 = 98; x9 = 99; x10 = 100; x11 = 101; x12 = 102; x13 = 103; x14 = 104; x15 = 105; x16 = 106; test (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16); return 0; } [hjl@gnu-mic-2 tmp]$ gcc /tmp/testf.c -mno-accumulate-outgoing-args -mx32 -g [hjl@gnu-mic-2 tmp]$ gdb a.out GNU gdb (GDB) 7.6.50.20131208-cvs Copyright (C) 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-unknown-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from a.out...done. (gdb) r Starting program: /tmp/a.out Program received signal SIGABRT, Aborted. 0xf7a55192 in raise () from /libx32/libc.so.6 (gdb) f 1 #1 0xf7a56776 in abort () from /libx32/libc.so.6 (gdb) f 2 #2 0x00400449 in test (x1=91, x2=92, x3=93, x4=94, x5=95, x6=96, x7=97, x8=98, x9=99, x10=100, x11=101, x12=102, x13=103, x14=104, x15=106, x16=1.40129846e-45) at /tmp/testf.c:9 9 __builtin_abort (); (gdb)
It works with GCC 4.7.
Add -maddress-mode=long fixes the problem.
The bug is in ;; %%% Kill this when call knows how to work this out. (define_split [(set (match_operand:SF 0 "push_operand") (match_operand:SF 1 "any_fp_register_operand"))] "reload_completed" [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) (set (mem:SF (reg:P SP_REG)) (match_dup 1))] "operands[2] = GEN_INT (-<P:MODE_SIZE>);") For (insn 54 53 55 2 (set (mem:SF (pre_modify:SI (reg/f:SI 7 sp) (plus:SI (reg/f:SI 7 sp) (const_int -8 [0xfffffffffffffff8]))) [0 S4 A32]) (reg:SF 22 xmm1 [orig:84 D.1790 ] [84])) x.i:27 124 {*pushsf_rex64} (expr_list:REG_ARGS_SIZE (const_int 16 [0x10]) (nil))) we generate the wrong operands[2]. It is better just use rtx op = XEXP (XEXP (XEXP (operands[0], 0), 1), 1); gcc_assert (CONST_INT_P (op)); operands[2] = op; instead.
Author: hjl Date: Fri Jan 24 03:38:10 2014 New Revision: 207023 URL: http://gcc.gnu.org/viewcvs?rev=207023&root=gcc&view=rev Log: Get stack adjustment from push operand in pushsf splitter pushsf for -m64/-mx32 looks like (set (mem:SF (pre_modify:SI (reg/f:SI 7 sp) (plus:SI (reg/f:SI 7 sp) (const_int -8)))) (reg:SF 22 xmm1 [orig:84 D.1790 ] [84])) Stack adjustment is in push operand and it isn't stack register mode size which may be 4 bytes for -mx32. This patch gets stack adjustment from push operand if code of push isn't PRE_DEC. gcc/ PR target/59929 * config/i386/i386.md (pushsf splitter): Get stack adjustment from push operand if code of push isn't PRE_DEC. gcc/testsuite/ PR target/59929 * gcc.target/i386/pr59929.c: New test. Added: trunk/gcc/testsuite/gcc.target/i386/pr59929.c Modified: trunk/gcc/ChangeLog trunk/gcc/config/i386/i386.md trunk/gcc/testsuite/ChangeLog
Author: hjl Date: Sat Jan 25 03:20:44 2014 New Revision: 207070 URL: http://gcc.gnu.org/viewcvs?rev=207070&root=gcc&view=rev Log: Get stack adjustment from push operand in pushsf splitter pushsf for -m64/-mx32 looks like (set (mem:SF (pre_modify:SI (reg/f:SI 7 sp) (plus:SI (reg/f:SI 7 sp) (const_int -8)))) (reg:SF 22 xmm1 [orig:84 D.1790 ] [84])) Stack adjustment is in push operand and it isn't stack register mode size which may be 4 bytes for -mx32. This patch gets stack adjustment from push operand if code of push isn't PRE_DEC. gcc/ Backport from mainline PR target/59929 * config/i386/i386.md (pushsf splitter): Get stack adjustment from push operand if code of push isn't PRE_DEC. gcc/testsuite/ Backport from mainline. PR target/59929 * gcc.target/i386/pr59929.c: New test. Added: branches/gcc-4_8-branch/gcc/testsuite/gcc.target/i386/pr59929.c Modified: branches/gcc-4_8-branch/gcc/ChangeLog branches/gcc-4_8-branch/gcc/config/i386/i386.md branches/gcc-4_8-branch/gcc/testsuite/ChangeLog
Fixed.