Bug 57845

Summary: ICE with -freg-struct-return on SPARC
Product: gcc Reporter: Adam Lackorzynski <adam>
Component: targetAssignee: Eric Botcazou <ebotcazou>
Status: RESOLVED FIXED    
Severity: normal CC: ebotcazou, sorganov
Priority: P3    
Version: 4.9.4   
Target Milestone: ---   
Host: x86_64 Target: sparc
Build: Known to work:
Known to fail: Last reconfirmed: 2015-11-05 00:00:00

Description Adam Lackorzynski 2013-07-07 23:19:44 UTC
The following code produces an ICE for a Sparc target, with 4.9.0. Also tested 4.7.4 and 4.8.2 with same result. No ICE for target x86 for any version tested.
No ICE with-freg-struct-return removed.

class foo
{
public:
  struct r { };
};

class c
{ 
  foo::r func(foo::r);
};

foo::r c::func(foo::r x)
{
  return x;
}

$ sparc-linux-g++ -m32 -c  -freg-struct-return  x.i
x.i: In member function ‘foo::r c::func(foo::r)’:
x.i:15:10: internal compiler error: in emit_move_insn, at expr.c:3486
   return x;
          ^
0x85ba84 emit_move_insn(rtx_def*, rtx_def*)
        /tmp/gcc/head/gcc/gcc/expr.c:3485
0xa80620 expand_value_return
        /tmp/gcc/head/gcc/gcc/stmt.c:1460
0x78f5f1 expand_gimple_stmt_1
        /tmp/gcc/head/gcc/gcc/cfgexpand.c:2248
0x78f5f1 expand_gimple_stmt
        /tmp/gcc/head/gcc/gcc/cfgexpand.c:2370
0x7910a7 expand_gimple_basic_block
        /tmp/gcc/head/gcc/gcc/cfgexpand.c:4204
0x793806 gimple_expand_cfg
        /tmp/gcc/head/gcc/gcc/cfgexpand.c:4723
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.


Adam
Comment 1 Eric Botcazou 2013-07-08 06:48:14 UTC
-freg-struct-return isn't supported on the SPARC.
Comment 2 Sergey Organov 2015-11-05 14:08:26 UTC
Just ran into this ICE with gcc 5.2.0 sparc-elf target. How comes ICE gets "WONT FIX" "resolution"??? 

BTW, gcc 3.4.4 did support -freg-struct-return on sparc-elf. Here is simple code on which gcc 5.2.0 ICEs, along with asm output from gcc 3.4.4:

$ cat struct.c
typedef struct { short int i; } T;

T f(short int i)
{
  T r;
  r.i = i;
  return r;
}
$ ~/try/sparc-elf-5.2.0/bin/sparc-elf-gcc -O0 -v -freg-struct-return -c struct.c
Using built-in specs.
COLLECT_GCC=/home/osv/try/sparc-elf-5.2.0/bin/sparc-elf-gcc
Target: sparc-elf
Configured with: ../../gcc/configure --prefix=/home/osv/try/sparc-elf-5.2.0 --target=sparc-elf --enable-languages=c,c++ --disable-shared --disable-lto --disable-nls --disable-libstdcxx --disable-libssp --disable-__cxa_atexit --disable-newlib-hw-fp --with-gnu-as --with-gnu-ld -with-newlib --with-cpu=v8
Thread model: single
gcc version 5.2.0 (GCC) 
COLLECT_GCC_OPTIONS='-O0' '-v' '-freg-struct-return' '-c' '-mcpu=v8'
 /home/osv/try/sparc-elf-5.2.0/libexec/gcc/sparc-elf/5.2.0/cc1 -quiet -v -imultilib v8 -D__sparc_v8__ struct.c -quiet -dumpbase struct.c -mcpu=v8 -auxbase struct -O0 -version -freg-struct-return -o /tmp/cc8Q7Kz8.s
