This changes inner ifs to have a result operand and to allow a simplify pattern to have multiple such ifs, thus:
(simplify (match-expression...) (if (cond1) result1) (if (cond2) result2) ... resultdefault) I'm not sure a default makes sense when a previous if failed (the first taken result always wins), but maybe it's useful to catch special-cases that simplify differently. What's not yet implemented is nesting those ifs to factor out common checks (useful for the sofar single pattern in match-comparison.pd). I'll get to that now. Bootstrap/regtest in progress on x86_64-unknown-linux-gnu. Richard. 2014-08-20 Richard Biener <rguent...@suse.de> * genmatch.c (parse_simplify): Change inner if parsing, allow multiple ifs. (parse_pattern): Adjust. * match.pd: Adjust inner ifs. * match-builtin.pd: Likewise. * match-comparison.pd: Likewise. * match-constant-folding.pd: Likewise. * match-plusminus.pd: Likewise. * match-rotate.pd: Likewise. Index: match-and-simplify/gcc/genmatch.c =================================================================== *** match-and-simplify.orig/gcc/genmatch.c 2014-08-20 14:32:10.826845091 +0200 --- match-and-simplify/gcc/genmatch.c 2014-08-20 14:32:19.236844512 +0200 *************** parse_op (cpp_reader *r) *** 2227,2234 **** (simplify "<ident>" <op> <op>) */ ! static simplify * ! parse_simplify (cpp_reader *r, source_location match_location) { const cpp_token *token = peek (r); const char *id; --- 2227,2235 ---- (simplify "<ident>" <op> <op>) */ ! static void ! parse_simplify (cpp_reader *r, source_location match_location, ! vec<simplify *>& simplifiers) { const cpp_token *token = peek (r); const char *id; *************** parse_simplify (cpp_reader *r, source_lo *** 2248,2278 **** token = peek (r); ! if (token->type != CPP_OPEN_PAREN) ! return new simplify (id, match, match_location, parse_op (r), token->src_loc); ! ! eat_token (r, CPP_OPEN_PAREN); ! ! token = peek (r); ! source_location result_loc = token->src_loc; ! ! // ( expr ) ! if (peek_ident (r, "if") == 0) { ! operand *result = parse_expr (r); eat_token (r, CPP_CLOSE_PAREN); ! return new simplify (id, match, match_location, result, result_loc); } ! // (if c-expr) ! eat_ident (r, "if"); ! operand *ifexpr = parse_c_expr (r, CPP_OPEN_PAREN); ! eat_token (r, CPP_CLOSE_PAREN); ! result_loc = peek (r)->src_loc; ! simplify *s = new simplify (id, match, match_location, parse_op (r), result_loc); ! s->ifexpr_vec.safe_push (ifexpr); ! return s; } void parse_pattern (cpp_reader *, vec<simplify *>&); --- 2249,2290 ---- token = peek (r); ! operand *result = NULL; ! source_location result_loc; ! while (!result ! && token->type == CPP_OPEN_PAREN) { ! eat_token (r, CPP_OPEN_PAREN); ! if (peek_ident (r, "if")) ! { ! vec<operand *> ifexprs = vNULL; ! eat_ident (r, "if"); ! ifexprs.safe_push (parse_c_expr (r, CPP_OPEN_PAREN)); ! /* ??? Support nested (if ...) here. */ ! token = peek (r); ! simplifiers.safe_push ! (new simplify (id, match, match_location, parse_op (r), ! token->src_loc, ifexprs)); ! } ! else ! { ! result_loc = token->src_loc; ! result = parse_expr (r); ! } eat_token (r, CPP_CLOSE_PAREN); ! token = peek (r); } ! if (!result ! && token->type != CPP_CLOSE_PAREN) ! { ! result_loc = token->src_loc; ! result = parse_op (r); ! } ! if (result) ! simplifiers.safe_push ! (new simplify (id, match, match_location, result, result_loc)); } void parse_pattern (cpp_reader *, vec<simplify *>&); *************** parse_pattern (cpp_reader *r, vec<simpli *** 2373,2379 **** const cpp_token *token = peek (r); const char *id = get_ident (r); if (strcmp (id, "simplify") == 0) ! simplifiers.safe_push (parse_simplify (r, token->src_loc)); else if (strcmp (id, "for") == 0) parse_for (r, token->src_loc, simplifiers); else if (strcmp (id, "if") == 0) --- 2385,2391 ---- const cpp_token *token = peek (r); const char *id = get_ident (r); if (strcmp (id, "simplify") == 0) ! parse_simplify (r, token->src_loc, simplifiers); else if (strcmp (id, "for") == 0) parse_for (r, token->src_loc, simplifiers); else if (strcmp (id, "if") == 0) Index: match-and-simplify/gcc/match-builtin.pd =================================================================== *** match-and-simplify.orig/gcc/match-builtin.pd 2014-08-20 14:32:10.826845091 +0200 --- match-and-simplify/gcc/match-builtin.pd 2014-08-20 14:32:19.236844512 +0200 *************** along with GCC; see the file COPYING3. *** 39,44 **** /* This needs to be conditionalized on flag_unsafe_math_optimizations, but we keep it for now to exercise function re-optimization. It makes gcc.dg/pr43419.c FAIL execution though. */ ! (if (REAL_VALUES_EQUAL (TREE_REAL_CST (@1), dconsthalf))) ! (BUILT_IN_SQRT @0)) --- 39,44 ---- /* This needs to be conditionalized on flag_unsafe_math_optimizations, but we keep it for now to exercise function re-optimization. It makes gcc.dg/pr43419.c FAIL execution though. */ ! (if (REAL_VALUES_EQUAL (TREE_REAL_CST (@1), dconsthalf)) ! (BUILT_IN_SQRT @0))) Index: match-and-simplify/gcc/match-comparison.pd =================================================================== *** match-and-simplify.orig/gcc/match-comparison.pd 2014-08-20 14:32:10.826845091 +0200 --- match-and-simplify/gcc/match-comparison.pd 2014-08-20 14:33:18.195840452 +0200 *************** *** 8,20 **** to use only two patterns by swapping the operands instead of changing the comparison code. */ (if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)) ! && tree_int_cst_sgn (@1) > 0)) ! (op @0 @2)) ! (simplify ! (op (mult @0 INTEGER_CST@1) integer_zerop@2) (if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)) ! && tree_int_cst_sgn (@1) < 0)) ! (op @2 @0))) #if 0 (for op in lt le eq ne ge gt --- 8,18 ---- to use only two patterns by swapping the operands instead of changing the comparison code. */ (if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)) ! && tree_int_cst_sgn (@1) > 0) ! (op @0 @2)) (if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)) ! && tree_int_cst_sgn (@1) < 0) ! (op @2 @0)))) #if 0 (for op in lt le eq ne ge gt Index: match-and-simplify/gcc/match-constant-folding.pd =================================================================== *** match-and-simplify.orig/gcc/match-constant-folding.pd 2014-08-20 14:32:10.826845091 +0200 --- match-and-simplify/gcc/match-constant-folding.pd 2014-08-20 14:32:19.236844512 +0200 *************** along with GCC; see the file COPYING3. *** 24,31 **** (simplify (minus @0 @0) ! (if (!HONOR_NANS (TYPE_MODE (type)))) ! { build_zero_cst (type); }) (simplify (mult @0 integer_zerop@1) --- 24,31 ---- (simplify (minus @0 @0) ! (if (!HONOR_NANS (TYPE_MODE (type))) ! { build_zero_cst (type); })) (simplify (mult @0 integer_zerop@1) *************** along with GCC; see the file COPYING3. *** 45,52 **** and simplifies 0 % x to 0. */ (simplify (trunc_mod integer_zerop@0 @1) ! (if (!integer_zerop (@1))) ! @0) (simplify (bit_ior @0 integer_all_onesp@1) --- 45,52 ---- and simplifies 0 % x to 0. */ (simplify (trunc_mod integer_zerop@0 @1) ! (if (!integer_zerop (@1)) ! @0)) (simplify (bit_ior @0 integer_all_onesp@1) Index: match-and-simplify/gcc/match-plusminus.pd =================================================================== *** match-and-simplify.orig/gcc/match-plusminus.pd 2014-08-20 14:32:10.826845091 +0200 --- match-and-simplify/gcc/match-plusminus.pd 2014-08-20 14:32:19.236844512 +0200 *************** along with GCC; see the file COPYING3. *** 23,34 **** /* Contract negates. */ (simplify (plus:c @0 (negate @1)) ! (if (!TYPE_SATURATING (type))) ! (minus @0 @1)) (simplify (minus @0 (negate @1)) ! (if (!TYPE_SATURATING (type))) ! (plus @0 @1)) /* Match patterns that allow contracting a plus-minus pair --- 23,34 ---- /* Contract negates. */ (simplify (plus:c @0 (negate @1)) ! (if (!TYPE_SATURATING (type)) ! (minus @0 @1))) (simplify (minus @0 (negate @1)) ! (if (!TYPE_SATURATING (type)) ! (plus @0 @1))) /* Match patterns that allow contracting a plus-minus pair *************** along with GCC; see the file COPYING3. *** 65,72 **** /* If the constant operation overflows we cannot do the transform as we would introduce undefined overflow, for example with (a - 1) + INT_MIN. */ ! (if (!TREE_OVERFLOW (@1 = int_const_binop (PLUS_EXPR, @1, @2)))) ! (plus @0 @1)) (simplify (plus (minus INTEGER_CST@0 @1) INTEGER_CST@2) (minus (plus @0 @2) @1)) --- 65,72 ---- /* If the constant operation overflows we cannot do the transform as we would introduce undefined overflow, for example with (a - 1) + INT_MIN. */ ! (if (!TREE_OVERFLOW (@1 = int_const_binop (PLUS_EXPR, @1, @2))) ! (plus @0 @1))) (simplify (plus (minus INTEGER_CST@0 @1) INTEGER_CST@2) (minus (plus @0 @2) @1)) Index: match-and-simplify/gcc/match-rotate.pd =================================================================== *** match-and-simplify.orig/gcc/match-rotate.pd 2014-08-20 14:32:10.826845091 +0200 --- match-and-simplify/gcc/match-rotate.pd 2014-08-20 14:32:19.237844511 +0200 *************** along with GCC; see the file COPYING3. *** 25,29 **** (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type) && TYPE_PRECISION (type) == GET_MODE_PRECISION (TYPE_MODE (type)) && tree_fits_uhwi_p (@1) && tree_fits_uhwi_p (@2) ! && wi::eq_p (TYPE_PRECISION (type), wi::add (@1, @2)))) ! (lrotate @0 @1))) --- 25,29 ---- (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type) && TYPE_PRECISION (type) == GET_MODE_PRECISION (TYPE_MODE (type)) && tree_fits_uhwi_p (@1) && tree_fits_uhwi_p (@2) ! && wi::eq_p (TYPE_PRECISION (type), wi::add (@1, @2))) ! (lrotate @0 @1)))) Index: match-and-simplify/gcc/match.pd =================================================================== *** match-and-simplify.orig/gcc/match.pd 2014-08-20 14:32:10.826845091 +0200 --- match-and-simplify/gcc/match.pd 2014-08-20 14:32:19.237844511 +0200 *************** along with GCC; see the file COPYING3. *** 41,47 **** #if GIMPLE (simplify (pointer_plus (addr@2 @0) INTEGER_CST@1) ! (if (is_gimple_min_invariant (@2))) { HOST_WIDE_INT off; tree base = get_addr_base_and_unit_offset (@0, &off); --- 41,47 ---- #if GIMPLE (simplify (pointer_plus (addr@2 @0) INTEGER_CST@1) ! (if (is_gimple_min_invariant (@2)) { HOST_WIDE_INT off; tree base = get_addr_base_and_unit_offset (@0, &off); *************** along with GCC; see the file COPYING3. *** 52,58 **** build2 (MEM_REF, TREE_TYPE (TREE_TYPE (@2)), build_fold_addr_expr (base), build_int_cst (ptr_type_node, off))); ! }) #endif --- 52,58 ---- build2 (MEM_REF, TREE_TYPE (TREE_TYPE (@2)), build_fold_addr_expr (base), build_int_cst (ptr_type_node, off))); ! })) #endif *************** along with GCC; see the file COPYING3. *** 66,73 **** if the new mask might be further optimized. */ (simplify (bit_and (rshift@0 @1 INTEGER_CST@2) integer_onep) ! (if (compare_tree_int (@2, TYPE_PRECISION (TREE_TYPE (@1)) - 1) == 0)) ! @0) /* COMPLEX_EXPR and REALPART/IMAGPART_EXPR cancellations. */ (simplify --- 66,73 ---- if the new mask might be further optimized. */ (simplify (bit_and (rshift@0 @1 INTEGER_CST@2) integer_onep) ! (if (compare_tree_int (@2, TYPE_PRECISION (TREE_TYPE (@1)) - 1) == 0) ! @0)) /* COMPLEX_EXPR and REALPART/IMAGPART_EXPR cancellations. */ (simplify