re PR tree-optimization/77820 (A jump threading opportunity with conditionals)
authorJiufu Guo <guojiufu@linux.ibm.com>
Thu, 13 Jun 2019 18:55:55 +0000 (18:55 +0000)
committerJeff Law <law@gcc.gnu.org>
Thu, 13 Jun 2019 18:55:55 +0000 (12:55 -0600)
PR tree-optimization/77820
* tree-ssa-threadedge.c
(edge_forwards_cmp_to_conditional_jump_through_empty_bb_p): New
function.
(thread_across_edge): Add call to
edge_forwards_cmp_to_conditional_jump_through_empty_bb_p.

PR tree-optimization/77820
* gcc.dg/tree-ssa/phi_on_compare-1.c: New testcase.
* gcc.dg/tree-ssa/phi_on_compare-2.c: New testcase.
* gcc.dg/tree-ssa/phi_on_compare-3.c: New testcase.
* gcc.dg/tree-ssa/phi_on_compare-4.c: New testcase.
* gcc.dg/tree-ssa/split-path-6.c: Update testcase.
* gcc.target/sh/pr51244-20.c: Update testcase.

Co-Authored-By: Lijia He <helijia@linux.ibm.com>
From-SVN: r272261

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/phi_on_compare-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/phi_on_compare-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/phi_on_compare-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/phi_on_compare-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/split-path-6.c
gcc/testsuite/gcc.target/sh/pr51244-20.c
gcc/tree-ssa-threadedge.c

index 2b9171f4ff2c1f6df7cd9af871c8e63f080c5d61..990f0a04aaa6d7f015ae33c82209de153a0bd24e 100644 (file)
@@ -1,3 +1,13 @@
+2019-06-13  Jiufu Guo  <guojiufu@linux.ibm.com>
+           Lijia He  <helijia@linux.ibm.com>
+
+       PR tree-optimization/77820
+       * tree-ssa-threadedge.c
+       (edge_forwards_cmp_to_conditional_jump_through_empty_bb_p): New
+       function.
+       (thread_across_edge): Add call to
+       edge_forwards_cmp_to_conditional_jump_through_empty_bb_p.
+
 2019-06-13  Iain Sandoe  <iain@sandoe.co.uk>
 
        * config/darwin-driver.c (validate_macosx_version_min): New.
index 9f05d1f22dc99a8da548432ff51826524b54fb91..7032352934c87e751282b3345a323e933ff601d9 100644 (file)
@@ -1,3 +1,14 @@
+2019-06-13  Jiufu Guo  <guojiufu@linux.ibm.com>
+           Lijia He  <helijia@linux.ibm.com>
+
+       PR tree-optimization/77820
+       * gcc.dg/tree-ssa/phi_on_compare-1.c: New testcase.
+       * gcc.dg/tree-ssa/phi_on_compare-2.c: New testcase.
+       * gcc.dg/tree-ssa/phi_on_compare-3.c: New testcase.
+       * gcc.dg/tree-ssa/phi_on_compare-4.c: New testcase.
+       * gcc.dg/tree-ssa/split-path-6.c: Update testcase.
+       * gcc.target/sh/pr51244-20.c: Update testcase.
+
 2019-06-13  Iain Sandoe  <iain@sandoe.co.uk>
 
        * gcc.dg/darwin-minversion-link.c: New test.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi_on_compare-1.c b/gcc/testsuite/gcc.dg/tree-ssa/phi_on_compare-1.c
