Jeff Law <l...@redhat.com> writes:
> On 01/24/14 01:24, Richard Sandiford wrote:
>> Richard Sandiford <rdsandif...@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()

Reply via email to