[backport from gcc-4.7/trunk ] From: "Andreas Krebbel" Date: Fri, 4 Mar 2011 13:04:53 +0100 Subject: [PATCH] recog.c: Fix RTX unsharing in change groups List-Archive: Hi, we currently miss to do RTX unsharing in some cases when mixing validate_change requests with and without rtx unsharing in the same change group. Debugging a setjmp testcase on s390 I've seen the following behaviour: In an insn like A = B + C B is replaced with D in fold_rtx. Unsharing is requested for D in this replacement (A = D + C). Later on fold_rtx invokes canonicalize_change_group which decides to swap D and C without requesting unsharing again (A = C + D). Since the unsharing for a change group is delayed until confirm_change_group and is bound to a location rather then the expression C is unshared instead of D then. The attached patch prevents that by doing RTX unsharing for all subsequent changes after finding a single change where unsharing has been explicitly requested. Ok for mainline? From: "Andreas Krebbel" Date: Tue, 22 Mar 2011 08:46:32 +0100 Subject: [PATCH] recog.c: Fix RTX unsharing in change groups - v2 List-Archive: Hi, this is an alternate solution to the problem described in: http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00187.html Although I still prefer the patch above since it would make validate_change easier to use I understand that it might add unnecessary unsharing. The unsharing for subsequent changes is only needed if these changes re-use parts of previous changes and insert it at a different location in the insn and that's probably a rare case. Swapping operands like in canonicalize_change_group is one example which can be easily fixed. Done with the attached patch. Ok for mainline? gcc/ 2011-03-22 Andreas Krebbel * recog.c (canonicalize_change_group): Use validate_unshare_change. --- gcc-4.6.0/gcc/recog.c.~1~ 2010-11-30 17:36:19.000000000 +0100 +++ gcc-4.6.0/gcc/recog.c 2011-05-14 15:58:02.000000000 +0200 @@ -277,8 +277,8 @@ canonicalize_change_group (rtx insn, rtx /* Oops, the caller has made X no longer canonical. Let's redo the changes in the correct order. */ rtx tem = XEXP (x, 0); - validate_change (insn, &XEXP (x, 0), XEXP (x, 1), 1); - validate_change (insn, &XEXP (x, 1), tem, 1); + validate_unshare_change (insn, &XEXP (x, 0), XEXP (x, 1), 1); + validate_unshare_change (insn, &XEXP (x, 1), tem, 1); return true; } else