From c5c5ba89acc96e48bf6eed87489fcda3efcd7fc3 Mon Sep 17 00:00:00 2001
From: Jan Hubicka <jh@suse.cz>
Date: Tue, 12 Mar 2013 13:13:33 +0100
Subject: [PATCH] re PR rtl-optimization/56571 (ICE in
 copyprop_hardreg_forward_1, at regcprop.c (insn does not satisfy its
 constraints !))

	PR middle-end/56571
	* valtrack.c (cleanup_auto_inc_dec): Unshare clobbers originating
	from pseudos.
	* emit-rtl.c (verify_rtx_sharing): Likewise.
	(copy_insn_1): Likewise.
	* rtl.c (copy_rtx): Likewise.
	PR middle-end/56571
	* gcc.c-torture/compile/pr56571.c: New testcase.

From-SVN: r196612
---
 gcc/ChangeLog                                 |  9 +++++++++
 gcc/emit-rtl.c                                | 20 +++++++++++++++----
 gcc/rtl.c                                     |  6 +++++-
 gcc/testsuite/ChangeLog                       |  5 +++++
 gcc/testsuite/gcc.c-torture/compile/pr56571.c |  8 ++++++++
 gcc/valtrack.c                                |  6 +++++-
 6 files changed, 48 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr56571.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a31a28e92ccb..8fad9e630a9b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2013-03-11  Jan Hubicka  <jh@suse.cz>
+
+	PR middle-end/56571
+	* valtrack.c (cleanup_auto_inc_dec): Unshare clobbers originating
+	from pseudos.
+	* emit-rtl.c (verify_rtx_sharing): Likewise.
+	(copy_insn_1): Likewise.
+	* rtl.c (copy_rtx): Likewise.
+
 2013-03-11  Georg-Johann Lay  <avr@gjlay.de>
 
 	PR target/56591
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 2c70fb1841da..59cd38d40f4c 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -2580,10 +2580,14 @@ verify_rtx_sharing (rtx orig, rtx insn)
     case RETURN:
     case SIMPLE_RETURN:
     case SCRATCH:
-      return;
       /* SCRATCH must be shared because they represent distinct values.  */
+      return;
     case CLOBBER:
-      if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
+      /* Share clobbers of hard registers (like cc0), but do not share pseudo reg
+         clobbers or clobbers of hard registers that originated as pseudos.
+         This is needed to allow safe register renaming.  */
+      if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
+	  && ORIGINAL_REGNO (XEXP (x, 0)) == REGNO (XEXP (x, 0)))
 	return;
       break;
 
@@ -2797,7 +2801,11 @@ repeat:
       /* SCRATCH must be shared because they represent distinct values.  */
       return;
     case CLOBBER:
-      if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
+      /* Share clobbers of hard registers (like cc0), but do not share pseudo reg
+         clobbers or clobbers of hard registers that originated as pseudos.
+         This is needed to allow safe register renaming.  */
+      if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
+	  && ORIGINAL_REGNO (XEXP (x, 0)) == REGNO (XEXP (x, 0)))
 	return;
       break;
 
@@ -5303,7 +5311,11 @@ copy_insn_1 (rtx orig)
     case SIMPLE_RETURN:
       return orig;
     case CLOBBER:
-      if (REG_P (XEXP (orig, 0)) && REGNO (XEXP (orig, 0)) < FIRST_PSEUDO_REGISTER)
+      /* Share clobbers of hard registers (like cc0), but do not share pseudo reg
+         clobbers or clobbers of hard registers that originated as pseudos.
+         This is needed to allow safe register renaming.  */
+      if (REG_P (XEXP (orig, 0)) && REGNO (XEXP (orig, 0)) < FIRST_PSEUDO_REGISTER
+	  && ORIGINAL_REGNO (XEXP (orig, 0)) == REGNO (XEXP (orig, 0)))
 	return orig;
       break;
 
diff --git a/gcc/rtl.c b/gcc/rtl.c
index bc49fc86fe99..b2d88f783b77 100644
--- a/gcc/rtl.c
+++ b/gcc/rtl.c
@@ -256,7 +256,11 @@ copy_rtx (rtx orig)
       /* SCRATCH must be shared because they represent distinct values.  */
       return orig;
     case CLOBBER:
-      if (REG_P (XEXP (orig, 0)) && REGNO (XEXP (orig, 0)) < FIRST_PSEUDO_REGISTER)
+      /* Share clobbers of hard registers (like cc0), but do not share pseudo reg
+         clobbers or clobbers of hard registers that originated as pseudos.
+         This is needed to allow safe register renaming.  */
+      if (REG_P (XEXP (orig, 0)) && REGNO (XEXP (orig, 0)) < FIRST_PSEUDO_REGISTER
+	  && ORIGINAL_REGNO (XEXP (orig, 0)) == REGNO (XEXP (orig, 0)))
 	return orig;
       break;
 
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 578f0da29cdd..f4af3d5c34cd 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2013-03-11  Jan Hubicka  <jh@suse.cz>
+
+	PR middle-end/56571
+	* gcc.c-torture/compile/pr56571.c: New testcase.
+
 2013-03-11  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 
 	* gcc.dg/tree-ssa/vector-4.c: Add comment regarding xfail.
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr56571.c b/gcc/testsuite/gcc.c-torture/compile/pr56571.c
new file mode 100644
index 000000000000..248148c9ff84
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr56571.c
@@ -0,0 +1,8 @@
+/* { dg-options "-funroll-loops -ftracer" } */
+int a, b;
+
+int f(void)
+{
+    (a % b) && f();
+    a = (0 || a | (a ? : 1));
+}
diff --git a/gcc/valtrack.c b/gcc/valtrack.c
index 87ce3f665b0a..997f68b50891 100644
--- a/gcc/valtrack.c
+++ b/gcc/valtrack.c
@@ -71,7 +71,11 @@ cleanup_auto_inc_dec (rtx src, enum machine_mode mem_mode ATTRIBUTE_UNUSED)
       /* SCRATCH must be shared because they represent distinct values.  */
       return x;
     case CLOBBER:
-      if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
+      /* Share clobbers of hard registers (like cc0), but do not share pseudo reg
+         clobbers or clobbers of hard registers that originated as pseudos.
+         This is needed to allow safe register renaming.  */
+      if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
+	  && ORIGINAL_REGNO (XEXP (x, 0)) == REGNO (XEXP (x, 0)))
 	return x;
       break;
 
-- 
GitLab