PR rtl-optimization/65321
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 10 Mar 2015 06:36:50 +0000 (06:36 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 10 Mar 2015 06:36:50 +0000 (06:36 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@221298 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 0cbeaa3..0ba2886 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 93d894f..67be09f 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 ec7a3bc..6c9ae2c 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 9ec5d8b..da4c61e 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 ();
     }