new file mode 100644 (file)
index 0000000..5227c87
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast -fdump-tree-vrp1" } */
+
+void g (int);
+void g1 (int);
+
+void
+f (long a, long b, long c, long d, long x)
+{
+  _Bool t;
+  if (x)
+    {
+      g (a + 1);
+      t = a < b;
+      c = d + x;
+    }
+  else
+    {
+      g (b + 1);
+      a = c + d;
+      t = c > d;
+    }
+
+  if (t)
+    g1 (c);
+
+  g (a);
+}
+
+/* { dg-final { scan-tree-dump-times "Removing basic block" 1 "vrp1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi_on_compare-2.c b/gcc/testsuite/gcc.dg/tree-ssa/phi_on_compare-2.c
new file mode 100644 (file)
index 0000000..eaf89bb
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast -fdump-tree-vrp1" } */
+
+void g (void);
+void g1 (void);
+
+void
+f (long a, long b, long c, long d, int x)
+{
+  _Bool t;
+  if (x)
+    t = c < d;
+  else
+    t = a < b;
+
+  if (t)
+    {
+      g1 ();
+      g ();
+    }
+}
+
+/* { dg-final { scan-tree-dump-times "Removing basic block" 1 "vrp1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi_on_compare-3.c b/gcc/testsuite/gcc.dg/tree-ssa/phi_on_compare-3.c
new file mode 100644 (file)
index 0000000..d5a1e0b
--- /dev/null
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast -fdump-tree-vrp1" } */
+
+void g (void);
+void g1 (void);
+
+void
+f (long a, long b, long c, long d, int x)
+{
+  int t;
+  if (x)
+    t = a < b;
+  else if (d == x)
+    t = c < b;
+  else
+    t = d > c;
+
+  if (t)
+    {
+      g1 ();
+      g ();
+    }
+}
+
+/* { dg-final { scan-tree-dump-times "Removing basic block" 1 "vrp1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi_on_compare-4.c b/gcc/testsuite/gcc.dg/tree-ssa/phi_on_compare-4.c
new file mode 100644 (file)
index 0000000..53acabc
--- /dev/null
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast -fdump-tree-vrp1" } */
+
+void g (int);
+void g1 (int);
+
+void
+f (long a, long b, long c, long d, int x)
+{
+  int t;
+  _Bool l1 = 0, l2 = 0;
+  if (x)
+    {
+      g (a);
+      c = a + b;
+      t = a < b;
+      l1 = 1;
+    }
+  else
+    {
+      g1 (b);
+      t = c > d;
+      d = c + b;
+      l2 = 1;
+    }
+
+  if (t)
+    {
+      if (l1 | l2)
+       g1 (c);
+    }
+  else
+    {
+      g (d);
+      g1 (a + b);
+    }
+  g (c + d);
+}
+
+/* { dg-final { scan-tree-dump-times "Removing basic block" 1 "vrp1" } } */
index 187c08407d5583699f6bd2c43d3c9211cab25b75..71d0fc0e83bf6abf0eda33bdbe2ce70ff4afee36 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fsplit-paths -fno-tree-cselim -fdump-tree-split-paths-details -w -fno-finite-loops" } */
+/* { dg-options "-O2 -fsplit-paths -fno-tree-cselim -fdump-tree-split-paths-details -fno-finite-loops -fno-tree-dominator-opts -fno-tree-vrp -w" } */
 
 struct __sFILE
 {
index c342163160b2cf10f26f59c54c3043ba478561c8..be265cd16afd012a5f746bb66fa355f05813be9c 100644 (file)
@@ -1,7 +1,7 @@
 /* Check that the SH specific sh_treg_combine RTL optimization pass works as
    expected.  */
 /* { dg-do compile }  */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -fno-tree-dominator-opts -fno-tree-vrp" } */
 
 /* { dg-final { scan-assembler-not "not\t" } } */
 /* { dg-final { scan-assembler-times "cmp/eq" 2 } } */
index c3ea2d680d8aefba74be383244bed15ff878d386..785227df690f3dddc1788b6fcdd53bd621410d15 100644 (file)
@@ -1157,6 +1157,68 @@ thread_through_normal_block (edge e,
   return 0;
 }
 
+/* There are basic blocks look like:
+   <P0>
+   p0 = a CMP b ; or p0 = (INT) (a CMP b)
+   goto <X>;
+
+   <P1>
+   p1 = c CMP d
+   goto <X>;
+
+   <X>
+   # phi = PHI <p0 (P0), p1 (P1)>
+   if (phi != 0) goto <Y>; else goto <Z>;
+
+   Then, edge (P0,X) or (P1,X) could be marked as EDGE_START_JUMP_THREAD
+   And edge (X,Y), (X,Z) is EDGE_COPY_SRC_JOINER_BLOCK
+
+   Return true if E is (P0,X) or (P1,X)  */
+
+bool
+edge_forwards_cmp_to_conditional_jump_through_empty_bb_p (edge e)
+{
+  /* See if there is only one stmt which is gcond.  */
+  gcond *gs;
+  if (!(gs = safe_dyn_cast<gcond *> (last_and_only_stmt (e->dest))))
+    return false;
+
+  /* See if gcond's cond is "(phi !=/== 0/1)" in the basic block.  */
+  tree cond = gimple_cond_lhs (gs);
+  enum tree_code code = gimple_cond_code (gs);
+  tree rhs = gimple_cond_rhs (gs);
+  if (TREE_CODE (cond) != SSA_NAME
+      || (code != NE_EXPR && code != EQ_EXPR)
+      || (!integer_onep (rhs) && !integer_zerop (rhs)))
+    return false;
+  gphi *phi = dyn_cast <gphi *> (SSA_NAME_DEF_STMT (cond));
+  if (phi == NULL || gimple_bb (phi) != e->dest)
+    return false;
+
+  /* Check if phi's incoming value is CMP.  */
+  gassign *def;
+  tree value = PHI_ARG_DEF_FROM_EDGE (phi, e);
+  if (TREE_CODE (value) != SSA_NAME
+      || !has_single_use (value)
+      || !(def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (value))))
+    return false;
+
+  /* Or if it is (INT) (a CMP b).  */
+  if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
+    {
+      value = gimple_assign_rhs1 (def);
+      if (TREE_CODE (value) != SSA_NAME
+         || !has_single_use (value)
+         || !(def = dyn_cast<gassign *> (SSA_NAME_DEF_STMT (value))))
+       return false;
+    }
+
+  if (TREE_CODE_CLASS (gimple_assign_rhs_code (def)) != tcc_comparison)
+    return false;
+
+  return true;
+}
+
 /* We are exiting E->src, see if E->dest ends with a conditional
    jump which has a known value when reached via E.
 
@@ -1317,10 +1379,12 @@ thread_across_edge (gcond *dummy_cond,
 
        /* If we were able to thread through a successor of E->dest, then
           record the jump threading opportunity.  */
-       if (found)
+       if (found
+           || edge_forwards_cmp_to_conditional_jump_through_empty_bb_p (e))
          {
-           propagate_threaded_block_debug_into (path->last ()->e->dest,
-                                                taken_edge->dest);
+           if (taken_edge->dest != path->last ()->e->dest)
+             propagate_threaded_block_debug_into (path->last ()->e->dest,
+                                                  taken_edge->dest);
            register_jump_thread (path);
          }
        else