Bug 47725 - [x32] error: unable to find a register to spill in class DIREG
Summary: [x32] error: unable to find a register to spill in class DIREG
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: 4.7.0
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-02-14 00:46 UTC by H.J. Lu
Modified: 2011-07-28 17:06 UTC (History)
3 users (show)

See Also:
Host:
Target: x32
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Test case generated by Mercury Compiler (30.13 KB, text/x-csrc)
2011-07-22 06:07 UTC, Paul Bone
Details

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2011-02-14 00:46:20 UTC
On x32 branch, I got

/export/build/gnu/gcc-x32/build-x86_64-linux/gcc/xgcc -B/export/build/gnu/gcc-x32/build-x86_64-linux/gcc/ -S -o u.s -mx32 -O2 -g -fPIC    u.c
u.c: In function \u2018__frame_state_for\u2019:
u.c:14:1: error: unable to find a register to spill in class \u2018DIREG\u2019
u.c:14:1: error: this is the insn:
(insn 11 20 14 2 (parallel [
            (set (reg:DI 2 cx [64])
                (const_int 0 [0]))
            (set (reg/f:DI 0 ax [62])
                (plus:DI (ashift:DI (reg:DI 2 cx [64])
                        (const_int 3 [0x3]))
                    (reg/f:DI 1 dx [60])))
            (set (mem/s/c:BLK (reg/f:DI 1 dx [60]) [0 context+0 S72 A64])
                (const_int 0 [0]))
            (use (reg:DI 0 ax [63]))
            (use (reg:DI 2 cx [64]))
        ]) u.c:11 874 {*rep_stosdi_rex64}
     (expr_list:REG_DEAD (reg:DI 0 ax [63])
        (expr_list:REG_UNUSED (reg:DI 2 cx [64])
            (expr_list:REG_UNUSED (reg/f:DI 0 ax [62])
                (nil)))))
u.c:14:1: internal compiler error: in spill_failure, at reload1.c:2105
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
make: *** [u.s] Error 1
[hjl@gnu-6 ilp32-14]$
Comment 1 H.J. Lu 2011-02-14 01:07:41 UTC
Combine changes

(insn 2 4 3 2 (set (reg/v/f:DI 59 [ pc_target ])
        (zero_extend:DI (reg:SI 5 di [ pc_target ]))) u.i:9 115 {*zero_extendsidi2_rex64}
     (expr_list:REG_DEAD (reg:SI 5 di [ pc_target ])
        (nil)))
...
(insn 11 10 14 2 (parallel [
            (set (reg:DI 64)
                (const_int 0 [0]))
            (set (reg/f:DI 62)
                (plus:DI (ashift:DI (reg:DI 64)
                        (const_int 3 [0x3]))
                    (reg/f:DI 60)))
            (set (mem/s/c:BLK (reg/f:DI 60) [0 context+0 S72 A64])
                (const_int 0 [0]))
            (use (reg:DI 63))
            (use (reg:DI 64))
        ]) u.i:11 874 {*rep_stosdi_rex64}
     (expr_list:REG_DEAD (reg:DI 63)
        (expr_list:REG_UNUSED (reg:DI 64)
            (expr_list:REG_UNUSED (reg/f:DI 62)
                (nil)))))

(insn 14 11 16 2 (set (mem/s/f/c:SI (plus:DI (reg/f:DI 20 frame)
                (const_int -8 [0xfffffffffffffff8])) [3 context.ra+0 S4 A64])
        (subreg/s/u:SI (reg/v/f:DI 59 [ pc_target ]) 0)) u.i:12 64 {*movsi_internal}
     (expr_list:REG_DEAD (reg/v/f:DI 59 [ pc_target ])
        (nil)))

to

