With the addition of cselim-limited in phiopt, factoring
out clobbers can be added easily. Now sink handles clobbers as
a store too. So this just moves that earlier.

This adds support there with a testcase to show it happens.

Bootstrapped and tested on x86_64-linux-gnu.

        PR tree-optimization/122178

gcc/ChangeLog:

        * tree-ssa-phiopt.cc (cond_if_else_store_replacement_1): Handle
        clobber statements.

gcc/testsuite/ChangeLog:

        * g++.dg/tree-ssa/cselim-1.C: New test.

Signed-off-by: Andrew Pinski <[email protected]>
---
 gcc/testsuite/g++.dg/tree-ssa/cselim-1.C | 37 ++++++++++++++++++++++++
 gcc/tree-ssa-phiopt.cc                   | 26 +++++++++++++----
 2 files changed, 57 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/tree-ssa/cselim-1.C

diff --git a/gcc/testsuite/g++.dg/tree-ssa/cselim-1.C 
b/gcc/testsuite/g++.dg/tree-ssa/cselim-1.C
new file mode 100644
index 00000000000..a621945f4e7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/cselim-1.C
@@ -0,0 +1,37 @@
+/* { dg-do compile { target c++11 } } */
+/* { dg-options "-O2 -fdump-tree-phiopt1-details -fdump-tree-optimized" } */
+/* PR tree-optimization/122178 */
+/* cselim/cselim-limited should be able to handle clobbers. */
+
+#include <new>
+
+struct s1
+{
+  bool t;
+};
+
+void f(s1 *a, bool b)
+{
+  if (b)
+  {
+    a = new(a)s1{1};
+  }
+  else
+  {
+    a = new(a)s1{0};
+  }
+}
+
+/*
+  The above should be optimized in phiopt1 to:
+  *a = {CLOBBER(bob)};
+  a->t = b;
+ */
+
+
+/* { dg-final { scan-tree-dump-times "factoring out stores" 1 "phiopt1" } } */
+/* { dg-final { scan-tree-dump-times "factoring out clobber" 1 "phiopt1" } } */
+/* { dg-final { scan-tree-dump-times " converted to straightline code" 1 
"phiopt1" } } */
+/* { dg-final { scan-tree-dump-not "if "  "phiopt1" } } */
+/* { dg-final { scan-tree-dump-not "if "  "optimized" } } */
+
diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
index 3d6673cfb90..9f7f662d7cf 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -3648,16 +3648,20 @@ cond_if_else_store_replacement_1 (basic_block then_bb, 
basic_block else_bb,
 
   if (then_assign == NULL
       || !gimple_assign_single_p (then_assign)
-      || gimple_clobber_p (then_assign)
-      || gimple_has_volatile_ops (then_assign)
       || else_assign == NULL
       || !gimple_assign_single_p (else_assign)
-      || gimple_clobber_p (else_assign)
-      || gimple_has_volatile_ops (else_assign)
       || stmt_references_abnormal_ssa_name (then_assign)
       || stmt_references_abnormal_ssa_name (else_assign))
     return false;
 
+  /* Allow both being clobbers but no other volatile operations. */
+  if (gimple_clobber_p (then_assign)
+      && gimple_clobber_p (else_assign))
+    ;
+  else if (gimple_has_volatile_ops (then_assign)
+          || gimple_has_volatile_ops (else_assign))
+   return false;
+
   lhs = gimple_assign_lhs (then_assign);
   if (!operand_equal_p (lhs, gimple_assign_lhs (else_assign), 0))
     return false;
@@ -3674,7 +3678,14 @@ cond_if_else_store_replacement_1 (basic_block then_bb, 
basic_block else_bb,
 
   if (!is_gimple_reg_type (TREE_TYPE (lhs)))
     {
-      if (!operand_equal_p (then_rhs, else_rhs))
+      /* Handle clobbers seperately as operand_equal_p does not check
+        the kind of the clobbers being the same. */
+      if (TREE_CLOBBER_P (then_rhs) && TREE_CLOBBER_P (else_rhs))
+       {
+         if (CLOBBER_KIND (then_rhs) != CLOBBER_KIND  (else_rhs))
+           return false;
+       }
+      else if (!operand_equal_p (then_rhs, else_rhs))
        return false;
       /* Currently only handle commoning of `= {}`.   */
       if (TREE_CODE (then_rhs) != CONSTRUCTOR)
@@ -3683,7 +3694,10 @@ cond_if_else_store_replacement_1 (basic_block then_bb, 
basic_block else_bb,
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
-      fprintf(dump_file, "factoring out stores:\n\tthen:\n");
+      if (TREE_CLOBBER_P (then_rhs))
+       fprintf(dump_file, "factoring out clobber:\n\tthen:\n");
+      else
+       fprintf(dump_file, "factoring out stores:\n\tthen:\n");
       print_gimple_stmt (dump_file, then_assign, 0,
                         TDF_VOPS|TDF_MEMSYMS);
       fprintf(dump_file, "\telse:\n");
-- 
2.43.0

Reply via email to