combine.c (simplify_shift_const, case XOR): Be careful when commuting XOR with ASHIFTRT.
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>
Fri, 30 Jan 2004 15:36:11 +0000 (15:36 +0000)
committerRichard Kenner <kenner@gcc.gnu.org>
Fri, 30 Jan 2004 15:36:11 +0000 (10:36 -0500)
* combine.c (simplify_shift_const, case XOR): Be careful when
commuting XOR with ASHIFTRT.

From-SVN: r76965

gcc/ChangeLog
gcc/combine.c

index 115979032b0b7df766e5fa9e80d849ae152bd5f5..91a921a98abf5824fcb924622e7bbb76a48bed58 100644 (file)
@@ -1,3 +1,8 @@
+2004-01-30  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
+
+       * combine.c (simplify_shift_const, case XOR): Be careful when
+       commuting XOR with ASHIFTRT.
+
 2004-01-30  Kazu Hirata  <kazu@cs.umass.edu>
             Eric Botcazou  <ebotcazou@libertysurf.fr>
 
index 9137076ad30678214af49d16a73be03aa9896565..130bda9c429c1e34967c5dfc31945e937acec2fd 100644 (file)
@@ -9568,6 +9568,11 @@ simplify_shift_const (rtx x, enum rtx_code code,
             (and (shift)) insns.  */
 
          if (GET_CODE (XEXP (varop, 1)) == CONST_INT
+             /* We can't do this if we have (ashiftrt (xor))  and the
+                constant has its sign bit set in shift_mode.  */
+             && !(code == ASHIFTRT && GET_CODE (varop) == XOR
+                  && 0 > trunc_int_for_mode (INTVAL (XEXP (varop, 1)),
+                                             shift_mode))
              && (new = simplify_binary_operation (code, result_mode,
                                                   XEXP (varop, 1),
                                                   GEN_INT (count))) != 0
@@ -9581,18 +9586,22 @@ simplify_shift_const (rtx x, enum rtx_code code,
 
          /* If we can't do that, try to simplify the shift in each arm of the
             logical expression, make a new logical expression, and apply
-            the inverse distributive law.  */
-         {
-           rtx lhs = simplify_shift_const (NULL_RTX, code, shift_mode,
-                                           XEXP (varop, 0), count);
-           rtx rhs = simplify_shift_const (NULL_RTX, code, shift_mode,
-                                           XEXP (varop, 1), count);
+            the inverse distributive law.  This also can't be done
+            for some (ashiftrt (xor)).  */
+         if (code != ASHIFTRT || GET_CODE (varop)!= XOR
+             || 0 <= trunc_int_for_mode (INTVAL (XEXP (varop, 1)),
+                                         shift_mode))
+           {
+             rtx lhs = simplify_shift_const (NULL_RTX, code, shift_mode,
+                                             XEXP (varop, 0), count);
+             rtx rhs = simplify_shift_const (NULL_RTX, code, shift_mode,
+                                             XEXP (varop, 1), count);
 
-           varop = gen_binary (GET_CODE (varop), shift_mode, lhs, rhs);
-           varop = apply_distributive_law (varop);
+             varop = gen_binary (GET_CODE (varop), shift_mode, lhs, rhs);
+             varop = apply_distributive_law (varop);
 
-           count = 0;
-         }
+             count = 0;
+           }
          break;
 
        case EQ: