]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/69320 (wrong code generation at -O2 and higher)
authorJeff Law <law@redhat.com>
Tue, 19 Jan 2016 06:43:54 +0000 (23:43 -0700)
committerJeff Law <law@gcc.gnu.org>
Tue, 19 Jan 2016 06:43:54 +0000 (23:43 -0700)
2016-01-18  Jeff Law  <law@redhat.com>

PR tree-optimization/69320
* tree-ssa-dom.c (record_edge_info): For comparisons against a boolean
ranged object, do nothing if the RHS constant is not [0..1].
(optimize_stmt): Comparing a boolean ranged object against a
constant outside [0..1] results in a compile-time constant.

* tree-ssanames.c (ssa_name_has_boolean_range): Remove unnecessary
test.

PR tree-optimization/69320
* gcc.c-torture/pr69320-1.c: New test.
* gcc.c-torture/pr69320-2.c: New test.
* gcc.c-torture/pr69320-3.c: New test.
* gcc.c-torture/pr69320-4.c: New test.

From-SVN: r232548

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr69320-1.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/pr69320-2.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/pr69320-3.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/pr69320-4.c [new file with mode: 0644]
gcc/tree-ssa-dom.c
gcc/tree-ssanames.c

index de6e1ede674686a960035eba9575a1e4f972528a..b39f864c3238a2964f759577a03b6e25856a9d5e 100644 (file)
@@ -1,3 +1,14 @@
+2016-01-18  Jeff Law  <law@redhat.com>
+
+       PR tree-optimization/69320
+       * tree-ssa-dom.c (record_edge_info): For comparisons against a boolean
+       ranged object, do nothing if the RHS constant is not [0..1].
+       (optimize_stmt): Comparing a boolean ranged object against a
+       constant outside [0..1] results in a compile-time constant.
+
+       * tree-ssanames.c (ssa_name_has_boolean_range): Remove unnecessary
+       test.
+
 2016-01-18  Sandra Loosemore <sandra@codesourcery.com>
 
        * doc/invoke.texi (Invoking GCC): Add new section to menu.
