re PR tree-optimization/71016 (Redundant sign extension with conditional __builtin_clzl)

PR tree-optimization/71016
	* tree-ssa-phiopt.c (tree_ssa_phiopt_worker): Pass cond_stmt to
	factor_out_conditional_conversion.  Formatting fix.
	(factor_out_conditional_conversion): Add cond_stmt argument.
	If arg1 is INTEGER_CST, punt if new_arg0 is not any operand of
	cond_stmt and if arg0_def_stmt is not the only stmt in its bb.
	Formatting fix.

	* gcc.target/i386/pr71016.c: New test.
	* gcc.target/aarch64/pr71016.c: New test.
	* gcc.dg/tree-ssa/pr66726-3.c: New test.

From-SVN: r244114
This commit is contained in:
Jakub Jelinek 2017-01-05 22:14:19 +01:00 committed by Jakub Jelinek
parent 26f203712b
commit cfd719e776
6 changed files with 85 additions and 7 deletions

View File

@ -1,3 +1,13 @@
2017-01-05 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/71016
* tree-ssa-phiopt.c (tree_ssa_phiopt_worker): Pass cond_stmt to
factor_out_conditional_conversion. Formatting fix.
(factor_out_conditional_conversion): Add cond_stmt argument.
If arg1 is INTEGER_CST, punt if new_arg0 is not any operand of
cond_stmt and if arg0_def_stmt is not the only stmt in its bb.
Formatting fix.
2017-01-05 David Malcolm <dmalcolm@redhat.com>
* Makefile.in (OBJS): Add read-md.o, read-rtl.o,

View File

@ -1,5 +1,10 @@
2017-01-05 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/71016
* gcc.target/i386/pr71016.c: New test.
* gcc.target/aarch64/pr71016.c: New test.
* gcc.dg/tree-ssa/pr66726-3.c: New test.
PR c++/78931
* g++.dg/cpp1z/decomp19.C: New test.

View File

@ -0,0 +1,16 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
/* { dg-final { scan-tree-dump-times "MIN_EXPR" 1 "optimized" } } */
extern unsigned short mode_size[];
int
oof (int mode)
{
int tem;
if (64 < mode_size[mode])
tem = 64;
else
tem = mode_size[mode];
return tem;
}

View File

@ -0,0 +1,10 @@
/* PR tree-optimization/71016 */
/* { dg-do compile } */
/* { dg-options "-O2" } */
/* { dg-final { scan-assembler-not "sxtw" } } */
long int
foo (long int i)
{
return i == 0 ? 17 : __builtin_clzl (i);
}

View File

@ -0,0 +1,10 @@
/* PR tree-optimization/71016 */
/* { dg-do compile { target lp64 } } */
/* { dg-options "-O2 -mlzcnt" } */
/* { dg-final { scan-assembler-not "cltq" } } */
long int
foo (long int i)
{
return i == 0 ? 17 : __builtin_clzl (i);
}

View File

@ -49,7 +49,8 @@ along with GCC; see the file COPYING3. If not see
static unsigned int tree_ssa_phiopt_worker (bool, bool);
static bool conditional_replacement (basic_block, basic_block,
edge, edge, gphi *, tree, tree);
static gphi *factor_out_conditional_conversion (edge, edge, gphi *, tree, tree);
static gphi *factor_out_conditional_conversion (edge, edge, gphi *, tree, tree,
gimple *);
static int value_replacement (basic_block, basic_block,
edge, edge, gimple *, tree, tree);
static bool minmax_replacement (basic_block, basic_block,
@ -313,7 +314,8 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads)
gcc_assert (arg0 != NULL_TREE && arg1 != NULL_TREE);
gphi *newphi = factor_out_conditional_conversion (e1, e2, phi,
arg0, arg1);
arg0, arg1,
cond_stmt);
if (newphi != NULL)
{
phi = newphi;
@ -402,11 +404,12 @@ replace_phi_edge_with_variable (basic_block cond_block,
/* PR66726: Factor conversion out of COND_EXPR. If the arguments of the PHI
stmt are CONVERT_STMT, factor out the conversion and perform the conversion
to the result of PHI stmt. Return the newly-created PHI, if any. */
to the result of PHI stmt. COND_STMT is the controlling predicate.
Return the newly-created PHI, if any. */
static gphi *
factor_out_conditional_conversion (edge e0, edge e1, gphi *phi,
tree arg0, tree arg1)
tree arg0, tree arg1, gimple *cond_stmt)
{
gimple *arg0_def_stmt = NULL, *arg1_def_stmt = NULL, *new_stmt;
tree new_arg0 = NULL_TREE, new_arg1 = NULL_TREE;
@ -472,7 +475,31 @@ factor_out_conditional_conversion (edge e0, edge e1, gphi *phi,
&& int_fits_type_p (arg1, TREE_TYPE (new_arg0)))
{
if (gimple_assign_cast_p (arg0_def_stmt))
{
/* For the INTEGER_CST case, we are just moving the
conversion from one place to another, which can often
hurt as the conversion moves further away from the
statement that computes the value. So, perform this
only if new_arg0 is an operand of COND_STMT, or
if arg0_def_stmt is the only non-debug stmt in
its basic block, because then it is possible this
could enable further optimizations (minmax replacement
etc.). See PR71016. */
if (new_arg0 != gimple_cond_lhs (cond_stmt)
&& new_arg0 != gimple_cond_rhs (cond_stmt)
&& gimple_bb (arg0_def_stmt) == e0->src)
{
gsi = gsi_for_stmt (arg0_def_stmt);
gsi_prev_nondebug (&gsi);
if (!gsi_end_p (gsi))
return NULL;
gsi = gsi_for_stmt (arg0_def_stmt);
gsi_next_nondebug (&gsi);
if (!gsi_end_p (gsi))
return NULL;
}
new_arg1 = fold_convert (TREE_TYPE (new_arg0), arg1);
}
else
return NULL;
}