This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] fix opt/13869
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 3 Feb 2004 22:16:08 -0800
- Subject: [tree-ssa] fix opt/13869
The problem here is that we bogon'ed the handling of booleans.
We equated the boolean to zero no matter the direction of the
branch. Oops.
Of interest is that C and C++ somehow result in different code
for this, such that C reduces the function to "return 0", and
C++ doesn't. Opened PR 14011 to track that.
r~
PR opt/13869
* tree-cfg.c (cfg_remove_useless_stmts_bb): Correct handling of
boolean variables in COND_EXPR_COND.
* g++.dg/opt/bool1.C: New.
Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.4.263
diff -c -p -d -r1.1.4.263 tree-cfg.c
*** tree-cfg.c 2 Feb 2004 14:55:15 -0000 1.1.4.263
--- tree-cfg.c 4 Feb 2004 06:05:46 -0000
*************** cfg_remove_useless_stmts_bb (basic_block
*** 1371,1397 ****
return;
cond = COND_EXPR_COND (last_stmt (bb->pred->src));
- if (bb->pred->flags & EDGE_FALSE_VALUE)
- cond = invert_truthvalue (cond);
! if (TREE_CODE (cond) == VAR_DECL
! || TREE_CODE (cond) == PARM_DECL)
{
var = cond;
! val = convert (TREE_TYPE (cond), integer_zero_node);
}
! else if ((TREE_CODE (cond) == EQ_EXPR)
&& (TREE_CODE (TREE_OPERAND (cond, 0)) == VAR_DECL
! || TREE_CODE (TREE_OPERAND (cond, 0)) == PARM_DECL)
! && (TREE_CODE (TREE_OPERAND (cond, 1)) == VAR_DECL
! || TREE_CODE (TREE_OPERAND (cond, 1)) == PARM_DECL
! || TREE_CONSTANT (TREE_OPERAND (cond, 1))))
{
var = TREE_OPERAND (cond, 0);
! val = TREE_OPERAND (cond, 1);
}
else
! return;
/* Only work for normal local variables. */
ann = var_ann (var);
--- 1371,1408 ----
return;
cond = COND_EXPR_COND (last_stmt (bb->pred->src));
! if (TREE_CODE (cond) == VAR_DECL || TREE_CODE (cond) == PARM_DECL)
{
var = cond;
! val = (bb->pred->flags & EDGE_FALSE_VALUE
! ? boolean_false_node : boolean_true_node);
}
! else if (TREE_CODE (cond) == TRUTH_NOT_EXPR
&& (TREE_CODE (TREE_OPERAND (cond, 0)) == VAR_DECL
! || TREE_CODE (TREE_OPERAND (cond, 0)) == PARM_DECL))
{
var = TREE_OPERAND (cond, 0);
! val = (bb->pred->flags & EDGE_FALSE_VALUE
! ? boolean_true_node : boolean_false_node);
}
else
! {
! if (bb->pred->flags & EDGE_FALSE_VALUE)
! cond = invert_truthvalue (cond);
! if (TREE_CODE (cond) == EQ_EXPR
! && (TREE_CODE (TREE_OPERAND (cond, 0)) == VAR_DECL
! || TREE_CODE (TREE_OPERAND (cond, 0)) == PARM_DECL)
! && (TREE_CODE (TREE_OPERAND (cond, 1)) == VAR_DECL
! || TREE_CODE (TREE_OPERAND (cond, 1)) == PARM_DECL
! || TREE_CONSTANT (TREE_OPERAND (cond, 1))))
! {
! var = TREE_OPERAND (cond, 0);
! val = TREE_OPERAND (cond, 1);
! }
! else
! return;
! }
/* Only work for normal local variables. */
ann = var_ann (var);
Index: testsuite/g++.dg/opt/bool1.C
===================================================================
RCS file: testsuite/g++.dg/opt/bool1.C
diff -N testsuite/g++.dg/opt/bool1.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/opt/bool1.C 4 Feb 2004 06:05:46 -0000
***************
*** 0 ****
--- 1,23 ----
+ // PR opt/13869
+ // { dg-do run }
+ // { dg-options "-O2" }
+
+ int test ()
+ {
+ bool my_bool = true;
+ for (int i = 0; i < 10; ++i)
+ {
+ if (!my_bool)
+ ;
+ else
+ my_bool = false;
+ };
+ return my_bool;
+ }
+
+ int main ()
+ {
+ if (test ())
+ abort ();
+ return 0;
+ }