cselim: Handle clobbers too [PR122178]

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 <andrew.pinski@oss.qualcomm.com>
This commit is contained in:
Andrew Pinski 2025-10-13 16:35:07 -07:00
parent d4d64838ae
commit 05393afc13
2 changed files with 57 additions and 6 deletions

View File

@ -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" } } */

View File

@ -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");