re PR rtl-optimization/65321 (ICE on valid code at -O2 and -O3 with -g enabled in...
authorJakub Jelinek <jakub@redhat.com>
Tue, 10 Mar 2015 06:36:50 +0000 (07:36 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 10 Mar 2015 06:36:50 +0000 (07:36 +0100)
PR rtl-optimization/65321
* cfgexpand.c (expand_debug_expr): Ensure shift amount isn't wider
than shift mode.
* var-tracking.c (use_narrower_mode): Likewise.

* gcc.dg/pr65321.c: New test.

From-SVN: r221298

gcc/ChangeLog
gcc/cfgexpand.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr65321.c [new file with mode: 0644]
gcc/var-tracking.c

index 0cbeaa3b9e32c0cd35706021408fb6c47320031b..0ba2886d66eda49c19fae9bc63dce846f3131f9b 100644 (file)
@@ -1,3 +1,10 @@
+2015-03-10  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/65321
+       * cfgexpand.c (expand_debug_expr): Ensure shift amount isn't wider
+       than shift mode.
+       * var-tracking.c (use_narrower_mode): Likewise.
+
 2015-03-10  Jan Hubicka  <hubicka@ucw.cz>
 
        PR tree-optimization/65355
index 93d894f37419399c9d4670779f9d58ad810ba6bf..67be09fc7ee2f846c533b97c8e2ea6dd5c875f16 100644 (file)
@@ -3921,6 +3921,31 @@ expand_debug_expr (tree exp)
       op1 = expand_debug_expr (TREE_OPERAND (exp, 1));
       if (!op1)
        return NULL_RTX;
+      switch (TREE_CODE (exp))
+       {
+       case LSHIFT_EXPR:
+       case RSHIFT_EXPR:
+       case LROTATE_EXPR:
+       case RROTATE_EXPR:
+       case WIDEN_LSHIFT_EXPR:
+         /* Ensure second operand isn't wider than the first one.  */
+         inner_mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 1)));
+         if (SCALAR_INT_MODE_P (inner_mode))
+           {
+             machine_mode opmode = mode;
+             if (VECTOR_MODE_P (mode))
+               opmode = GET_MODE_INNER (mode);
+             if (SCALAR_INT_MODE_P (opmode)
+                 && (GET_MODE_PRECISION (opmode)
+                     < GET_MODE_PRECISION (inner_mode)))
+               op1 = simplify_gen_subreg (opmode, op1, inner_mode,
+                                          subreg_lowpart_offset (opmode,
+                                                                 inner_mode));
+           }
+         break;
+       default:
+         break;
+       }
       /* Fall through.  */
 
     unary:
index ec7a3bc5ba4bc96fec68e448700ad50278469f55..6c9ae2ca96e41df8179f2e084eb6d8b0dc247a97 100644 (file)
@@ -1,3 +1,8 @@
+2015-03-10  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/65321
+       * gcc.dg/pr65321.c: New test.
+
 2015-03-10  Jan Hubicka  <hubicka@ucw.cz>
 
        PR tree-optimization/65355
diff --git a/gcc/testsuite/gcc.dg/pr65321.c b/gcc/testsuite/gcc.dg/pr65321.c
new file mode 100644 (file)
index 0000000..294487c
--- /dev/null
@@ -0,0 +1,31 @@
+/* PR rtl-optimization/65321 */
+/* { dg-do compile } */
+/* { dg-options "-O3 -g" } */
+
+int a, b, c, d, e;
+
+int
+foo (void)
+{
+  int h;
+  char i;
+  for (; c > 0;)
+    {
+      for (d = 0; d < 2; d++)
+       {
+         i = 1 << d;
+         if (i - a)
+           {
+             e = b = 0;
+             for (; c; c--)
+               d = 127;
+           }
+       }
+      h = ~d;
+      if (h > c)
+       for (;;)
+         ;
+      return 0;
+    }
+  return 0;
+}
index 9ec5d8bcf81c384bf00642ae69308fc08b5fd145..da4c61e7d5684b4f62da7f4d633e85957570ade1 100644 (file)
@@ -1011,7 +1011,13 @@ use_narrower_mode (rtx x, machine_mode mode, machine_mode wmode)
       return simplify_gen_binary (GET_CODE (x), mode, op0, op1);
     case ASHIFT:
       op0 = use_narrower_mode (XEXP (x, 0), mode, wmode);
-      return simplify_gen_binary (ASHIFT, mode, op0, XEXP (x, 1));
+      op1 = XEXP (x, 1);
+      /* Ensure shift amount is not wider than mode.  */
+      if (GET_MODE (op1) == VOIDmode)
+       op1 = lowpart_subreg (mode, op1, wmode);
+      else if (GET_MODE_PRECISION (mode) < GET_MODE_PRECISION (GET_MODE (op1)))
+       op1 = lowpart_subreg (mode, op1, GET_MODE (op1));
+      return simplify_gen_binary (ASHIFT, mode, op0, op1);
     default:
       gcc_unreachable ();
     }