PR rtl-optimization/69764
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 12 Feb 2016 16:49:44 +0000 (16:49 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 12 Feb 2016 16:49:44 +0000 (16:49 +0000)
PR rtl-optimization/69771
* optabs.c (expand_binop_directly): For shift_optab_p, force
convert_modes with VOIDmode if xop1 has VOIDmode.

* c-c++-common/pr69764.c: New test.
* gcc.dg/torture/pr69771.c: New test.

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

gcc/ChangeLog
gcc/optabs.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/pr69764.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr69771.c [new file with mode: 0644]

index 65b32b8..871a2f0 100644 (file)
@@ -1,3 +1,10 @@
+2016-02-12  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/69764
+       PR rtl-optimization/69771
+       * optabs.c (expand_binop_directly): For shift_optab_p, force
+       convert_modes with VOIDmode if xop1 has VOIDmode.
+
 2016-02-12  Ilya Enkovich  <enkovich.gnu@gmail.com>
 
        PR target/69729
index e1ba615..b651878 100644 (file)
@@ -993,6 +993,7 @@ expand_binop_directly (machine_mode mode, optab binoptab,
   bool commutative_p;
   rtx_insn *pat;
   rtx xop0 = op0, xop1 = op1;
+  bool canonicalize_op1 = false;
 
   /* If it is a commutative operator and the modes would match
      if we would swap the operands, we can save the conversions.  */
@@ -1006,6 +1007,11 @@ expand_binop_directly (machine_mode mode, optab binoptab,
   xop0 = avoid_expensive_constant (xmode0, binoptab, 0, xop0, unsignedp);
   if (!shift_optab_p (binoptab))
     xop1 = avoid_expensive_constant (xmode1, binoptab, 1, xop1, unsignedp);
+  else
+    /* Shifts and rotates often use a different mode for op1 from op0;
+       for VOIDmode constants we don't know the mode, so force it
+       to be canonicalized using convert_modes.  */
+    canonicalize_op1 = true;
 
   /* In case the insn wants input operands in modes different from
      those of the actual operands, convert the operands.  It would
@@ -1020,7 +1026,8 @@ expand_binop_directly (machine_mode mode, optab binoptab,
       mode0 = xmode0;
     }
 
-  mode1 = GET_MODE (xop1) != VOIDmode ? GET_MODE (xop1) : mode;
+  mode1 = ((GET_MODE (xop1) != VOIDmode || canonicalize_op1)
+          ? GET_MODE (xop1) : mode);
   if (xmode1 != VOIDmode && xmode1 != mode1)
     {
       xop1 = convert_modes (xmode1, mode1, xop1, unsignedp);
index ffb14ef..dfae7fc 100644 (file)
@@ -1,3 +1,10 @@
+2016-02-12  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/69764
+       PR rtl-optimization/69771
+       * c-c++-common/pr69764.c: New test.
+       * gcc.dg/torture/pr69771.c: New test.
+
 2016-02-12  Marek Polacek  <polacek@redhat.com>
 
        * g++.dg/torture/init-list1.C: New.
diff --git a/gcc/testsuite/c-c++-common/pr69764.c b/gcc/testsuite/c-c++-common/pr69764.c
new file mode 100644 (file)
index 0000000..79623ec
--- /dev/null
@@ -0,0 +1,38 @@
+/* PR rtl-optimization/69764 */
+/* { dg-do compile { target int32plus } } */
+
+unsigned char
+fn1 (unsigned char a)
+{
+  return a >> ~6;      /* { dg-warning "right shift count is negative" } */
+}
+
+unsigned short
+fn2 (unsigned short a)
+{
+  return a >> ~6;      /* { dg-warning "right shift count is negative" } */
+}
+
+unsigned int
+fn3 (unsigned int a)
+{
+  return a >> ~6;      /* { dg-warning "right shift count is negative" } */
+}
+
+unsigned char
+fn4 (unsigned char a)
+{
+  return a >> 0xff03;  /* { dg-warning "right shift count >= width of type" } */
+}
+
+unsigned short
+fn5 (unsigned short a)
+{
+  return a >> 0xff03;  /* { dg-warning "right shift count >= width of type" } */
+}
+
+unsigned int
+fn6 (unsigned int a)
+{
+  return a >> 0xff03;  /* { dg-warning "right shift count >= width of type" } */
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr69771.c b/gcc/testsuite/gcc.dg/torture/pr69771.c
new file mode 100644 (file)
index 0000000..8314c82
--- /dev/null
@@ -0,0 +1,12 @@
+/* PR rtl-optimization/69771 */
+/* { dg-do compile } */
+
+unsigned char a = 5, c;
+unsigned short b = 0;
+unsigned d = 0x76543210;
+
+void
+foo (void)
+{
+  c = d >> ~(a || ~b); /* { dg-warning "shift count is negative" } */
+}