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 <rguent...@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;