public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Avoid zext/sext directly from hard registers during expansion (PR rtl-optimization/53942)
@ 2012-07-17  9:51 Jakub Jelinek
  2012-07-19 19:36 ` Richard Henderson
  0 siblings, 1 reply; 2+ messages in thread
From: Jakub Jelinek @ 2012-07-17  9:51 UTC (permalink / raw)
  To: gcc-patches

Hi!

The following testcase ICEs on i?86, because combiner sees a zero extension
of the likely spilled cx register generated during expansion and as it is
not a simple register move, propagates it into a use many insns later in the
function, enlarging thus the lifetime of the hard register and causing RA
failure on a register in between the two that needs to use that particular
hard register.

cant_combine_insn_p only special cases simple register moves out of or into
likely spilled hard registers.  The following patch fixes it by using
roughly the same condition to decide if it is ok to emit a zero or sign
extension directly from the hard register or if it is better to first copy
the hard register into a pseudo (then combiner (and fwprop etc.) seem to do
the right thing).

Bootstrapped/regtested on x86_64-linux and i686-linux, on both I've verified
it doesn't affect code generation for cc1plus (appart from function.o
obviously), libstdc++.so and libgcj.so.  Ok for trunk (and perhaps after a
while for the 4.7 branch)?

2012-07-17  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/53942
	* function.c (assign_parm_setup_reg): Avoid zero/sign extension
	directly from likely spilled non-fixed hard registers, move them
	to pseudo first.

	* gcc.dg/pr53942.c: New test.

--- gcc/function.c.jj	2012-06-25 08:38:26.000000000 +0200
+++ gcc/function.c	2012-07-16 13:41:52.847928315 +0200
@@ -2988,11 +2988,26 @@ assign_parm_setup_reg (struct assign_par
 	  && insn_operand_matches (icode, 1, op1))
 	{
 	  enum rtx_code code = unsignedp ? ZERO_EXTEND : SIGN_EXTEND;
-	  rtx insn, insns;
+	  rtx insn, insns, t = op1;
 	  HARD_REG_SET hardregs;
 
 	  start_sequence ();
-	  insn = gen_extend_insn (op0, op1, promoted_nominal_mode,
+	  /* If op1 is a hard register that is likely spilled, first
+	     force it into a pseudo, otherwise combiner might extend
+	     its lifetime too much.  */
+	  if (GET_CODE (t) == SUBREG)
+	    t = SUBREG_REG (t);
+	  if (REG_P (t)
+	      && HARD_REGISTER_P (t)
+	      && ! TEST_HARD_REG_BIT (fixed_reg_set, REGNO (t))
+	      && targetm.class_likely_spilled_p (REGNO_REG_CLASS (REGNO (t))))
+	    {
+	      t = gen_reg_rtx (GET_MODE (op1));
+	      emit_move_insn (t, op1);
+	    }
+	  else
+	    t = op1;
+	  insn = gen_extend_insn (op0, t, promoted_nominal_mode,
 				  data->passed_mode, unsignedp);
 	  emit_insn (insn);
 	  insns = get_insns ();
--- gcc/testsuite/gcc.dg/pr53942.c.jj	2012-06-15 19:53:34.312404791 +0200
+++ gcc/testsuite/gcc.dg/pr53942.c	2012-07-17 11:26:48.863053287 +0200
@@ -0,0 +1,34 @@
+/* PR rtl-optimization/53942 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-mtune=pentium2" { target { { i?86-*-* x86_64-*-* } && ia32 } } } */
+
+struct S
+{
+  unsigned short w[3];
+  unsigned int x, y;
+};
+
+struct S *baz (void);
+
+__attribute__ ((noinline))
+static unsigned char
+foo (struct S *x, unsigned char y)
+{
+  unsigned char c = 0;
+  unsigned char v = x->w[0];
+  c |= v;
+  v = ((x->w[1]) & (1 << y)) ? 1 : 0;
+  c |= v << 1;
+  v = ((x->w[2]) & 0xff) & (1 << y);
+  c |= v << 2;
+  return c;
+}
+
+void
+bar (void)
+{
+  struct S *s = baz ();
+  s->x = foo (s, 6);
+  s->y = foo (s, 7);
+}

	Jakub

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Avoid zext/sext directly from hard registers during expansion (PR rtl-optimization/53942)
  2012-07-17  9:51 [PATCH] Avoid zext/sext directly from hard registers during expansion (PR rtl-optimization/53942) Jakub Jelinek
@ 2012-07-19 19:36 ` Richard Henderson
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Henderson @ 2012-07-19 19:36 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches

On 07/17/2012 02:50 AM, Jakub Jelinek wrote:
> 2012-07-17  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR rtl-optimization/53942
> 	* function.c (assign_parm_setup_reg): Avoid zero/sign extension
> 	directly from likely spilled non-fixed hard registers, move them
> 	to pseudo first.
> 
> 	* gcc.dg/pr53942.c: New test.


Ok.


r~

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2012-07-19 19:36 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-17  9:51 [PATCH] Avoid zext/sext directly from hard registers during expansion (PR rtl-optimization/53942) Jakub Jelinek
2012-07-19 19:36 ` Richard Henderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).