This fixes the folding bits for PR18908 where we fail to canonicalize X ^ ~0 as ~X. Fixed by making integer_all_onesp use TYPE_PRECISION and by making forwprop also perform this canonicalization.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Richard. 2011-07-20 Richard Guenther <rguent...@suse.de> PR middle-end/18908 * tree.c (integer_all_onesp): Use TYPE_PRECISION, not mode precision. * tree-ssa-forwprop.c (simplify_bitwise_binary): Remove bogus ADDR_EXPR folding. Canonicalize X ^ ~0 as ~X. * gcc.dg/tree-ssa/pr18908.c: New testcase. Index: gcc/tree.c =================================================================== *** gcc/tree.c (revision 176497) --- gcc/tree.c (working copy) *************** integer_all_onesp (const_tree expr) *** 1759,1767 **** if (!uns) return 0; ! /* Note that using TYPE_PRECISION here is wrong. We care about the ! actual bits, not the (arbitrary) range of the type. */ ! prec = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (expr))); if (prec >= HOST_BITS_PER_WIDE_INT) { HOST_WIDE_INT high_value; --- 1759,1765 ---- if (!uns) return 0; ! prec = TYPE_PRECISION (TREE_TYPE (expr)); if (prec >= HOST_BITS_PER_WIDE_INT) { HOST_WIDE_INT high_value; Index: gcc/tree-ssa-forwprop.c =================================================================== *** gcc/tree-ssa-forwprop.c (revision 176497) --- gcc/tree-ssa-forwprop.c (working copy) *************** simplify_bitwise_binary (gimple_stmt_ite *** 1710,1746 **** tree def1_arg1, def2_arg1; enum tree_code def1_code, def2_code; - /* If the first argument is an SSA name that is itself a result of a - typecast of an ADDR_EXPR to an integer, feed the ADDR_EXPR to the - folder rather than the ssa name. */ - if (code == BIT_AND_EXPR - && TREE_CODE (arg2) == INTEGER_CST - && TREE_CODE (arg1) == SSA_NAME) - { - gimple def = SSA_NAME_DEF_STMT (arg1); - tree op = arg1; - - /* ??? This looks bogus - the conversion could be truncating. */ - if (is_gimple_assign (def) - && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)) - && INTEGRAL_TYPE_P (TREE_TYPE (arg1))) - { - tree opp = gimple_assign_rhs1 (def); - if (TREE_CODE (opp) == ADDR_EXPR) - op = opp; - } - - res = fold_binary_loc (gimple_location (stmt), - BIT_AND_EXPR, TREE_TYPE (gimple_assign_lhs (stmt)), - op, arg2); - if (res && is_gimple_min_invariant (res)) - { - gimple_assign_set_rhs_from_tree (gsi, res); - update_stmt (stmt); - return true; - } - } - def1_code = TREE_CODE (arg1); def1_arg1 = arg1; if (TREE_CODE (arg1) == SSA_NAME) --- 1710,1715 ---- *************** simplify_bitwise_binary (gimple_stmt_ite *** 1861,1866 **** --- 1830,1846 ---- update_stmt (stmt); return true; } + + /* Canonicalize X ^ ~0 to ~X. */ + if (code == BIT_XOR_EXPR + && TREE_CODE (arg2) == INTEGER_CST + && integer_all_onesp (arg2)) + { + gimple_assign_set_rhs_with_ops (gsi, BIT_NOT_EXPR, arg1, NULL_TREE); + gcc_assert (gsi_stmt (*gsi) == stmt); + update_stmt (stmt); + return true; + } /* Try simple folding for X op !X, and X op X. */ res = simplify_bitwise_binary_1 (code, TREE_TYPE (arg1), arg1, arg2); Index: gcc/testsuite/gcc.dg/tree-ssa/pr18908.c =================================================================== *** gcc/testsuite/gcc.dg/tree-ssa/pr18908.c (revision 0) --- gcc/testsuite/gcc.dg/tree-ssa/pr18908.c (revision 0) *************** *** 0 **** --- 1,9 ---- + /* { dg-do compile } */ + /* { dg-options "-O -fdump-tree-forwprop1" } */ + + _Bool f3(_Bool *p) { *p ^= 1; } + + /* We should be able to canonicalize the above to use bitwise not. */ + /* { dg-final { scan-tree-dump "~D" "forwprop1" } } */ + /* { dg-final { scan-tree-dump-not "\\\^ 1" "forwprop1" } } */ + /* { dg-final { cleanup-tree-dump "forwprop1" } } */