This fixes most of the testsuite fallout of earlier patches. Committed.
Richard. 2014-06-05 Richard Biener <rguent...@suse.de> * gimple-match-head.c (gimple_resimplify2): Verify constant folded result is really constant. (gimple_match_and_simplify): Likewise. Bail out for internal functions. * match.pd: Match what fold-const.c does for folding of division and modulo with regarding to possibly zero 2nd operand. Add comment to bogus pow (x, 0.5) to sqrt (x) simplification. Index: gcc/gimple-match-head.c =================================================================== --- gcc/gimple-match-head.c (revision 211234) +++ gcc/gimple-match-head.c (working copy) @@ -173,7 +173,8 @@ gimple_resimplify2 (gimple_seq *seq, } } } - if (tem != NULL_TREE) + if (tem != NULL_TREE + && CONSTANT_CLASS_P (tem)) { res_ops[0] = tem; res_ops[1] = NULL_TREE; @@ -334,7 +335,8 @@ gimple_match_and_simplify (enum tree_cod if (constant_for_folding (op0)) { tree res = fold_unary_to_constant (code, type, op0); - if (res != NULL_TREE) + if (res != NULL_TREE + && CONSTANT_CLASS_P (res)) return res; } @@ -354,9 +356,8 @@ gimple_match_and_simplify (enum tree_cod if (constant_for_folding (op0) && constant_for_folding (op1)) { tree res = fold_binary_to_constant (code, type, op0, op1); - /* ??? We can't assert that we fold this to a constant as - for example we can't fold things like 1 / 0. */ - if (res != NULL_TREE) + if (res != NULL_TREE + && CONSTANT_CLASS_P (res)) return res; } @@ -566,6 +567,9 @@ gimple_match_and_simplify (gimple stmt, && gimple_call_lhs (stmt) != NULL_TREE) { tree fn = gimple_call_fn (stmt); + /* ??? Internal function support missing. */ + if (!fn) + return false; if (TREE_CODE (fn) == SSA_NAME && valueize) fn = valueize (fn); Index: gcc/match.pd =================================================================== --- gcc/match.pd (revision 211221) +++ gcc/match.pd (working copy) @@ -40,29 +40,21 @@ along with GCC; see the file COPYING3. (match_and_simplify (mult @0 integer_onep) @0) +/* Make sure to preserve divisions by zero. This is the reason why + we don't simplify x / x to 1 or 0 / x to 0. */ (match_and_simplify (trunc_div @0 integer_onep) @0) -/* It's hard to preserve non-folding of / 0 which is done by a - positional check in fold-const.c (to preserve warnings). The - issue here is that we fold too early in frontends. - Also fold happilt folds 0 / x to 0 (even if x turns out to be zero later). */ -(match_and_simplify - (trunc_div integer_zerop@0 @1) - @0) -(match_and_simplify - (trunc_div @0 @0) - { build_one_cst (type); }) (match_and_simplify (trunc_mod @0 integer_onep) { build_zero_cst (type); }) +/* Same applies to modulo operations, but fold is inconsistent here + and simplifies 0 % x to 0. */ (match_and_simplify (trunc_mod integer_zerop@0 @1) + if (!integer_zerop (@1)) @0) (match_and_simplify - (trunc_mod @0 @0) - { build_zero_cst (type); }) -(match_and_simplify (bit_ior @0 integer_zerop) @0) (match_and_simplify @@ -280,6 +272,8 @@ to (minus @1 @0) (BUILT_IN_POW @0 (PLUS_EXPR @1 { build_one_cst (TREE_TYPE (@1)); }))) (match_and_simplify (BUILT_IN_POW @0 REAL_CST_P@1) + /* This needs to be conditionalized on flag_unsafe_math_optimizations, + but we keep it for now to exercise function re-optimization. */ if (REAL_VALUES_EQUAL (TREE_REAL_CST (@1), dconsthalf)) (BUILT_IN_SQRT @0))