This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Fix tree-optimization/20139.
- From: Kazu Hirata <kazu at cs dot umass dot edu>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 22 Feb 2005 20:52:31 -0500 (EST)
- Subject: [patch] Fix tree-optimization/20139.
Hi,
Attached is a patch to fix tree-optimization/20139.
Consider the attached testcase.
TER changes
p_2 = ABS_EXPR <x_1>;
if (p_2 < 0.0) goto <L0>; else goto <L1>;
into
if (ABS_EXPR <x> < 0.0) goto <L0>; else goto <L1>;
which would get folded by fold in find_taken_edge, which I recently
removed, causing a missed optimization at tree level.
The patch essentially restores fold for the last run of
cleanup_tree_cfg by running fold_cond_expr_cond immediately before
cleanup_tree_cfg.
IMHO, the right thing to do is to propagate the range of ABS_EXPR's
result, and fold the "if" statement accordingly. I hope this patch
will be reverted in 4.1 once we start doing a good VRP.
Some people are for removing gcc.c-torture/execute/20020720-1.c as the
testcase in this patch will be stronger in that it checks that "if" is
gone at tree level. Others don't see a reason for removing the old
testcase. Personally, I can go with either option.
Tested on i686-pc-linux-gnu. OK to apply?
Kazu Hirata
2005-02-22 Kazu Hirata <kazu@cs.umass.edu>
PR tree-optimization/20139
* tree-cfg.c (fold_cond_expr_cond): Export.
* tree-flow.h: Add a prototype for fold_cond_expr_cond.
* tree-optimize.c (execute_cleanup_cfg_post_optimizing): Call
fold_cond_expr_cond.
2005-02-22 Kazu Hirata <kazu@cs.umass.edu>
PR tree-optimization/20139
* gcc.dg/tree-ssa/pr20139.c: New.
Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-cfg.c,v
retrieving revision 2.151
diff -u -d -p -r2.151 tree-cfg.c
--- tree-cfg.c 21 Feb 2005 18:38:05 -0000 2.151
+++ tree-cfg.c 22 Feb 2005 16:57:21 -0000
@@ -442,7 +442,7 @@ create_bb (void *h, void *e, basic_block
/* Fold COND_EXPR_COND of each COND_EXPR. */
-static void
+void
fold_cond_expr_cond (void)
{
basic_block bb;
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-flow.h,v
retrieving revision 2.81
diff -u -d -p -r2.81 tree-flow.h
--- tree-flow.h 10 Feb 2005 00:32:44 -0000 2.81
+++ tree-flow.h 22 Feb 2005 16:57:21 -0000
@@ -477,6 +477,7 @@ extern void debug_loop_ir (void);
extern void print_loop_ir (FILE *);
extern void cleanup_dead_labels (void);
extern void group_case_labels (void);
+extern void fold_cond_expr_cond (void);
extern bool cleanup_tree_cfg (void);
extern tree first_stmt (basic_block);
extern tree last_stmt (basic_block);
Index: tree-optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-optimize.c,v
retrieving revision 2.73
diff -u -d -p -r2.73 tree-optimize.c
--- tree-optimize.c 17 Feb 2005 16:19:41 -0000 2.73
+++ tree-optimize.c 22 Feb 2005 16:57:21 -0000
@@ -111,6 +111,11 @@ static struct tree_opt_pass pass_all_opt
static void
execute_cleanup_cfg_post_optimizing (void)
{
+ /* TODO: For 4.1, remove this call to fold_cond_expr_cond and fix
+ any missed optimization that may arise. With good range
+ propagation and bit tracking, we should be able to eliminate this
+ call. */
+ fold_cond_expr_cond ();
cleanup_tree_cfg ();
cleanup_dead_labels ();
group_case_labels ();
--- /dev/null 2005-02-20 05:55:40.284481520 -0500
+++ testsuite/gcc.dg/tree-ssa/pr20139.c 2005-02-22 20:49:35.643197360 -0500
@@ -0,0 +1,39 @@
+/* Copyright (C) 2002, 2005 Free Software Foundation.
+
+ Ensure that fabs(x) < 0.0 optimization is working.
+
+ Written by Roger Sayle, 20th July 2002.
+ Adapted to the tree optimizers by Kazu Hirata.
+
+ This testcase is essentially the same as
+ gcc.c-torture/execute/20020720-1.c. The only difference is that
+ this testcase ensures that the "if" statement is optimized away at
+ tree level, whereas 20020720-1.c tests that the "if" statement is
+ optimized away at some point during the compilation. */
+
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-final_cleanup" } */
+
+extern void abort (void);
+extern double fabs (double);
+extern void link_error (void);
+
+void
+foo (double x)
+{
+ double p, q;
+
+ p = fabs (x);
+ q = 0.0;
+ if (p < q)
+ link_error ();
+}
+
+int
+main()
+{
+ foo (1.0);
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "if" 0 "final_cleanup"} } */