(insn 11 10 14 2 (parallel [
            (set (reg:DI 64) 
                (const_int 0 [0]))
            (set (reg/f:DI 62) 
                (plus:DI (ashift:DI (reg:DI 64) 
                        (const_int 3 [0x3]))
                    (reg/f:DI 60)))
            (set (mem/s/c:BLK (reg/f:DI 60) [0 context+0 S72 A64])
                (const_int 0 [0]))
            (use (reg:DI 63))
            (use (reg:DI 64))
        ]) u.i:11 874 {*rep_stosdi_rex64}
     (expr_list:REG_DEAD (reg:DI 63) 
        (expr_list:REG_UNUSED (reg:DI 64) 
            (expr_list:REG_UNUSED (reg/f:DI 62) 
                (nil)))))

(insn 14 11 16 2 (set (mem/s/f/c:SI (plus:DI (reg/f:DI 20 frame)
                (const_int -8 [0xfffffffffffffff8])) [3 context.ra+0 S4 A64])
        (reg:SI 5 di [ pc_target ])) u.i:12 64 {*movsi_internal}
     (expr_list:REG_DEAD (reg:SI 5 di [ pc_target ])
        (nil)))


Since *rep_stosdi_rex64 needs the RDI register, it kills
reload.  Eric, should combine move hard register?
Comment 2 H.J. Lu 2011-02-14 01:28:08 UTC
I think this is similar to PR 47449.
Comment 3 H.J. Lu 2011-02-14 03:04:29 UTC
I am testing this patch:

diff --git a/gcc/combine.c b/gcc/combine.c
index 5e1236b..78f3089 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -2138,6 +2138,12 @@ cant_combine_insn_p (rtx insn)
     return asm_noperands (PATTERN (insn)) > 0;
   src = SET_SRC (set);
   dest = SET_DEST (set);
+  if (GET_CODE (src) == ZERO_EXTEND
+      || GET_CODE (src) == SIGN_EXTEND)
+    src = XEXP (src, 0);
+  if (GET_CODE (dest) == ZERO_EXTEND
+      || GET_CODE (dest) == SIGN_EXTEND)
+    dest = XEXP (dest, 0);
   if (GET_CODE (src) == SUBREG)
     src = SUBREG_REG (src);
   if (GET_CODE (dest) == SUBREG)
Comment 4 Eric Botcazou 2011-02-14 08:03:53 UTC
> --- a/gcc/combine.c
> +++ b/gcc/combine.c
> @@ -2138,6 +2138,12 @@ cant_combine_insn_p (rtx insn)
>      return asm_noperands (PATTERN (insn)) > 0;
>    src = SET_SRC (set);
>    dest = SET_DEST (set);
> +  if (GET_CODE (src) == ZERO_EXTEND
> +      || GET_CODE (src) == SIGN_EXTEND)
> +    src = XEXP (src, 0);
> +  if (GET_CODE (dest) == ZERO_EXTEND
> +      || GET_CODE (dest) == SIGN_EXTEND)
> +    dest = XEXP (dest, 0);
>    if (GET_CODE (src) == SUBREG)
>      src = SUBREG_REG (src);
>    if (GET_CODE (dest) == SUBREG)

ZERO_EXTEND and SIGN_EXTEND are real operations (they generate code) though, so this will pessimize.

Who generates insn #2?  The machinery handling parameters in function.c?  If so, maybe it should do the copy in the incoming mode instead:

