Bug 59929 - [4.8/4.9 regression] -mno-accumulate-outgoing-args doesn't work with x32
Summary: [4.8/4.9 regression] -mno-accumulate-outgoing-args doesn't work with x32
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.8.2
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-01-23 21:12 UTC by H.J. Lu
Modified: 2014-01-25 03:34 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2014-01-23 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2014-01-23 21:12:53 UTC
[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)
Comment 1 H.J. Lu 2014-01-23 21:19:38 UTC
It works with GCC 4.7.
Comment 2 H.J. Lu 2014-01-23 21:20:21 UTC
Add -maddress-mode=long fixes the problem.
Comment 3 H.J. Lu 2014-01-23 22:43:04 UTC
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.
Comment 4 hjl@gcc.gnu.org 2014-01-24 03:38:42 UTC
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
Comment 5 hjl@gcc.gnu.org 2014-01-25 03:21:16 UTC
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
Comment 6 H.J. Lu 2014-01-25 03:34:26 UTC
Fixed.