]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR tree-optimization/85529 (wrong code at -O2 and -O3 on x86_64-linux...
authorJakub Jelinek <jakub@redhat.com>
Fri, 22 Jun 2018 21:19:32 +0000 (23:19 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 22 Jun 2018 21:19:32 +0000 (23:19 +0200)
Backported from mainline
2018-04-27  Jakub Jelinek  <jakub@redhat.com>

PR tree-optimization/85529
* tree-ssa-reassoc.c (optimize_range_tests_var_bound): Add FIRST_BB
argument.  Don't call get_nonzero_bits if opcode is ERROR_MARK_NODE,
rhs2 def stmt's bb is dominated by first_bb and it isn't an obvious
zero extension or masking of the MSB bit.
(optimize_range_tests): Add FIRST_BB argument, pass it through
to optimize_range_tests_var_bound.
(maybe_optimize_range_tests, reassociate_bb): Adjust
optimize_range_tests callers.

* gcc.c-torture/execute/pr85529-1.c: New test.
* gcc.c-torture/execute/pr85529-2.c: New test.
* gcc.dg/pr85529.c: New test.

From-SVN: r261959

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

index 957bf2021f90450cca055eea1137a27aa123c8ab..1b8d9633c35934a033aa89bd356d4a55f7db805f 100644 (file)
@@ -1,6 +1,18 @@
 2018-06-22  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2018-04-27  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/85529
+       * tree-ssa-reassoc.c (optimize_range_tests_var_bound): Add FIRST_BB
+       argument.  Don't call get_nonzero_bits if opcode is ERROR_MARK_NODE,
+       rhs2 def stmt's bb is dominated by first_bb and it isn't an obvious
+       zero extension or masking of the MSB bit.
+       (optimize_range_tests): Add FIRST_BB argument, pass it through
+       to optimize_range_tests_var_bound.
+       (maybe_optimize_range_tests, reassociate_bb): Adjust
+       optimize_range_tests callers.
+
        2018-04-19  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/85446
index d9646b01cbc5b0bc1cbf40ed008066a070963c71..180ec1daaeb93dde5472e40e48e73c4b9b4edd33 100644 (file)
@@ -1,6 +1,13 @@
 2018-06-22  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2018-04-27  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/85529
+       * gcc.c-torture/execute/pr85529-1.c: New test.
+       * gcc.c-torture/execute/pr85529-2.c: New test.
+       * gcc.dg/pr85529.c: New test.
+
        2018-04-18  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/84463
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr85529-1.c b/gcc/testsuite/gcc.c-torture/execute/pr85529-1.c
new file mode 100644 (file)
index 0000000..83d5cdd
--- /dev/null
@@ -0,0 +1,28 @@
+/* PR tree-optimization/85529 */
+
+struct S { int a; };
+
+int b, c = 1, d, e, f;
+static int g;
+volatile struct S s;
+
+signed char
+foo (signed char i, int j)
+{
+  return i < 0 ? i : i << j;
+}
+
+int
+main ()
+{
+  signed char k = -83;
+  if (!d)
+    goto L;
+  k = e || f;
+L:
+  for (; b < 1; b++)
+    s.a != (k < foo (k, 2) && (c = k = g));
+  if (c != 1)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr85529-2.c b/gcc/testsuite/gcc.c-torture/execute/pr85529-2.c
new file mode 100644 (file)
index 0000000..727280d
--- /dev/null
@@ -0,0 +1,25 @@
+/* PR tree-optimization/85529 */
+
+__attribute__((noinline, noclone)) int
+foo (int x)
+{
+  x &= 63;
+  x -= 50;
+  x |= 1;
+  if (x < 0)
+    return 1;
+  int y = x >> 2;
+  if (x >= y)
+    return 1;
+  return 0;
+}
+
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 63; i++)
+    if (foo (i) != 1)
+      __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr85529.c b/gcc/testsuite/gcc.dg/pr85529.c
new file mode 100644 (file)
index 0000000..0b73228
--- /dev/null
@@ -0,0 +1,27 @@
+/* PR tree-optimization/85529 */
+/* { dg-do run } */
+/* { dg-options "-O2 -fno-ssa-phiopt" } */
+
+__attribute__((noinline, noclone)) int
+foo (int x)
+{
+  x &= 31;
+  x -= 25;
+  x *= 2;
+  if (x < 0)
+    return 1;
+  int y = x >> 2;
+  if (x >= y)
+    return 1;
+  return 0;
+}
+
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 63; i++)
+    if (foo (i) != 1)
+      __builtin_abort ();
+  return 0;
+}
index d3014e410b15ddbb4da463f42fa00a664db44fee..e6562c6c9ba1c4b295582bcd61059eced2947a5b 100644 (file)
@@ -2878,7 +2878,8 @@ optimize_range_tests_to_bit_test (enum tree_code opcode, int first, int length,
 static bool
 optimize_range_tests_var_bound (enum tree_code opcode, int first, int length,
                                vec<operand_entry *> *ops,
-                               struct range_entry *ranges)
+                               struct range_entry *ranges,
+                               basic_block first_bb)
 {
   int i;
   bool any_changes = false;
@@ -2975,6 +2976,60 @@ optimize_range_tests_var_bound (enum tree_code opcode, int first, int length,
       if (idx == NULL)
        continue;
 
+      /* maybe_optimize_range_tests allows statements without side-effects
+        in the basic blocks as long as they are consumed in the same bb.
+        Make sure rhs2's def stmt is not among them, otherwise we can't
+        use safely get_nonzero_bits on it.  E.g. in:
+         # RANGE [-83, 1] NONZERO 173
+         # k_32 = PHI <k_47(13), k_12(9)>
+        ...
+         if (k_32 >= 0)
+           goto <bb 5>; [26.46%]
+         else
+           goto <bb 9>; [73.54%]
+
+         <bb 5> [local count: 140323371]:
+         # RANGE [0, 1] NONZERO 1
+         _5 = (int) k_32;
+         # RANGE [0, 4] NONZERO 4
+         _21 = _5 << 2;
+         # RANGE [0, 4] NONZERO 4
+         iftmp.0_44 = (char) _21;
+         if (k_32 < iftmp.0_44)
+           goto <bb 6>; [84.48%]
+         else
+           goto <bb 9>; [15.52%]
+        the ranges on _5/_21/iftmp.0_44 are flow sensitive, assume that
+        k_32 >= 0.  If we'd optimize k_32 >= 0 to true and k_32 < iftmp.0_44
+        to (unsigned) k_32 < (unsigned) iftmp.0_44, then we would execute
+        those stmts even for negative k_32 and the value ranges would be no
+        longer guaranteed and so the optimization would be invalid.  */
+      if (opcode == ERROR_MARK)
+       {
+         gimple *g = SSA_NAME_DEF_STMT (rhs2);
+         basic_block bb2 = gimple_bb (g);
+         if (bb2
+             && bb2 != first_bb
+             && dominated_by_p (CDI_DOMINATORS, bb2, first_bb))
+           {
+             /* As an exception, handle a few common cases.  */
+             if (gimple_assign_cast_p (g)
+                 && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (g)))
+                 && TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (g)))
+                 && (TYPE_PRECISION (TREE_TYPE (rhs2))
+                     > TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (g)))))
+               /* Zero-extension is always ok.  */ ;
+             else if (is_gimple_assign (g)
+                      && gimple_assign_rhs_code (g) == BIT_AND_EXPR
+                      && TREE_CODE (gimple_assign_rhs2 (g)) == INTEGER_CST
+                      && !wi::neg_p (gimple_assign_rhs2 (g)))
+               /* Masking with INTEGER_CST with MSB clear is always ok
+                  too.  */ ;
+             else
+               continue;
+           }
+       }
+
       wide_int nz = get_nonzero_bits (rhs2);
       if (wi::neg_p (nz))
        continue;