(insn 2 4 3 2 (set (reg/v/f:SI 59 [ pc_target ])
        (reg:SI 5 di [ pc_target ]))

(insn 3 5 4 2 (set (reg:DI 60)
        (zero_extend:DI (reg/v/f:SI 59 [ pc_target ])))
Comment 5 H.J. Lu 2011-02-14 14:06:45 UTC
(In reply to comment #4)
> 
> Who generates insn #2?  The machinery handling parameters in function.c?  If
> so, maybe it should do the copy in the incoming mode instead:
> 
> (insn 2 4 3 2 (set (reg/v/f:SI 59 [ pc_target ])
>         (reg:SI 5 di [ pc_target ]))
> 
> (insn 3 5 4 2 (set (reg:DI 60)
>         (zero_extend:DI (reg/v/f:SI 59 [ pc_target ])))

assign_parm_setup_reg has

          enum rtx_code code = unsignedp ? ZERO_EXTEND : SIGN_EXTEND;
          rtx insn, insns;
          HARD_REG_SET hardregs;

          start_sequence ();
          insn = gen_extend_insn (op0, op1, promoted_nominal_mode,
                                  data->passed_mode, unsignedp);
          emit_insn (insn);
          insns = get_insns ();
Comment 6 H.J. Lu 2011-02-14 14:13:32 UTC
This seems to work:

diff --git a/gcc/function.c b/gcc/function.c
index 3f721fb..4c78407 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -3000,11 +3000,15 @@ assign_parm_setup_reg (struct assign_parm_data_all *all,
 tree parm,
 	  && insn_data[icode].operand[1].predicate (op1, data->passed_mode))
 	{
 	  enum rtx_code code = unsignedp ? ZERO_EXTEND : SIGN_EXTEND;
-	  rtx insn, insns;
+	  rtx insn, insns, copy;
 	  HARD_REG_SET hardregs;
 
 	  start_sequence ();
-	  insn = gen_extend_insn (op0, op1, promoted_nominal_mode,
+	  /* We must copy the hard register first before extending it.
+	     Otherwise, combine won't see the hard register.  */
+	  copy = gen_reg_rtx (data->passed_mode);
+	  emit_move_insn (copy, op1);
+	  insn = gen_extend_insn (op0, copy, promoted_nominal_mode,
 				  data->passed_mode, unsignedp);
 	  emit_insn (insn);
 	  insns = get_insns ();
Comment 7 hjl@gcc.gnu.org 2011-02-14 18:54:15 UTC
Author: hjl
Date: Mon Feb 14 18:54:12 2011
New Revision: 170148

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=170148
Log:
Copy the hard register first before extending it.

gcc/

2011-02-14  H.J. Lu  <hongjiu.lu@intel.com>

	PR middle-end/47725
	* function.c (assign_parm_setup_reg): Copy the hard register
	first before extending it.

gcc/testsuite/

2011-02-13  H.J. Lu  <hongjiu.lu@intel.com>

	PR middle-end/47725
	* gcc.dg/torture/pr47725.c: New.

Added:
    branches/x32/gcc/testsuite/gcc.dg/torture/pr47725.c
Modified:
    branches/x32/gcc/ChangeLog.x32
    branches/x32/gcc/function.c
    branches/x32/gcc/testsuite/ChangeLog.x32
Comment 8 H.J. Lu 2011-02-14 19:02:08 UTC
A patch is posted at

http://gcc.gnu.org/ml/gcc-patches/2011-02/msg00909.html
Comment 9 hjl@gcc.gnu.org 2011-02-15 16:50:47 UTC
Author: hjl
Date: Tue Feb 15 16:50:43 2011
New Revision: 170179

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=170179
Log:
Check zero/sign extended hard registers.

gcc/

2011-02-15  H.J. Lu  <hongjiu.lu@intel.com>

	PR middle-end/47725
	* combine.c (cant_combine_insn_p): Check zero/sign extended
	hard registers.

gcc/testsuite/

2011-02-15  H.J. Lu  <hongjiu.lu@intel.com>

	PR middle-end/47725
	* gcc.dg/torture/pr47725.c: New.

Added:
    trunk/gcc/testsuite/gcc.dg/torture/pr47725.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/combine.c
    trunk/gcc/testsuite/ChangeLog
Comment 10 hjl@gcc.gnu.org 2011-02-15 19:46:29 UTC
Author: hjl
Date: Tue Feb 15 19:46:26 2011
New Revision: 170197

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=170197
Log:
Revert cant_combine_insn_p change.

gcc/

2011-02-15  H.J. Lu  <hongjiu.lu@intel.com>

	PR middle-end/47725
	* combine.c (cant_combine_insn_p): Revert the last change.

gcc/testsuite/

2011-02-15  H.J. Lu  <hongjiu.lu@intel.com>

	PR middle-end/47725
	* gcc.dg/torture/pr47725.c: Removed.

Removed:
    trunk/gcc/testsuite/gcc.dg/torture/pr47725.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/combine.c
    trunk/gcc/testsuite/ChangeLog
Comment 11 hjl@gcc.gnu.org 2011-02-16 20:15:12 UTC
Author: hjl
Date: Wed Feb 16 20:15:07 2011
New Revision: 170218

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=170218
Log:
Check zero/sign extended hard registers in cant_combine_insn_p.

2011-02-15  H.J. Lu  <hongjiu.lu@intel.com>

	PR middle-end/47725
	* combine.c (cant_combine_insn_p): Check zero/sign extended
	hard registers.

Modified:
    branches/x32/gcc/ChangeLog.x32
    branches/x32/gcc/combine.c
Comment 12 hjl@gcc.gnu.org 2011-03-18 00:29:18 UTC
Author: hjl
Date: Fri Mar 18 00:29:15 2011
New Revision: 171124

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=171124
Log:
Check zero/sign extended hard registers.

gcc/

2011-03-17  H.J. Lu  <hongjiu.lu@intel.com>

	PR middle-end/47725
	* combine.c (cant_combine_insn_p): Check zero/sign extended
	hard registers.

gcc/testsuite/

2011-03-17  H.J. Lu  <hongjiu.lu@intel.com>

	PR middle-end/47725
	* gcc.dg/torture/pr47725.c: New.

Added:
    trunk/gcc/testsuite/gcc.dg/torture/pr47725.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/combine.c
    trunk/gcc/testsuite/ChangeLog
Comment 13 hjl@gcc.gnu.org 2011-03-18 04:02:30 UTC
Author: hjl
Date: Fri Mar 18 04:02:25 2011
New Revision: 171125

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=171125
Log:
Revert the last change on cant_combine_insn_p.

2011-03-17  H.J. Lu  <hongjiu.lu@intel.com>

	PR middle-end/47725
	* combine.c (cant_combine_insn_p): Don't check zero/sign
	extended hard registers.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/combine.c
Comment 14 hjl@gcc.gnu.org 2011-04-02 06:03:56 UTC
Author: hjl
Date: Sat Apr  2 06:03:52 2011
New Revision: 171877

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=171877
Log:
Don't check zero/sign extended hard registers.

2011-03-29  H.J. Lu  <hongjiu.lu@intel.com>

	PR middle-end/47725
	* combine.c (cant_combine_insn_p): Don't check zero/sign extended
	hard registers.

Modified:
    branches/x32/gcc/ChangeLog.x32
    branches/x32/gcc/combine.c
Comment 15 hjl@gcc.gnu.org 2011-04-02 06:05:06 UTC
Author: hjl
Date: Sat Apr  2 06:05:03 2011
New Revision: 171878

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=171878
Log:
Promote pointer function arguments and return values to Pmode.

2011-03-29  H.J. Lu  <hongjiu.lu@intel.com>

	PR middle-end/47725
	PR target/48085
	* calls.c (precompute_register_parameters): Convert pointer to
	TLS symbol if needed.

	* config/i386/i386.c (ix86_promote_function_mode): New.
	(TARGET_PROMOTE_FUNCTION_MODE): Likewise.

Modified:
    branches/x32/gcc/ChangeLog.x32
    branches/x32/gcc/calls.c
    branches/x32/gcc/config/i386/i386.c
Comment 16 hjl@gcc.gnu.org 2011-06-20 14:53:52 UTC
Author: hjl
Date: Mon Jun 20 14:53:48 2011
New Revision: 175218

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=175218
Log:
Check zero/sign extended hard registers.

2011-06-20  H.J. Lu  <hongjiu.lu@intel.com>

	PR middle-end/47725
	* combine.c (cant_combine_insn_p): Check zero/sign extended
	hard registers.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/combine.c
Comment 17 Eric Botcazou 2011-06-20 16:01:53 UTC
> Check zero/sign extended hard registers.
> 
> 2011-06-20  H.J. Lu  <hongjiu.lu@intel.com>
> 
>     PR middle-end/47725
>     * combine.c (cant_combine_insn_p): Check zero/sign extended
>     hard registers.
> 
> Modified:
>     trunk/gcc/ChangeLog
>     trunk/gcc/combine.c

Why are you installing this again?  The patch isn't correct and I thought it was unnecessary in the end.
Comment 18 hjl@gcc.gnu.org 2011-06-20 17:03:21 UTC
Author: hjl
Date: Mon Jun 20 17:03:16 2011
New Revision: 175222

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=175222
Log:
Don't check zero/sign extended hard registers.

2011-06-20  H.J. Lu  <hongjiu.lu@intel.com>

	PR middle-end/47725
	* combine.c (cant_combine_insn_p): Don't check zero/sign
	extended hard registers.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/combine.c
Comment 19 Paul Bone 2011-07-22 06:01:30 UTC
I'm seeing the same problem in gcc 4.4 and 4.6, I did not test 4.5:

paul@semillion:~/code/mercury-compiler-rotd-2011-06-23/compiler$ gcc-4.4 -v -c
-o /tmp/out.o -O1 ml_backend.ml_closure_gen.i
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.4.5-8'
--with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs
--enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-4.4 --enable-shared --enable-multiarch
--enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib
--without-included-gettext --enable-threads=posix
--with-gxx-include-dir=/usr/include/c++/4.4 --libdir=/usr/lib --enable-nls
--enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc
--enable-targets=all --with-arch-32=i586 --with-tune=generic
--enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu
--target=i486-linux-gnu
Thread model: posix
gcc version 4.4.5 (Debian 4.4.5-8) 
COLLECT_GCC_OPTIONS='-v' '-c' '-o' '/tmp/out.o' '-O1' '-mtune=generic'
'-march=i586'
 /usr/lib/gcc/i486-linux-gnu/4.4.5/cc1 -fpreprocessed
ml_backend.ml_closure_gen.i -quiet -dumpbase ml_backend.ml_closure_gen.i
-mtune=generic -march=i586 -auxbase-strip /tmp/out.o -O1 -version -o
/tmp/ccbABR7o.s
GNU C (Debian 4.4.5-8) version 4.4.5 (i486-linux-gnu)
        compiled by GNU C version 4.4.5, GMP version 4.3.2, MPFR version
3.0.0-p3.
GGC heuristics: --param ggc-min-expand=98 --param ggc-min-heapsize=127992
Compiler executable checksum: 0192d925385d4e6642a93c63f245f907
ml_backend.ml_closure_gen.c:32: warning:
‘mercury__ml_backend__ml_closure_gen__ml_gen_maybe_pseudo_type_info_defn_4_0’
used but never defined
ml_backend.ml_closure_gen.c: In function ‘ml_backend__ml_closure_gen_module11’:
ml_backend.ml_closure_gen.c:230: error: unable to find a register to spill in
class ‘DIREG’
ml_backend.ml_closure_gen.c:230: error: this is the insn:
(insn 123 122 124 11 ml_backend.ml_closure_gen.c:105 (parallel [
            (set (mem:SI (reg/f:SI 136) [0 S4 A32])
                (reg/v:SI 80 [ MR_tempr3 ]))
            (set (reg/v:SI 82 [ MR_tempr1 ])
                (plus:SI (reg/f:SI 136)
                    (const_int 4 [0x4])))
        ]) 852 {*strsetsi_1} (expr_list:REG_DEAD (reg/f:SI 136)
        (nil)))
ml_backend.ml_closure_gen.c:230: confused by earlier errors, bailing out
Preprocessed source stored into /tmp/cccXoZX2.out file, please attach this to
your bugreport.

I will attach the generated test case.
Comment 20 Paul Bone 2011-07-22 06:07:11 UTC
Created attachment 24808 [details]
Test case generated by Mercury Compiler

This is a test case generated by the Mercury compiler, it has been reduced just enough code to cause the bug to occur.  It can be reproduced in gcc 4.4 and 4.6 at an optimization level of -O1 but not -O0.  The output of GCC is:

paul@semillion:~/code/mercury-compiler-rotd-2011-06-23/compiler$ gcc-4.4 -v -c -o /tmp/out.o -O1 ml_backend.ml_closure_gen.i
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.4.5-8' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.4 --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-targets=all --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
Thread model: posix
gcc version 4.4.5 (Debian 4.4.5-8)
COLLECT_GCC_OPTIONS='-v' '-c' '-o' '/tmp/out.o' '-O1' '-mtune=generic' '-march=i586'
 /usr/lib/gcc/i486-linux-gnu/4.4.5/cc1 -fpreprocessed ml_backend.ml_closure_gen.i -quiet -dumpbase ml_backend.ml_closure_gen.i -mtune=generic -march=i586 -auxbase-strip /tmp/out.o -O1 -version -o /tmp/ccbABR7o.s
GNU C (Debian 4.4.5-8) version 4.4.5 (i486-linux-gnu)
        compiled by GNU C version 4.4.5, GMP version 4.3.2, MPFR version 3.0.0-p3.
GGC heuristics: --param ggc-min-expand=98 --param ggc-min-heapsize=127992
Compiler executable checksum: 0192d925385d4e6642a93c63f245f907
ml_backend.ml_closure_gen.c:32: warning: ‘mercury__ml_backend__ml_closure_gen__ml_gen_maybe_pseudo_type_info_defn_4_0’ used but never defined
ml_backend.ml_closure_gen.c: In function ‘ml_backend__ml_closure_gen_module11’:
ml_backend.ml_closure_gen.c:230: error: unable to find a register to spill in class ‘DIREG’
ml_backend.ml_closure_gen.c:230: error: this is the insn:
(insn 123 122 124 11 ml_backend.ml_closure_gen.c:105 (parallel [
            (set (mem:SI (reg/f:SI 136) [0 S4 A32])
                (reg/v:SI 80 [ MR_tempr3 ]))
            (set (reg/v:SI 82 [ MR_tempr1 ])
                (plus:SI (reg/f:SI 136)
                    (const_int 4 [0x4])))
        ]) 852 {*strsetsi_1} (expr_list:REG_DEAD (reg/f:SI 136)
        (nil)))
ml_backend.ml_closure_gen.c:230: confused by earlier errors, bailing out
Preprocessed source stored into /tmp/cccXoZX2.out file, please attach this to your bugreport.
Comment 21 Uroš Bizjak 2011-07-28 17:02:49 UTC
(In reply to comment #19)
> I'm seeing the same problem in gcc 4.4 and 4.6, I did not test 4.5:

Please, do not hijack bug reports.

Open new one, this one is for x32 (that is x86_64 with 32bit pointers) target.
Comment 22 Uroš Bizjak 2011-07-28 17:06:49 UTC
The testcase, referred in Comment 0 is:

struct _Unwind_Context
{
  void *reg[17];
  void *ra;
};
extern void bar (struct _Unwind_Context *);
void
__frame_state_for (void *pc_target)
{
  struct _Unwind_Context context;
  __builtin_memset (&context, 0, sizeof (struct _Unwind_Context));
  context.ra = pc_target;
  bar (&context);
}

Compiling with recent mainline works OK:

~/gcc-build/gcc/cc1 -O2 -fpic -mx32 pr47725.c

__frame_state_for:
.LFB0:
	.cfi_startproc
	subq	$88, %rsp
	.cfi_def_cfa_offset 96
	movq	%rdi, %rsi
	xorl	%eax, %eax
	movq	%rsp, %rdi
	movl	$9, %ecx
	rep stosq
	movq	%rsp, %rdi
	movl	%esi, 68(%rsp)
	call	bar@PLT
	addq	$88, %rsp
	.cfi_def_cfa_offset 8
	ret

Fixed.