This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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;
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]