diff mbox

Fix REE (PR rtl-optimization/53160)

Message ID 20120430134308.GM16117@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek April 30, 2012, 1:43 p.m. UTC
Hi!

As shown on the testcase below, if REE modifies some sign/zero extension
insn, which is on the candidate vector, as a def_insn of some other
extension, before combine_reaching_defs is called on that insn, we might
ignore the changes done to that insn and just assume it is only an
extension to the recorded mode.  It might be an extension to a wider mode
though.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
ok for trunk/4.7?

2012-04-30  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/53160
	* ree.c (combine_reaching_defs): Handle the case where cand->insn
	has been modified by ree pass already.

	* gcc.c-torture/execute/pr53160.c: New test.


	Jakub

Comments

Richard Henderson April 30, 2012, 6:58 p.m. UTC | #1
On 04/30/2012 06:43 AM, Jakub Jelinek wrote:
> Hi!
>
> As shown on the testcase below, if REE modifies some sign/zero extension
> insn, which is on the candidate vector, as a def_insn of some other
> extension, before combine_reaching_defs is called on that insn, we might
> ignore the changes done to that insn and just assume it is only an
> extension to the recorded mode.  It might be an extension to a wider mode
> though.
>
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
> ok for trunk/4.7?
>
> 2012-04-30  Jakub Jelinek<jakub@redhat.com>
>
> 	PR rtl-optimization/53160
> 	* ree.c (combine_reaching_defs): Handle the case where cand->insn
> 	has been modified by ree pass already.
>
> 	* gcc.c-torture/execute/pr53160.c: New test.
>

Ok.


r~
diff mbox

Patch

--- gcc/ree.c.jj	2012-01-31 11:04:34.000000000 +0100
+++ gcc/ree.c	2012-04-30 11:24:02.682520157 +0200
@@ -667,6 +667,24 @@  combine_reaching_defs (ext_cand *cand, c
   if (!outcome)
     return false;
 
+  /* If cand->insn has been already modified, update cand->mode to a wider
+     mode if possible, or punt.  */
+  if (state->modified[INSN_UID (cand->insn)].kind != EXT_MODIFIED_NONE)
+    {
+      enum machine_mode mode;
+      rtx set;
+
+      if (state->modified[INSN_UID (cand->insn)].kind
+	  != (cand->code == ZERO_EXTEND
+	      ? EXT_MODIFIED_ZEXT : EXT_MODIFIED_SEXT)
+	  || state->modified[INSN_UID (cand->insn)].mode != cand->mode
+	  || (set = single_set (cand->insn)) == NULL_RTX)
+	return false;
+      mode = GET_MODE (SET_DEST (set));
+      gcc_assert (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (cand->mode));
+      cand->mode = mode;
+    }
+
   merge_successful = true;
 
   /* Go through the defs vector and try to merge all the definitions
--- gcc/testsuite/gcc.c-torture/execute/pr53160.c.jj	2012-04-30 11:34:33.807798084 +0200
+++ gcc/testsuite/gcc.c-torture/execute/pr53160.c	2012-04-30 11:34:18.000000000 +0200
@@ -0,0 +1,35 @@ 
+/* PR rtl-optimization/53160 */
+
+extern void abort (void);
+
+int a, c = 1, d, e, g;
+volatile int b;
+volatile char f;
+long h;
+short i;
+
+void
+foo (void)
+{
+  for (e = 0; e; ++e)
+    ;
+}
+
+int
+main ()
+{
+  if (g)
+    (void) b;
+  foo ();
+  for (d = 0; d >= 0; d--)
+    {
+      short j = f;
+      int k = 0;
+      i = j ? j : j << k;
+    }
+  h = c == 0 ? 0 : i;
+  a = h;
+  if (a != 0)
+    abort ();
+  return 0;
+}