index 9245b50b567e1b567230817773c38537fc5522fb..fc476b96b8062f283585bb5af00e50133481f44c 100644 (file)
@@ -1,3 +1,11 @@
+2016-01-15  Jeff Law  <law@redhat.com>
+
+       PR tree-optimization/69320
+       * gcc.c-torture/pr69320-1.c: New test.
+       * gcc.c-torture/pr69320-2.c: New test.
+       * gcc.c-torture/pr69320-3.c: New test.
+       * gcc.c-torture/pr69320-4.c: New test.
+
 2016-01-18  Patrick Palka  <ppalka@gcc.gnu.org>
 
        PR c++/11858
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr69320-1.c b/gcc/testsuite/gcc.c-torture/execute/pr69320-1.c
new file mode 100644 (file)
index 0000000..0aba2fc
--- /dev/null
@@ -0,0 +1,20 @@
+#include <stdlib.h>
+int a, b, d, f;
+char c;
+static int *e = &d;
+int main() {
+  int g = -1L;
+  *e = g;
+  c = 4;
+  for (; c >= 14; c++)
+    *e = 1;
+  f = a == 0;
+  *e ^= f;
+  int h = ~d;
+  if (d)
+    b = h;
+  if (h)
+    exit (0);
+  abort ();
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr69320-2.c b/gcc/testsuite/gcc.c-torture/execute/pr69320-2.c
new file mode 100644 (file)
index 0000000..b85672c
--- /dev/null
@@ -0,0 +1,35 @@
+
+#include <stdlib.h>
+
+int a, *c, d, e, g, f;
+short b;
+
+int 
+fn1 ()
+{
+  int h = d != 10;
+  if (h > g)
+     asm volatile ("" : : : "memory");
+  if (h == 10)
+    {
+      int *i = 0;
+      a = 0;
+      for (; a < 7; a++)
+       for (; *i;)
+         ;
+    }
+  else
+    {
+      b = e / h;
+      return f;
+    }
+  c = &h;
+  abort ();
+}
+
+int
+main ()
+{
+  fn1 ();
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr69320-3.c b/gcc/testsuite/gcc.c-torture/execute/pr69320-3.c
new file mode 100644 (file)
index 0000000..213c93f
--- /dev/null
@@ -0,0 +1,17 @@
+#include <stdlib.h>
+
+static int a[40] = {7, 5, 3, 3, 0, 0, 3};
+short b;
+int c = 5;
+int main() {
+  b = 0;
+  for (; b <= 3; b++)
+    if (a[b + 6] ^ (0 || c))
+      ;
+    else
+      break;
+  if (b != 4)
+    abort ();
+  exit (0);
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr69320-4.c b/gcc/testsuite/gcc.c-torture/execute/pr69320-4.c
new file mode 100644 (file)
index 0000000..356cd0f
--- /dev/null
@@ -0,0 +1,18 @@
+#include <stdlib.h>
+
+int a;
+char b, d;
+short c;
+short fn1(int p1, int p2) { return p2 >= 2 ? p1 : p1 > p2; }
+
+int main() {
+  int *e = &a, *f = &a;
+  b = 1;
+  for (; b <= 9; b++) {
+    c = *e != 5 || d;
+    *f = fn1(c || b, a);
+  }
+  if ((long long) a != 1)
+    abort ();
+  exit (0);
+}
index 829863794a31ee1d462dcfa4c196bc49dc5dc866..3eeaa9cdcf9d7ccce09be13c18befaffd269853f 100644 (file)
@@ -387,11 +387,16 @@ record_edge_info (basic_block bb)
 
           /* Special case comparing booleans against a constant as we
              know the value of OP0 on both arms of the branch.  i.e., we
-             can record an equivalence for OP0 rather than COND.  */
-          if ((code == EQ_EXPR || code == NE_EXPR)
-              && TREE_CODE (op0) == SSA_NAME
+             can record an equivalence for OP0 rather than COND. 
+
+            However, don't do this if the constant isn't zero or one.
+            Such conditionals will get optimized more thoroughly during
+            the domwalk.  */
+         if ((code == EQ_EXPR || code == NE_EXPR)
+             && TREE_CODE (op0) == SSA_NAME
              && ssa_name_has_boolean_range (op0)
-              && is_gimple_min_invariant (op1))
+             && is_gimple_min_invariant (op1)
+             && (integer_zerop (op1) || integer_onep (op1)))
             {
              tree true_val = constant_boolean_node (true, TREE_TYPE (op0));
              tree false_val = constant_boolean_node (false, TREE_TYPE (op0));
@@ -1828,6 +1833,31 @@ optimize_stmt (basic_block bb, gimple_stmt_iterator si,
            }
        }
 
+      if (gimple_code (stmt) == GIMPLE_COND)
+       {
+         tree lhs = gimple_cond_lhs (stmt);
+         tree rhs = gimple_cond_rhs (stmt);
+
+         /* If the LHS has a range [0..1] and the RHS has a range ~[0..1],
+            then this conditional is computable at compile time.  We can just
+            shove either 0 or 1 into the LHS, mark the statement as modified
+            and all the right things will just happen below.
+
+            Note this would apply to any case where LHS has a range
+            narrower than its type implies and RHS is outside that
+            narrower range.  Future work.  */
+         if (TREE_CODE (lhs) == SSA_NAME
+             && ssa_name_has_boolean_range (lhs)
+             && TREE_CODE (rhs) == INTEGER_CST
+             && ! (integer_zerop (rhs) || integer_onep (rhs)))
+           {
+             gimple_cond_set_lhs (as_a <gcond *> (stmt),
+                                  fold_convert (TREE_TYPE (lhs),
+                                                integer_zero_node));
+             gimple_set_modified (stmt, true);
+           }
+       }
+
       update_stmt_if_modified (stmt);
       eliminate_redundant_computations (&si, const_and_copies,
                                        avail_exprs_stack);
index b6f72e2ba2c2fb34288947086b43fcf01c23ead1..ed87f3ee7d429b53323ffcd1a4492638944a84e1 100644 (file)
@@ -437,8 +437,7 @@ ssa_name_has_boolean_range (tree op)
      only takes on values [0..1] as determined by VRP
      analysis.  */
   if (INTEGRAL_TYPE_P (TREE_TYPE (op))
-      && (TYPE_PRECISION (TREE_TYPE (op)) > 1
-         || TYPE_UNSIGNED (TREE_TYPE (op)))
+      && (TYPE_PRECISION (TREE_TYPE (op)) > 1)
       && wi::eq_p (get_nonzero_bits (op), 1))
     return true;