Handle XOR in canonicalize_condition

Richard Sandiford rdsandiford@googlemail.com
Sat Jan 25 20:03:00 GMT 2014


Jeff Law <law@redhat.com> writes:
> On 01/24/14 01:24, Richard Sandiford wrote:
>> Richard Sandiford <rdsandiford@googlemail.com> writes:
>>> The other problem is related to the way that MIPS16 tests for equality.
>>> Conditional branches test register $24, and the only instructions that
>>> set $24 are MOVE and CMP(I), which is actually an XOR rather than a
>>> subtraction.
>>
>> Er, don't know what I was thinking here, but please ignore this summary
>> of the ISA.  There are conditional branches to test MIPS16 registers
>> and other ways of setting $24.  (But other than that...)
>>
>> The patch itself still stands though.
> Right.  This is just the RTL version of what I did for trees about a 
> year ago.
>
> The comment is a bit misleading as far as pulling things out of the RTL. 
>   You're showing it a combined form.  SET is something like
> (set (reg) (xor (reg) (reg))) if I'm reading everything correctly.
>
> Please try to improve the comment and you're good to go.  No need to 
> wait for further review, but please post the final form for the archivers.

Thanks, here's what I applied.

Richard


gcc/
	* rtlanal.c (canonicalize_condition): Split out duplicated mode check.
	Handle XOR.

gcc/testsuite/
	* gcc.dg/unroll_1.c: Add -fenable-rtl-loop2.

Index: gcc/rtlanal.c
===================================================================
--- gcc/rtlanal.c	2014-01-23 22:27:57.176646235 +0000
+++ gcc/rtlanal.c	2014-01-25 20:00:19.952181804 +0000
@@ -5051,23 +5051,24 @@ canonicalize_condition (rtx insn, rtx co
 
 	     ??? This mode check should perhaps look more like the mode check
 	     in simplify_comparison in combine.  */
-
-	  if ((GET_CODE (SET_SRC (set)) == COMPARE
-	       || (((code == NE
-		     || (code == LT
-			 && val_signbit_known_set_p (inner_mode,
-						     STORE_FLAG_VALUE))
+	  if (((GET_MODE_CLASS (mode) == MODE_CC)
+	       != (GET_MODE_CLASS (inner_mode) == MODE_CC))
+	      && mode != VOIDmode
+	      && inner_mode != VOIDmode)
+	    break;
+	  if (GET_CODE (SET_SRC (set)) == COMPARE
+	      || (((code == NE
+		    || (code == LT
+			&& val_signbit_known_set_p (inner_mode,
+						    STORE_FLAG_VALUE))
 #ifdef FLOAT_STORE_FLAG_VALUE
-		     || (code == LT
-			 && SCALAR_FLOAT_MODE_P (inner_mode)
-			 && (fsfv = FLOAT_STORE_FLAG_VALUE (inner_mode),
-			     REAL_VALUE_NEGATIVE (fsfv)))
+		    || (code == LT
+			&& SCALAR_FLOAT_MODE_P (inner_mode)
+			&& (fsfv = FLOAT_STORE_FLAG_VALUE (inner_mode),
+			    REAL_VALUE_NEGATIVE (fsfv)))
 #endif
-		     ))
-		   && COMPARISON_P (SET_SRC (set))))
-	      && (((GET_MODE_CLASS (mode) == MODE_CC)
-		   == (GET_MODE_CLASS (inner_mode) == MODE_CC))
-		  || mode == VOIDmode || inner_mode == VOIDmode))
+		    ))
+		  && COMPARISON_P (SET_SRC (set))))
 	    x = SET_SRC (set);
 	  else if (((code == EQ
 		     || (code == GE
@@ -5080,15 +5081,25 @@ canonicalize_condition (rtx insn, rtx co
 			     REAL_VALUE_NEGATIVE (fsfv)))
 #endif
 		     ))
-		   && COMPARISON_P (SET_SRC (set))
-		   && (((GET_MODE_CLASS (mode) == MODE_CC)
-			== (GET_MODE_CLASS (inner_mode) == MODE_CC))
-		       || mode == VOIDmode || inner_mode == VOIDmode))
-
+		   && COMPARISON_P (SET_SRC (set)))
 	    {
 	      reverse_code = 1;
 	      x = SET_SRC (set);
 	    }
+	  else if ((code == EQ || code == NE)
+		   && GET_CODE (SET_SRC (set)) == XOR)
+	    /* Handle sequences like:
+
+	       (set op0 (xor X Y))
+	       ...(eq|ne op0 (const_int 0))...
+
+	       in which case:
+
+	       (eq op0 (const_int 0)) reduces to (eq X Y)
+	       (ne op0 (const_int 0)) reduces to (ne X Y)
+
+	       This is the form used by MIPS16, for example.  */
+	    x = SET_SRC (set);
 	  else
 	    break;
 	}
Index: gcc/testsuite/gcc.dg/unroll_1.c
===================================================================
--- gcc/testsuite/gcc.dg/unroll_1.c	2014-01-23 22:27:57.176646235 +0000
+++ gcc/testsuite/gcc.dg/unroll_1.c	2014-01-24 17:52:54.258209196 +0000
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-rtl-loop2_unroll=stderr -fno-peel-loops -fno-tree-vrp -fdisable-tree-cunroll -fdisable-tree-cunrolli -fenable-rtl-loop2_unroll" } */
+/* { dg-options "-O2 -fdump-rtl-loop2_unroll=stderr -fno-peel-loops -fno-tree-vrp -fdisable-tree-cunroll -fdisable-tree-cunrolli -fenable-rtl-loop2 -fenable-rtl-loop2_unroll" } */
 
 unsigned a[100], b[100];
 inline void bar()



More information about the Gcc-patches mailing list