GNU C11 (GCC) version 5.2.0 (sparc-elf)
	compiled by GNU C version 4.4.5 20101112 (Red Hat 4.4.5-2), GMP version 5.0.1, MPFR version 3.0.0, MPC version 0.8.2
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/home/osv/try/sparc-elf-5.2.0/lib/gcc/sparc-elf/5.2.0/../../../../sparc-elf/sys-include"
#include "..." search starts here:
#include <...> search starts here:
 /home/osv/try/sparc-elf-5.2.0/lib/gcc/sparc-elf/5.2.0/include
 /home/osv/try/sparc-elf-5.2.0/lib/gcc/sparc-elf/5.2.0/include-fixed
 /home/osv/try/sparc-elf-5.2.0/lib/gcc/sparc-elf/5.2.0/../../../../sparc-elf/include
End of search list.
GNU C11 (GCC) version 5.2.0 (sparc-elf)
	compiled by GNU C version 4.4.5 20101112 (Red Hat 4.4.5-2), GMP version 5.0.1, MPFR version 3.0.0, MPC version 0.8.2
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 88c66c4c8e0ff180c6a3d3a418365f25
struct.c: In function 'f':
struct.c:7:10: internal compiler error: in emit_move_insn, at expr.c:3601
   return r;
          ^
0x66a1bc emit_move_insn(rtx_def*, rtx_def*)
	../../../gcc/gcc/expr.c:3601
0x59ba27 expand_value_return
	../../../gcc/gcc/cfgexpand.c:3177
0x59f30c expand_return
	../../../gcc/gcc/cfgexpand.c:3300
0x59f30c expand_gimple_stmt_1
	../../../gcc/gcc/cfgexpand.c:3373
0x59f30c expand_gimple_stmt
	../../../gcc/gcc/cfgexpand.c:3497
0x5a18ea expand_gimple_basic_block
	../../../gcc/gcc/cfgexpand.c:5509
0x5a66a7 execute
	../../../gcc/gcc/cfgexpand.c:6127
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
$ /opt/sparc-elf-3.4.4/bin/sparc-elf-gcc -O0 -v -freg-struct-return -save-temps -c struct.c
Reading specs from /opt/sparc-elf-3.4.4/lib/gcc/sparc-elf/3.4.4/specs
Configured with: ../gcc-3.4.4/configure --target=sparc-elf --prefix=/opt/sparc-elf-3.4.4 --with-gnu-as --with-gnu-ld --verbose --enable-languages=c,c++ --disable-shared --disable-nls --with-newlib --with-cpu=leon
Thread model: single
gcc version 3.4.4
 /opt/sparc-elf-3.4.4/libexec/gcc/sparc-elf/3.4.4/cc1 -E -quiet -v -D__leonbare__ struct.c -freg-struct-return -O0 -o struct.i
ignoring nonexistent directory "/opt/sparc-elf-3.4.4/lib/gcc/sparc-elf/3.4.4/../../../../sparc-elf/sys-include"
#include "..." search starts here:
#include <...> search starts here:
 /opt/sparc-elf-3.4.4/lib/gcc/sparc-elf/3.4.4/include
 /opt/sparc-elf-3.4.4/lib/gcc/sparc-elf/3.4.4/../../../../sparc-elf/include
End of search list.
 /opt/sparc-elf-3.4.4/libexec/gcc/sparc-elf/3.4.4/cc1 -fpreprocessed struct.i -quiet -dumpbase struct.c -auxbase struct -O0 -version -freg-struct-return -o struct.s
GNU C version 3.4.4 (sparc-elf)
	compiled by GNU C version 3.4.6.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
 /opt/sparc-elf-3.4.4/lib/gcc/sparc-elf/3.4.4/../../../../sparc-elf/bin/as -V -Qy -s -o struct.o struct.s
GNU assembler version 2.16.1 (sparc-elf) using BFD version 2.16.1
$ cat struct.s
	.file	"struct.c"
	.section	".text"
	.align 4
	.global f
	.type	f, #function
	.proc	010
f:
	!#PROLOGUE# 0
	save	%sp, -112, %sp
	!#PROLOGUE# 1
	mov	%i0, %g1
	sth	%g1, [%fp+68]
	lduh	[%fp+68], %g1
	sth	%g1, [%fp-10]
	lduh	[%fp-10], %g1
	mov	%g1, %i0
	ret
	restore
	.size	f, .-f
	.ident	"GCC: (GNU) 3.4.4"
