[backport gcc-4.8/trunk r196612, adjusted for cleanup_auto_inc_dec being in combine.c not valtrack.c ] Date: Mon, 11 Mar 2013 19:06:13 +0100 From: Jan Hubicka Subject: Fix sharing of clobbers List-Archive: Hi, in the testcase we die in post-reload cprop because updating one insn clobber actually affect other insn clobber. I actually introduced clobber sharing back in 2005 to save memory for (clobber cc0). This broke with introduction of post-reload code copying that is now done by shrink wrapping. Fixed by unsharing those clobbers that originate from pseudos. Bootstrapped/regtested x86_64-linux, OK? gcc/ 2013-03-11 Jan Hubicka 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. gcc/testsuite/ 2013-03-11 Jan Hubicka PR middle-end/56571 * gcc.c-torture/compile/pr56571.c: New testcase. --- gcc-4.7.2/gcc/combine.c.~1~ 2012-08-09 17:33:28.000000000 +0200 +++ gcc-4.7.2/gcc/combine.c 2013-03-15 08:53:38.519178243 +0100 @@ -2387,7 +2387,11 @@ cleanup_auto_inc_dec (rtx src, enum mach /* 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; --- gcc-4.7.2/gcc/emit-rtl.c.~1~ 2012-02-22 11:37:03.000000000 +0100 +++ gcc-4.7.2/gcc/emit-rtl.c 2013-03-15 08:53:38.529178204 +0100 @@ -2524,10 +2524,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; @@ -2744,7 +2748,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; @@ -5281,7 +5289,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; --- gcc-4.7.2/gcc/rtl.c.~1~ 2011-09-13 01:38:21.000000000 +0200 +++ gcc-4.7.2/gcc/rtl.c 2013-03-15 08:53:38.529178204 +0100 @@ -261,7 +261,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; --- gcc-4.7.2/gcc/testsuite/gcc.c-torture/compile/pr56571.c.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.7.2/gcc/testsuite/gcc.c-torture/compile/pr56571.c 2013-03-15 08:53:38.519178243 +0100 @@ -0,0 +1,8 @@ +/* { dg-options "-funroll-loops -ftracer" } */ +int a, b; + +int f(void) +{ + (a % b) && f(); + a = (0 || a | (a ? : 1)); +}