diff mbox

[RFA,middle-end] Fix PR target/41993

Message ID 20121106.075813.150568568.kkojima@rr.iij4u.or.jp
State New
Headers show

Commit Message

Kaz Kojima Nov. 5, 2012, 10:58 p.m. UTC
Hi,

The attached patch is to solve PR target/41993 which will affect
targets using MODE_EXIT.
Without it, we can't find all return registers for __builtin_return
in mode-switching.c:create_pre_exit.  See the trail #4 by Uros in
the PR for the details.  The patch is tested with bootstrap and
regtested on i686-pc-linux-gnu with no new failures.  It's also
tested on cross sh4-unknown-linux-gnu.
OK for trunk?

Regards,
	kaz
--
2012-11-05  Uros Bizjak  <ubizjak@gmail.com>
	    Kaz Kojima  <kkojima@gcc.gnu.org>

	PR target/41993
	* mode-switching.c (create_pre_exit): Set return_copy to
	last_insn when copy_start is a pseudo reg.

Comments

Eric Botcazou Nov. 6, 2012, 8:12 a.m. UTC | #1
> 2012-11-05  Uros Bizjak  <ubizjak@gmail.com>
> 	    Kaz Kojima  <kkojima@gcc.gnu.org>
> 
> 	PR target/41993
> 	* mode-switching.c (create_pre_exit): Set return_copy to
> 	last_insn when copy_start is a pseudo reg.

OK, thanks.  The number of special cases dealt with in the function is on the 
verge of making it barely understandable though.  Why couldn't a backward scan 
based only on:

		    /* If the return register is not likely spilled, - as is
		       the case for floating point on SH4 - then it might
		       be set by an arithmetic operation that needs a
		       different mode than the exit block.  */
		    for (j = n_entities - 1; j >= 0; j--)
		      {
			int e = entity_map[j];
			int mode = MODE_NEEDED (e, return_copy);

			if (mode != num_modes[e] && mode != MODE_EXIT (e))
			  break;
		      }

(with a few shortcuts to speed it up) be sufficient?
Kaz Kojima Nov. 6, 2012, 9:11 a.m. UTC | #2
Eric Botcazou <ebotcazou@adacore.com> wrote:
> OK, thanks.  The number of special cases dealt with in the function is on the 
> verge of making it barely understandable though.  Why couldn't a backward scan 
> based only on:
> 
> 		    /* If the return register is not likely spilled, - as is
> 		       the case for floating point on SH4 - then it might
> 		       be set by an arithmetic operation that needs a
> 		       different mode than the exit block.  */
> 		    for (j = n_entities - 1; j >= 0; j--)
> 		      {
> 			int e = entity_map[j];
> 			int mode = MODE_NEEDED (e, return_copy);
> 
> 			if (mode != num_modes[e] && mode != MODE_EXIT (e))
> 			  break;
> 		      }
> 
> (with a few shortcuts to speed it up) be sufficient?

Although I might be getting you wrong, the current code does a scan
based on those lines but builtin_return, functions with no return
value and exceptions require special treatments and made things
complex.

Regards,
	kaz
Eric Botcazou Nov. 6, 2012, 9:14 a.m. UTC | #3
> Although I might be getting you wrong, the current code does a scan
> based on those lines but builtin_return, functions with no return
> value and exceptions require special treatments and made things
> complex.

I was referring to the ret_start/reg_end/nregs business: why is it necessary?
Kaz Kojima Nov. 6, 2012, 9:33 a.m. UTC | #4
Eric Botcazou <ebotcazou@adacore.com> wrote:
> I was referring to the ret_start/reg_end/nregs business: why is it necessary?

I thought that they are for the return value which requires
multiple hard registers.

Regards,
	kaz
Uros Bizjak Nov. 6, 2012, 2:33 p.m. UTC | #5
On Mon, Nov 5, 2012 at 11:58 PM, Kaz Kojima <kkojima@rr.iij4u.or.jp> wrote:

> The attached patch is to solve PR target/41993 which will affect
> targets using MODE_EXIT.
> Without it, we can't find all return registers for __builtin_return
> in mode-switching.c:create_pre_exit.  See the trail #4 by Uros in
> the PR for the details.  The patch is tested with bootstrap and
> regtested on i686-pc-linux-gnu with no new failures.  It's also
> tested on cross sh4-unknown-linux-gnu.

Attached patch adds the testcase from PR to the testsuite.

2012-11-06  Uros Bizjak  <ubizjak@gmail.com>

	PR middle-end/41993
	* gcc.dg/torture/pr41993.c: New test.

Tested on x86_64-pc-linux-gnu {,-m32}, committed to mainline SVN.

Uros.

/* { dg-do compile } */
/* { dg-options "-mavx -mvzeroupper" { target { i?86-*-* x86_64-*-* } } } */

short retframe_short (void *rframe)
{
  __builtin_return (rframe);
}
diff mbox

Patch

--- ORIG/trunk/gcc/mode-switching.c	2012-11-05 08:07:55.000000000 +0900
+++ trunk/gcc/mode-switching.c	2012-11-05 19:22:56.000000000 +0900
@@ -324,7 +324,10 @@  create_pre_exit (int n_entities, int *en
 		    else
 		      break;
 		    if (copy_start >= FIRST_PSEUDO_REGISTER)
-		      break;
+		      {
+			last_insn = return_copy;
+			continue;
+		      }
 		    copy_num
 		      = hard_regno_nregs[copy_start][GET_MODE (copy_reg)];