$
Comment 3 Eric Botcazou 2015-11-05 14:19:15 UTC
Because nobody is interested in fixing it but patches are welcome of course.
Comment 4 Sergey Organov 2015-11-05 16:01:02 UTC
"WONTFIX: The problem described is a bug which will never be fixed." sounds very different from "nobody is interested in fixing it but  but patches are welcome". No?

Anyway, setting RESOLVED WONTFIX on an ICE sounds like bad idea in general. Is there some agreement between gcc developers about it?
Comment 5 Eric Botcazou 2015-11-05 16:35:15 UTC
> "WONTFIX: The problem described is a bug which will never be fixed." sounds
> very different from "nobody is interested in fixing it but  but patches are
> welcome". No?

No, the latter implies the former in 99% of the cases.

> Anyway, setting RESOLVED WONTFIX on an ICE sounds like bad idea in general.

We should indeed sorry out given that the option used to be accepted.
Comment 6 Sergey Organov 2015-11-05 20:46:38 UTC
Contrary to the rationale for closing this bug, the option -freg-struct-return seems to be supported and does work fine in some cases, see below. What do I miss?

$ cat struct.c
typedef struct { int i; } T;

T f(int i)
{
  T r;
  r.i = i;
  return r;
}
$ ~/try/sparc-elf-5.2.0/bin/sparc-elf-gcc -O2 -freg-struct-return -save-temps -c struct.c
$ cat struct.s
	.file	"struct.c"
	.section	".text"
	.align 4
	.global f
	.type	f, #function
	.proc	010
f:
	jmp	%o7+8
	 nop
	.size	f, .-f
	.ident	"GCC: (GNU) 5.2.0"
$ ~/try/sparc-elf-5.2.0/bin/sparc-elf-gcc -O2 -save-temps -c struct.c
$ cat struct.s
	.file	"struct.c"
	.section	".text"
	.align 4
	.global f
	.type	f, #function
	.proc	010
f:
	ld	[%sp+64], %g1
	st	%o0, [%g1]
	jmp	%o7+12
	 mov	%g1, %o0
	.size	f, .-f
	.ident	"GCC: (GNU) 5.2.0"
$
Comment 7 Eric Botcazou 2015-11-05 22:43:34 UTC
> Contrary to the rationale for closing this bug, the option
> -freg-struct-return seems to be supported and does work fine in some cases,
> see below. What do I miss?

That it works in some cases doesn't mean that it is supported.  Did you try to compile more than toy examples with the 3.4.4 compiler?
Comment 8 Sergey Organov 2015-11-06 11:03:49 UTC
I'm trying to upgrade from 3.4.4 to 5.2.0, and I used -freg-struct-return for years with 3.4.4 with no issues. Not that there is huge amount of code that actually uses functions returning structures, but the project itself is about 5Mb of compiled code.

I immediately ran to this ICE compiling real code, and then narrowed it down to these toy examples. I can easily check any code on 3.4.4, but I doubt it'd be productive for me to dig into current gcc sources I'm not familiar with, especially provided you doubt the feature is to be at all supported. 

On the other hand, I doubt the case I provided works in 5.2.0 by pure accident either, and there is some hope a fix for the ICE is rather simple for somebody who is familiar with gcc code base.
Comment 9 Eric Botcazou 2015-11-06 11:27:50 UTC
> I'm trying to upgrade from 3.4.4 to 5.2.0, and I used -freg-struct-return
> for years with 3.4.4 with no issues. Not that there is huge amount of code
> that actually uses functions returning structures, but the project itself is
> about 5Mb of compiled code.

Certainly fascinating.  I have been working on GCC for almost 15 years and did not see a single mention of the option over these years.  There is not a single test in the testsuite that exercises it.  When I overhauled the implementation of the calling conventions in the SPARC back-end for GCC 3.4.x:
  https://gcc.gnu.org/gcc-3.4/sparc-abi.html
I didn't know that it was even existing.  This stuff looks a bit magical...

> On the other hand, I doubt the case I provided works in 5.2.0 by pure
> accident either, and there is some hope a fix for the ICE is rather simple
> for somebody who is familiar with gcc code base.

