simplify_shift_const_1 has code to convert:

  (ashift (trunc (plus X C1)) C2)

into:

  (plus (ashift (trunc X) C2) C1<<C2)

The bug in the testcase was that it was calculating C1<<C2 in the mode
of the result rather than in the mode of X, but it wasn't truncating C1
to that mode first.

Generating temporary rtxes for this kind of thing is less than ideal,
but we're already doing that for the C2 argument and result, even though
we only want a HOST_WIDE_INT in the end.  Cleaning things up so that
operations can be done directly on wide_ints is future work.
E.g. using wi::lshift directly here would avoid the checks for things
like SHIFT_COUNT_TRUNCATED.

Tested on x86_64-linux-gnu.  OK to install?

Thanks,
Richard


gcc/
        PR rtl-optimization/61222
        * combine.c (simplify_shift_const_1): Fix modes used when handling
        PLUS.

gcc/testsuite/
        PR rtl-optimization/61222
        * gcc.c-torture/compile/pr61222-1.c: New test.
        * gcc.c-torture/compile/pr61222-2.c: Likewise.

Index: gcc/combine.c
===================================================================
--- gcc/combine.c       2014-05-21 12:05:45.273722308 +0100
+++ gcc/combine.c       2014-05-22 10:34:54.852807517 +0100
@@ -10349,9 +10349,10 @@ simplify_shift_const_1 (enum rtx_code co
          /* (ashift (plus foo C) N) is (plus (ashift foo N) C').  */
          if (code == ASHIFT
              && CONST_INT_P (XEXP (varop, 1))
-             && (new_rtx = simplify_const_binary_operation (ASHIFT, 
result_mode,
-                                                        XEXP (varop, 1),
-                                                        GEN_INT (count))) != 0
+             && (new_rtx = simplify_const_binary_operation
+                 (ASHIFT, result_mode,
+                  gen_int_mode (INTVAL (XEXP (varop, 1)), result_mode),
+                  GEN_INT (count))) != 0
              && CONST_INT_P (new_rtx)
              && merge_outer_ops (&outer_op, &outer_const, PLUS,
                                  INTVAL (new_rtx), result_mode, &complement_p))
@@ -10368,9 +10369,10 @@ simplify_shift_const_1 (enum rtx_code co
          if (code == LSHIFTRT
              && CONST_INT_P (XEXP (varop, 1))
              && mode_signbit_p (result_mode, XEXP (varop, 1))
-             && (new_rtx = simplify_const_binary_operation (code, result_mode,
-                                                        XEXP (varop, 1),
-                                                        GEN_INT (count))) != 0
+             && (new_rtx = simplify_const_binary_operation
+                 (code, result_mode,
+                  gen_int_mode (INTVAL (XEXP (varop, 1)), result_mode),
+                  GEN_INT (count))) != 0
              && CONST_INT_P (new_rtx)
              && merge_outer_ops (&outer_op, &outer_const, XOR,
                                  INTVAL (new_rtx), result_mode, &complement_p))
Index: gcc/testsuite/gcc.c-torture/compile/pr61222-1.c
===================================================================
--- /dev/null   2014-05-18 17:42:44.871287828 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr61222-1.c     2014-05-22 
10:33:39.458121563 +0100
@@ -0,0 +1,23 @@
+int a, b, d, e;
+char c;
+
+void
+foo ()
+{
+  for (; a; a++)
+    {
+      d = ((b == 0) ^ (129 + a));
+      c = d * 9;
+      e = c < 1;
+      if (e)
+       for (;;)
+         ;
+    }
+}
+
+int
+main ()
+{
+  foo ();
+  return 0;
+}
Index: gcc/testsuite/gcc.c-torture/compile/pr61222-2.c
===================================================================
--- /dev/null   2014-05-18 17:42:44.871287828 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr61222-2.c     2014-05-22 
10:33:39.458121563 +0100
@@ -0,0 +1,7 @@
+int a, b, d;
+int main (void)
+{
+  int c = a && 1;
+  d = 1 << (((c | (b - 842)) << 1) + 1);
+  return 0;
+}

Reply via email to