re PR tree-optimization/81588 (Wrong code at -O2)
authorJakub Jelinek <jakub@redhat.com>
Tue, 1 Aug 2017 08:32:37 +0000 (10:32 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 1 Aug 2017 08:32:37 +0000 (10:32 +0200)
PR tree-optimization/81588
* tree-ssa-reassoc.c (optimize_range_tests_var_bound): If
ranges[i].in_p, invert comparison code ccode.  For >/>=,
swap rhs1 and rhs2 and comparison code unconditionally,
for </<= don't do that.  Don't swap rhs1/rhs2 again if
ranges[i].in_p, instead invert comparison code ccode if
opcode or oe->rank is BIT_IOR_EXPR.

* gcc.dg/tree-ssa/pr81588.c: New test.
* gcc.dg/pr81588.c: New test.
* gcc.c-torture/execute/pr81588.c: New test.

From-SVN: r250760

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr81588.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr81588.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/pr81588.c [new file with mode: 0644]
gcc/tree-ssa-reassoc.c

index c811099037d0ef8909c5530d17c4f804d548a945..ee6fcd5794e6f122532067c6ecf827aaba176cbe 100644 (file)
@@ -1,5 +1,13 @@
 2017-08-01  Jakub Jelinek  <jakub@redhat.com>
 
+       PR tree-optimization/81588
+       * tree-ssa-reassoc.c (optimize_range_tests_var_bound): If
+       ranges[i].in_p, invert comparison code ccode.  For >/>=,
+       swap rhs1 and rhs2 and comparison code unconditionally,
+       for </<= don't do that.  Don't swap rhs1/rhs2 again if
+       ranges[i].in_p, instead invert comparison code ccode if
+       opcode or oe->rank is BIT_IOR_EXPR.
+
        PR target/80846
        * optabs.def (vec_extract_optab, vec_init_optab): Change from
        a direct optab to conversion optab.
index 8ae9ef50c391e9353a147552f51374d49e427fcd..5d05b3b695bec63b062e58e906e616cce51a59f3 100644 (file)
@@ -1,3 +1,10 @@
+2017-08-01  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/81588
+       * gcc.dg/tree-ssa/pr81588.c: New test.
+       * gcc.dg/pr81588.c: New test.
+       * gcc.c-torture/execute/pr81588.c: New test.
+
 2017-08-01  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/81297
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr81588.c b/gcc/testsuite/gcc.c-torture/execute/pr81588.c
new file mode 100644 (file)
index 0000000..b8f84b3
--- /dev/null
@@ -0,0 +1,45 @@
+/* PR tree-optimization/81588 */
+
+__attribute__((noinline, noclone)) int
+bar (int x)
+{
+  __asm volatile ("" : : "g" (x) : "memory");
+}
+
+__attribute__((noinline, noclone)) int
+foo (unsigned x, long long y)
+{
+  if (y < 0)
+    return 0;
+  if (y < (long long) (4 * x))
+    {
+      bar (y);
+      return 1;
+    }
+  return 0;
+}     
+
+int
+main ()
+{
+  volatile unsigned x = 10;
+  volatile long long y = -10000;
+  if (foo (x, y) != 0)
+    __builtin_abort ();
+  y = -1;
+  if (foo (x, y) != 0)
+    __builtin_abort ();
+  y = 0;
+  if (foo (x, y) != 1)
+    __builtin_abort ();
+  y = 39;
+  if (foo (x, y) != 1)
+    __builtin_abort ();
+  y = 40;
+  if (foo (x, y) != 0)
+    __builtin_abort ();
+  y = 10000;
+  if (foo (x, y) != 0)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr81588.c b/gcc/testsuite/gcc.dg/pr81588.c
new file mode 100644 (file)
index 0000000..4e83607
--- /dev/null
@@ -0,0 +1,26 @@
+/* PR tree-optimization/81588 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+long long int a = 5011877430933453486LL, c = 1;
+unsigned short b = 24847;
+
+#include "tree-ssa/pr81588.c"
+
+int
+main ()
+{
+  foo ();
+  if (c != 0)
+    __builtin_abort ();
+  a = 24846;
+  c = 1;
+  foo ();
+  if (c != 1)
+    __builtin_abort ();
+  a = -5;
+  foo ();
+  if (c != 0)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr81588.c b/gcc/testsuite/gcc.dg/tree-ssa/pr81588.c
new file mode 100644 (file)
index 0000000..2709abd
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR tree-optimization/81588 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-reassoc1-details" } */
+       
+extern long long int a, c;
+extern unsigned short b;
+
+/* { dg-final { scan-tree-dump-times "Optimizing range test \[^\n\r]* and comparison" 1 "reassoc1" } } */
+
+__attribute__((noinline, noclone)) void
+foo (void)
+{
+  if ((b > a) != (1 + (a < 0)))
+    c = 0;
+}
index 7c3007f853a154100934f6e6ff26398358568dc3..b4fe488e79776894b2f634edebff8ec2f6ee640d 100644 (file)
@@ -2958,17 +2958,26 @@ optimize_range_tests_var_bound (enum tree_code opcode, int first, int length,
        {
        case GT_EXPR:
        case GE_EXPR:
-         if (!ranges[i].in_p)
-           std::swap (rhs1, rhs2);
+       case LT_EXPR:
+       case LE_EXPR:
+         break;
+       default:
+         continue;
+       }
+      if (ranges[i].in_p)
+       ccode = invert_tree_comparison (ccode, false);
+      switch (ccode)
+       {
+       case GT_EXPR:
+       case GE_EXPR:
+         std::swap (rhs1, rhs2);
          ccode = swap_tree_comparison (ccode);
          break;
        case LT_EXPR:
        case LE_EXPR:
-         if (ranges[i].in_p)
-           std::swap (rhs1, rhs2);
          break;
        default:
-         continue;
+         gcc_unreachable ();
        }
 
       int *idx = map->get (rhs1);
@@ -3015,8 +3024,14 @@ optimize_range_tests_var_bound (enum tree_code opcode, int first, int length,
          fprintf (dump_file, "\n");
        }
 
-      if (ranges[i].in_p)
-       std::swap (rhs1, rhs2);
+      operand_entry *oe = (*ops)[ranges[i].idx];
+      ranges[i].in_p = 0;
+      if (opcode == BIT_IOR_EXPR
+         || (opcode == ERROR_MARK && oe->rank == BIT_IOR_EXPR))
+       {
+         ranges[i].in_p = 1;
+         ccode = invert_tree_comparison (ccode, false);
+       }
 
       unsigned int uid = gimple_uid (stmt);
       gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
@@ -3043,7 +3058,6 @@ optimize_range_tests_var_bound (enum tree_code opcode, int first, int length,
        }
       else
        {
-         operand_entry *oe = (*ops)[ranges[i].idx];
          tree ctype = oe->op ? TREE_TYPE (oe->op) : boolean_type_node;
          if (!INTEGRAL_TYPE_P (ctype)
              || (TREE_CODE (ctype) != BOOLEAN_TYPE
@@ -3065,7 +3079,7 @@ optimize_range_tests_var_bound (enum tree_code opcode, int first, int length,
          ranges[i].high = ranges[i].low;
        }
       ranges[i].strict_overflow_p = false;
-      operand_entry *oe = (*ops)[ranges[*idx].idx];
+      oe = (*ops)[ranges[*idx].idx];
       /* Now change all the other range test immediate uses, so that
         those tests will be optimized away.  */
       if (opcode == ERROR_MARK)