Admittedly, I'll have a look then.
Comment 10 Eric Botcazou 2015-11-06 11:31:37 UTC
Investigating.
Comment 11 Eric Botcazou 2015-11-10 00:45:36 UTC
Author: ebotcazou
Date: Tue Nov 10 00:45:03 2015
New Revision: 230074

URL: https://gcc.gnu.org/viewcvs?rev=230074&root=gcc&view=rev
Log:
	PR target/57845
	* config/sparc/sparc.c (sparc_function_value_1): In 32-bit mode, do
	not promote the mode for aggregate types.

Added:
    trunk/gcc/testsuite/gcc.target/sparc/sparc-ret-1.c
      - copied unchanged from r230016, trunk/gcc/testsuite/gcc.target/sparc/sparc-ret.c
    trunk/gcc/testsuite/gcc.target/sparc/sparc-ret-2.c
Removed:
    trunk/gcc/testsuite/gcc.target/sparc/sparc-ret.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/sparc/sparc.c
    trunk/gcc/testsuite/ChangeLog
Comment 12 Eric Botcazou 2015-11-10 00:48:00 UTC
Author: ebotcazou
Date: Tue Nov 10 00:47:28 2015
New Revision: 230076

URL: https://gcc.gnu.org/viewcvs?rev=230076&root=gcc&view=rev
Log:
	PR target/57845
	* config/sparc/sparc.c (sparc_function_value_1): In 32-bit mode, do
	not promote the mode for aggregate types.

Added:
    branches/gcc-5-branch/gcc/testsuite/gcc.target/sparc/sparc-ret-1.c
      - copied unchanged from r228932, branches/gcc-5-branch/gcc/testsuite/gcc.target/sparc/sparc-ret.c
    branches/gcc-5-branch/gcc/testsuite/gcc.target/sparc/sparc-ret-2.c
      - copied unchanged from r230074, trunk/gcc/testsuite/gcc.target/sparc/sparc-ret-2.c
Removed:
    branches/gcc-5-branch/gcc/testsuite/gcc.target/sparc/sparc-ret.c
Modified:
    branches/gcc-5-branch/gcc/ChangeLog
    branches/gcc-5-branch/gcc/config/sparc/sparc.c
    branches/gcc-5-branch/gcc/testsuite/ChangeLog
Comment 13 Eric Botcazou 2015-11-10 00:49:37 UTC
Author: ebotcazou
Date: Tue Nov 10 00:49:05 2015
New Revision: 230077

URL: https://gcc.gnu.org/viewcvs?rev=230077&root=gcc&view=rev
Log:
	PR target/57845
	* config/sparc/sparc.c (sparc_function_value_1): In 32-bit mode, do
	not promote the mode for aggregate types.

Added:
    branches/gcc-4_9-branch/gcc/testsuite/gcc.target/sparc/sparc-ret-1.c
      - copied unchanged from r228932, branches/gcc-4_9-branch/gcc/testsuite/gcc.target/sparc/sparc-ret.c
    branches/gcc-4_9-branch/gcc/testsuite/gcc.target/sparc/sparc-ret-2.c
      - copied unchanged from r230076, trunk/gcc/testsuite/gcc.target/sparc/sparc-ret-2.c
Removed:
    branches/gcc-4_9-branch/gcc/testsuite/gcc.target/sparc/sparc-ret.c
Modified:
    branches/gcc-4_9-branch/gcc/ChangeLog
    branches/gcc-4_9-branch/gcc/config/sparc/sparc.c
    branches/gcc-4_9-branch/gcc/testsuite/ChangeLog
Comment 14 Eric Botcazou 2015-11-10 00:51:43 UTC
Fixed on all active branches but -freg-struct-return comes with no warranty.
Comment 15 Sergey Organov 2015-11-10 11:17:01 UTC
Eric, thanks a lot for taking care of the issue!
Comment 16 Sergey Organov 2015-11-19 15:07:05 UTC
I confirm it is fixed on sparc-elf-gcc (GCC) 5.2.1 20151119.

Thanks one more time!