diff mbox

Fix combiner with (set (pc) (pc)) jumps in undo_buf.other_insn (PR rtl-optimization/47157)

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

Commit Message

Jakub Jelinek Jan. 3, 2011, 2:36 p.m. UTC
Hi!

If try_combine turns a JUMP_INSN into a noop move, it correctly calls
update_cfg_for_uncondjump on it and sets *new_direct_jump_p if the
noop move is in i3, but as shown on the testcase below, a jump can
be turned into a noop move also when adjusting the only CC user and in that
case we wouldn't do the necessary cfg adjustments.

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

2011-01-03  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/47157
	* combine.c (try_combine): If undobuf.other_insn becomes
	(set (pc) (pc)) jump, call update_cfg_for_uncondjump on it
	and set *new_direct_jump_p too.

	* gcc.c-torture/compile/pr47157.c: New test.


	Jakub

Comments

Paolo Bonzini Jan. 3, 2011, 4:05 p.m. UTC | #1
On 01/03/2011 03:36 PM, Jakub Jelinek wrote:
> Hi!
>
> If try_combine turns a JUMP_INSN into a noop move, it correctly calls
> update_cfg_for_uncondjump on it and sets *new_direct_jump_p if the
> noop move is in i3, but as shown on the testcase below, a jump can
> be turned into a noop move also when adjusting the only CC user and in that
> case we wouldn't do the necessary cfg adjustments.
>
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
> trunk?

Looks good to me.

Paolo
Eric Botcazou Jan. 3, 2011, 5:22 p.m. UTC | #2
> 2011-01-03  Jakub Jelinek  <jakub@redhat.com>
>
> 	PR rtl-optimization/47157
> 	* combine.c (try_combine): If undobuf.other_insn becomes
> 	(set (pc) (pc)) jump, call update_cfg_for_uncondjump on it
> 	and set *new_direct_jump_p too.
>
> 	* gcc.c-torture/compile/pr47157.c: New test.

OK, thanks.
diff mbox

Patch

--- gcc/combine.c.jj	2010-12-02 11:51:32.000000000 +0100
+++ gcc/combine.c	2011-01-03 11:07:59.000000000 +0100
@@ -4378,6 +4378,15 @@  try_combine (rtx i3, rtx i2, rtx i1, rtx
       update_cfg_for_uncondjump (i3);
     }
 
+  if (undobuf.other_insn != NULL_RTX
+      && GET_CODE (PATTERN (undobuf.other_insn)) == SET
+      && SET_SRC (PATTERN (undobuf.other_insn)) == pc_rtx
+      && SET_DEST (PATTERN (undobuf.other_insn)) == pc_rtx)
+    {
+      *new_direct_jump_p = 1;
+      update_cfg_for_uncondjump (undobuf.other_insn);
+    }
+
   combine_successes++;
   undo_commit ();
 
--- gcc/testsuite/gcc.c-torture/compile/pr47157.c.jj	2011-01-03 11:21:37.000000000 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr47157.c	2011-01-03 11:21:17.000000000 +0100
@@ -0,0 +1,20 @@ 
+/* PR rtl-optimization/47157 */
+
+struct S { unsigned a; unsigned b; } c = { 1, 0 };
+unsigned long int e;
+void bar (int);
+int baz (void);
+
+static int
+foo (int x, short y)
+{
+  return ((x ^ y) & ((x ^ (x ^ y) & ~__INT_MAX__) - y ^ y)) < 0 ? x : x - y;
+}
+
+void
+test (void)
+{
+  bar (foo (baz () != (c.a | c.b), -1L));
+  for (e = 0; e; e = 1)
+    ;
+}