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]

[PATCH] Remove bogus canonicalization from canonicalize_cond_expr_cond


This patch removes treating (bool)x the same as x != 0 in
canonicalize_cond_expr_cond.  That isn't true as the cast to
bool can be a truncation.  With lowering bit-field refs
this exposes a miscompile of g++.dg/opt/nrv5.C.

When removing that canonicalization fold turns out to be
unhelpful exposing more of those cases, so this patch removes
that particular folding (which existed since forever).  It also
adjusts indirect inlining pattern matching to also allow an
inverted test which is what fold now produces.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2011-06-15  Richard Guenther  <rguenther@suse.de>

	* gimple.c (canonicalize_cond_expr_cond): (bool)x is not
	the same as x != 0.
	* fold-const.c (fold_binary_loc): Do not fold X & 1 != 0 to
	(bool) X & 1.
	* ipa-prop.c (ipa_analyze_indirect_call_uses): Also allow
	equality compares against zero for the lower bit.

Index: gcc/gimple.c
===================================================================
*** gcc/gimple.c	(revision 175079)
--- gcc/gimple.c	(working copy)
*************** canonicalize_cond_expr_cond (tree t)
*** 3139,3154 ****
        && truth_value_p (TREE_CODE (TREE_OPERAND (t, 0))))
      t = TREE_OPERAND (t, 0);
  
-   /* For (bool)x use x != 0.  */
-   if (CONVERT_EXPR_P (t)
-       && TREE_CODE (TREE_TYPE (t)) == BOOLEAN_TYPE)
-     {
-       tree top0 = TREE_OPERAND (t, 0);
-       t = build2 (NE_EXPR, TREE_TYPE (t),
- 		  top0, build_int_cst (TREE_TYPE (top0), 0));
-     }
    /* For !x use x == 0.  */
!   else if (TREE_CODE (t) == TRUTH_NOT_EXPR)
      {
        tree top0 = TREE_OPERAND (t, 0);
        t = build2 (EQ_EXPR, TREE_TYPE (t),
--- 3139,3146 ----
        && truth_value_p (TREE_CODE (TREE_OPERAND (t, 0))))
      t = TREE_OPERAND (t, 0);
  
    /* For !x use x == 0.  */
!   if (TREE_CODE (t) == TRUTH_NOT_EXPR)
      {
        tree top0 = TREE_OPERAND (t, 0);
        t = build2 (EQ_EXPR, TREE_TYPE (t),
Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c	(revision 175079)
--- gcc/fold-const.c	(working copy)
*************** fold_binary_loc (location_t loc,
*** 12357,12370 ****
  	    }
  	}
  
-       /* If this is an NE comparison of zero with an AND of one, remove the
- 	 comparison since the AND will give the correct value.  */
-       if (code == NE_EXPR
- 	  && integer_zerop (arg1)
- 	  && TREE_CODE (arg0) == BIT_AND_EXPR
- 	  && integer_onep (TREE_OPERAND (arg0, 1)))
- 	return fold_convert_loc (loc, type, arg0);
- 
        /* If we have (A & C) == C where C is a power of 2, convert this into
  	 (A & C) != 0.  Similarly for NE_EXPR.  */
        if (TREE_CODE (arg0) == BIT_AND_EXPR
--- 12357,12362 ----
Index: gcc/ipa-prop.c
===================================================================
*** gcc/ipa-prop.c	(revision 175079)
--- gcc/ipa-prop.c	(working copy)
*************** ipa_analyze_indirect_call_uses (struct c
*** 1347,1353 ****
    if (!branch || gimple_code (branch) != GIMPLE_COND)
      return;
  
!   if (gimple_cond_code (branch) != NE_EXPR
        || !integer_zerop (gimple_cond_rhs (branch)))
      return;
  
--- 1347,1354 ----
    if (!branch || gimple_code (branch) != GIMPLE_COND)
      return;
  
!   if ((gimple_cond_code (branch) != NE_EXPR
!        && gimple_cond_code (branch) != EQ_EXPR)
        || !integer_zerop (gimple_cond_rhs (branch)))
      return;
  


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