--- /dev/null
+/* { 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" } } */
+
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;
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)
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");