Hi!

The following testcase ICEs in wide-int*, but the reason is a mode mismatch
(we build a SImode MULT with one QImode argument and one VOIDmode argument,
then it is folded into SImode NEG with QImode argument, ...).
The bug is in assuming that the mode of c1 must be m, that is usually the
case, but shifts are special, the second argument can have a different mode.

The following patch makes sure we perform the computation of the new shift
count in the right mode.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2017-11-24  Jakub Jelinek  <ja...@redhat.com>

        PR rtl-optimization/81553
        * combine.c (simplify_if_then_else): In (if_then_else COND (OP Z C1) Z)
        to (OP Z (mult COND (C1 * STORE_FLAG_VALUE))) optimization, if OP
        is a shift where C1 has different mode than the whole shift, use C1's
        mode for MULT rather than the shift's mode.

        * gcc.c-torture/compile/pr81553.c: New test.

--- gcc/combine.c.jj    2017-11-19 18:08:08.000000000 +0100
+++ gcc/combine.c       2017-11-24 12:07:25.701480794 +0100
@@ -6639,11 +6639,15 @@ simplify_if_then_else (rtx x)
 
       if (z)
        {
-         temp = subst (simplify_gen_relational (true_code, m, VOIDmode,
+         machine_mode cm = m;
+         if ((op == ASHIFT || op == LSHIFTRT || op == ASHIFTRT)
+             && GET_MODE (c1) != VOIDmode)
+           cm = GET_MODE (c1);
+         temp = subst (simplify_gen_relational (true_code, cm, VOIDmode,
                                                 cond_op0, cond_op1),
                        pc_rtx, pc_rtx, 0, 0, 0);
-         temp = simplify_gen_binary (MULT, m, temp,
-                                     simplify_gen_binary (MULT, m, c1,
+         temp = simplify_gen_binary (MULT, cm, temp,
+                                     simplify_gen_binary (MULT, cm, c1,
                                                           const_true_rtx));
          temp = subst (temp, pc_rtx, pc_rtx, 0, 0, 0);
          temp = simplify_gen_binary (op, m, gen_lowpart (m, z), temp);
--- gcc/testsuite/gcc.c-torture/compile/pr81553.c.jj    2017-11-24 
12:11:25.681551110 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr81553.c       2017-11-24 
12:10:55.000000000 +0100
@@ -0,0 +1,10 @@
+/* PR rtl-optimization/81553 */
+
+int a, b, c, d;
+
+void
+foo (void)
+{
+  d = 1 >> c >> 1;
+  b = ~(209883449764912897ULL & d) << (0 >= a) | ~d;
+}

        Jakub

Reply via email to