aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2017-01-05 22:14:19 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2017-01-05 22:14:19 +0100
commitcfd719e7769fd43fbfecfc0c8f69d5f05e54169b (patch)
treeb56fb744d9f892b66b366fb97ea74b0afeb48d32 /gcc
parent26f203712b9a90913473a1a75ce6f96783a6ec65 (diff)
downloadgcc-cfd719e7769fd43fbfecfc0c8f69d5f05e54169b.zip
gcc-cfd719e7769fd43fbfecfc0c8f69d5f05e54169b.tar.gz
gcc-cfd719e7769fd43fbfecfc0c8f69d5f05e54169b.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr66726-3.c16
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr71016.c10
-rw-r--r--gcc/testsuite/gcc.target/i386/pr71016.c10
-rw-r--r--gcc/tree-ssa-phiopt.c41
6 files changed, 85 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1114d8a..8e51cee 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index cd205bd..e99e399 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr66726-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr66726-3.c
new file mode 100644
index 0000000..55c7a14
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr66726-3.c
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/pr71016.c b/gcc/testsuite/gcc.target/aarch64/pr71016.c
new file mode 100644
index 0000000..f50d693
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr71016.c
@@ -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);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr71016.c b/gcc/testsuite/gcc.target/i386/pr71016.c
new file mode 100644
index 0000000..d5a89eb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr71016.c
@@ -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);
+}
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
index 259f6fe..07a226e 100644
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -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,
@@ -233,7 +234,7 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads)
continue;
}
else if (do_hoist_loads
- && EDGE_SUCC (bb1, 0)->dest == EDGE_SUCC (bb2, 0)->dest)
+ && EDGE_SUCC (bb1, 0)->dest == EDGE_SUCC (bb2, 0)->dest)
{
basic_block bb3 = EDGE_SUCC (bb1, 0)->dest;
@@ -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))
- new_arg1 = fold_convert (TREE_TYPE (new_arg0), arg1);
+ {
+ /* 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;
}
@@ -524,7 +551,7 @@ factor_out_conditional_conversion (edge e0, edge e1, gphi *phi,
/* Create the conversion stmt and insert it. */
if (convert_code == VIEW_CONVERT_EXPR)
temp = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (result), temp);
- new_stmt = gimple_build_assign (result, convert_code, temp);
+ new_stmt = gimple_build_assign (result, convert_code, temp);
gsi = gsi_after_labels (gimple_bb (phi));
gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);