@@ -3101,11 +3156,12 @@ optimize_range_tests_var_bound (enum tree_code opcode, int first, int length,
    maybe_optimize_range_tests for inter-bb range optimization.
    In that case if oe->op is NULL, oe->id is bb->index whose
    GIMPLE_COND is && or ||ed into the test, and oe->rank says
-   the actual opcode.  */
+   the actual opcode.
+   FIRST_BB is the first basic block if OPCODE is ERROR_MARK.  */
 
 static bool
 optimize_range_tests (enum tree_code opcode,
-                     vec<operand_entry *> *ops)
+                     vec<operand_entry *> *ops, basic_block first_bb)
 {
   unsigned int length = ops->length (), i, j, first;
   operand_entry *oe;
@@ -3183,7 +3239,7 @@ optimize_range_tests (enum tree_code opcode,
     any_changes |= optimize_range_tests_to_bit_test (opcode, first, length,
                                                     ops, ranges);
   any_changes |= optimize_range_tests_var_bound (opcode, first, length, ops,
-                                                ranges);
+                                                ranges, first_bb);
 
   if (any_changes && opcode != ERROR_MARK)
     {
@@ -3930,7 +3986,7 @@ maybe_optimize_range_tests (gimple *stmt)
        break;
     }
   if (ops.length () > 1)
-    any_changes = optimize_range_tests (ERROR_MARK, &ops);
+    any_changes = optimize_range_tests (ERROR_MARK, &ops, first_bb);
   if (any_changes)
     {
       unsigned int idx, max_idx = 0;
@@ -5682,7 +5738,7 @@ reassociate_bb (basic_block bb)
                  if (is_vector)
                    optimize_vec_cond_expr (rhs_code, &ops);
                  else
-                   optimize_range_tests (rhs_code, &ops);
+                   optimize_range_tests (rhs_code, &ops, NULL);
                }
 
              if (rhs_code == MULT_EXPR && !is_vector)