mirror of git://gcc.gnu.org/git/gcc.git
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:
parent
26f203712b
commit
cfd719e776
|
|
@ -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>
|
2017-01-05 David Malcolm <dmalcolm@redhat.com>
|
||||||
|
|
||||||
* Makefile.in (OBJS): Add read-md.o, read-rtl.o,
|
* Makefile.in (OBJS): Add read-md.o, read-rtl.o,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
2017-01-05 Jakub Jelinek <jakub@redhat.com>
|
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
|
PR c++/78931
|
||||||
* g++.dg/cpp1z/decomp19.C: New test.
|
* g++.dg/cpp1z/decomp19.C: New test.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -49,7 +49,8 @@ along with GCC; see the file COPYING3. If not see
|
||||||
static unsigned int tree_ssa_phiopt_worker (bool, bool);
|
static unsigned int tree_ssa_phiopt_worker (bool, bool);
|
||||||
static bool conditional_replacement (basic_block, basic_block,
|
static bool conditional_replacement (basic_block, basic_block,
|
||||||
edge, edge, gphi *, tree, tree);
|
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,
|
static int value_replacement (basic_block, basic_block,
|
||||||
edge, edge, gimple *, tree, tree);
|
edge, edge, gimple *, tree, tree);
|
||||||
static bool minmax_replacement (basic_block, basic_block,
|
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);
|
gcc_assert (arg0 != NULL_TREE && arg1 != NULL_TREE);
|
||||||
|
|
||||||
gphi *newphi = factor_out_conditional_conversion (e1, e2, phi,
|
gphi *newphi = factor_out_conditional_conversion (e1, e2, phi,
|
||||||
arg0, arg1);
|
arg0, arg1,
|
||||||
|
cond_stmt);
|
||||||
if (newphi != NULL)
|
if (newphi != NULL)
|
||||||
{
|
{
|
||||||
phi = newphi;
|
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
|
/* 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
|
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 *
|
static gphi *
|
||||||
factor_out_conditional_conversion (edge e0, edge e1, gphi *phi,
|
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;
|
gimple *arg0_def_stmt = NULL, *arg1_def_stmt = NULL, *new_stmt;
|
||||||
tree new_arg0 = NULL_TREE, new_arg1 = NULL_TREE;
|
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)))
|
&& int_fits_type_p (arg1, TREE_TYPE (new_arg0)))
|
||||||
{
|
{
|
||||||
if (gimple_assign_cast_p (arg0_def_stmt))
|
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);
|
new_arg1 = fold_convert (TREE_TYPE (new_arg0), arg1);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue