This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] combine: Allow substituting the target reg of a clobber


On Sat, Sep 27, 2014 at 05:03:26PM -0500, Segher Boessenkool wrote:
> I've tried to make a stable future-proof testcase that does such a three-insn
> combination.  Not easy at all.

Turns out it is quite easy (when you've seen the solution, anyway :-P )

Tested on powerpc64-linux as before, and bootstrapped + regression checked
on x86_64-linux.  Also checked the testcase fails before on i386 and x86_64,
and works afterwards.

Does this look good?


Segher



2014-10-02  Segher Boessenkool  <segher@kernel.crashing.org>

gcc/
	PR rtl-optimization/62151
	* combine.c (can_combine_p): Allow the destination register of INSN
	to be clobbered in I3.
	(subst): Do not substitute into clobbers of registers.

gcc/testsuite/
	* gcc.dg/combine-clobber.c: New.



diff --git a/gcc/combine.c b/gcc/combine.c
index 1457eab..ff5f0db 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -1950,11 +1950,7 @@ can_combine_p (rtx_insn *insn, rtx_insn *i3, rtx_insn *pred ATTRIBUTE_UNUSED,
     for (i = XVECLEN (PATTERN (i3), 0) - 1; i >= 0; i--)
       if (GET_CODE (XVECEXP (PATTERN (i3), 0, i)) == CLOBBER)
 	{
-	  /* Don't substitute for a register intended as a clobberable
-	     operand.  */
 	  rtx reg = XEXP (XVECEXP (PATTERN (i3), 0, i), 0);
-	  if (rtx_equal_p (reg, dest))
-	    return 0;
 
 	  /* If the clobber represents an earlyclobber operand, we must not
 	     substitute an expression containing the clobbered register.
@@ -4963,6 +4959,11 @@ subst (rtx x, rtx from, rtx to, int in_dest, int in_cond, int unique_copy)
    || (REG_P (X) && REG_P (Y)	\
        && REGNO (X) == REGNO (Y) && GET_MODE (X) == GET_MODE (Y)))
 
+  /* Do not substitute into clobbers of regs -- this will never result in
+     valid RTL.  */
+  if (GET_CODE (x) == CLOBBER && REG_P (XEXP (x, 0)))
+    return x;
+
   if (! in_dest && COMBINE_RTX_EQUAL_P (x, from))
     {
       n_occurrences++;
diff --git a/gcc/testsuite/gcc.dg/combine-clobber.c b/gcc/testsuite/gcc.dg/combine-clobber.c
new file mode 100644
index 0000000..bf0d88c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/combine-clobber.c
@@ -0,0 +1,22 @@
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -fdump-rtl-combine-all" } */
+
+/* This testcase checks if combine tries to combine sequences where the last
+   insn has a clobber of a reg, and a previous insn sets that reg.
+
+   In this case, we have three insns
+
+   (set flags (compare a b))
+   (set tmp (eq flags 0))
+   (parallel [(set dst (neg tmp))
+	      (clobber flags)])
+
+   Previously, combine would not try the three-insn combination because of
+   the set and clobber of flags.  Now it does.  Test that.  */
+
+
+int f(int a, int b) { return -(a == b); }
+
+/* This regexp works for reg parameters as well as mem parameters.  */
+/* { dg-final { scan-rtl-dump {neg:SI[^:]*eq:SI[^:]*:SI} "combine" } } */
+/* { dg-final { cleanup-rtl-dump "combine" } } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]