diff mbox

combine: Handle aborts in is_parallel_of_n_reg_sets (PR68381)

Message ID 579c3fee8ef39fe70575bd5e0a38ee866faf564a.1448345542.git.segher@kernel.crashing.org
State New
Headers show

Commit Message

Segher Boessenkool Nov. 24, 2015, 6:37 a.m. UTC
Some users of is_parallel_of_n_reg_sets disregard the clobbers in a
parallel after it has returned "yes, this is a parallel of N sets and
maybe some clobbers".  But combine uses a clobber of const0_rtx to
indicate substitution failure, so this leads to disaster.

Fix this by checking for such special clobbers in is_parallel_of_n_reg_sets.

Tested on powerpc64-linux.  Also tested with Kyrill's testcase, manually
inspected the generated asm and the combine dump file (with some extra
instrumentation).  This testcase needs -O1 btw.

The "performance problem" in the PR (same testcase, but with -O3) is
a missed jump optimization: a pseudo is set (to 0) in one BB (and
nowhere else), and then tested against 0 in another BB.  Nothing after
combine seems to handle this.

Applying this patch to trunk.  Kyrill, could you handle the testcase?
Together with whatever you decide should be done for the -O3 problem.
Thank you for tracking down this nastiness!


Segher


2015-11-24  Segher Boessenkool  <segher@kernel.crashing.org>

	PR rtl-optimization/68381
	* combine.c (is_parallel_of_n_reg_sets): Return false if the pattern
	is poisoned.

---
 gcc/combine.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
diff mbox

Patch

diff --git a/gcc/combine.c b/gcc/combine.c
index 2a66fd5..4958d3b 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -2512,7 +2512,8 @@  is_parallel_of_n_reg_sets (rtx pat, int n)
 	|| !REG_P (SET_DEST (XVECEXP (pat, 0, i))))
       return false;
   for ( ; i < len; i++)
-    if (GET_CODE (XVECEXP (pat, 0, i)) != CLOBBER)
+    if (GET_CODE (XVECEXP (pat, 0, i)) != CLOBBER
+	|| XEXP (XVECEXP (pat, 0, i), 0) == const0_rtx)
       return false;
 
   return true;