From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1666) id 408A43858C56; Thu, 13 Oct 2022 11:49:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 408A43858C56 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1665661744; bh=CLhZI0OhqjnCK4rfPDm+AD2tVt634Ppaq5rIM5eCDSg=; h=From:To:Subject:Date:From; b=AfBmc6o0mklMAXPKc2QVL6CYgQTtolUQyrcGIzvRt2D7f4rGuPuyr0hxtEyh1E7cj kyh02rNt2GxVlt1EPdB+f9NhurlxndmucLRmrzwCWC6TAN/cZPDOCfVlM1I3qNQAxY JatXE49Oy3URoPv+AJR5vXKWFwKu4LUH3KJyFx2Y= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Richard Biener To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-3271] diagnose return statement in match.pd (with { ... } expressions X-Act-Checkin: gcc X-Git-Author: Richard Biener X-Git-Refname: refs/heads/master X-Git-Oldrev: 9f0d4adabe2035886a1aa8d2ca990a90de000613 X-Git-Newrev: 786e4c024f941671a233f5779d73a5d22f4e9588 Message-Id: <20221013114904.408A43858C56@sourceware.org> Date: Thu, 13 Oct 2022 11:49:04 +0000 (GMT) List-Id: https://gcc.gnu.org/g:786e4c024f941671a233f5779d73a5d22f4e9588 commit r13-3271-g786e4c024f941671a233f5779d73a5d22f4e9588 Author: Richard Biener Date: Thu Oct 13 12:59:09 2022 +0200 diagnose return statement in match.pd (with { ... } expressions The expression in (with { ... } is used like a statement expression which means control flow that leaves it is not allowed. The following explicitely diagnoses 'return' and fixes up the few cases that crept into match.pd (oops). Any such return will prematurely end matching the current expression. * genmatch.cc (parser::parse_c_expr): Diagnose 'return'. * match.pd: Replace 'return' statements in with expressions with appropriate variants. Diff: --- gcc/genmatch.cc | 7 +- gcc/match.pd | 293 ++++++++++++++++++++++++++++---------------------------- 2 files changed, 150 insertions(+), 150 deletions(-) diff --git a/gcc/genmatch.cc b/gcc/genmatch.cc index a0b22c50ae3..4a8802469cd 100644 --- a/gcc/genmatch.cc +++ b/gcc/genmatch.cc @@ -4447,8 +4447,11 @@ parser::parse_c_expr (cpp_ttype start) /* If this is possibly a user-defined identifier mark it used. */ if (token->type == CPP_NAME) { - id_base *idb = get_operator ((const char *)CPP_HASHNODE - (token->val.node.node)->ident.str); + const char *str + = (const char *)CPP_HASHNODE (token->val.node.node)->ident.str; + if (strcmp (str, "return") == 0) + fatal_at (token, "return statement not allowed in C expression"); + id_base *idb = get_operator (str); user_id *p; if (idb && (p = dyn_cast (idb)) && p->is_oper_list) record_operlist (token->src_loc, p); diff --git a/gcc/match.pd b/gcc/match.pd index 3550c16aaa6..fd64ad740b6 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -7930,131 +7930,131 @@ and, /* Build a vector of integers from the tree mask. */ vec_perm_builder builder; - if (!tree_to_vec_perm_builder (&builder, op2)) - return NULL_TREE; - - /* Create a vec_perm_indices for the integer vector. */ - poly_uint64 nelts = TYPE_VECTOR_SUBPARTS (type); - bool single_arg = (op0 == op1); - vec_perm_indices sel (builder, single_arg ? 1 : 2, nelts); } - (if (sel.series_p (0, 1, 0, 1)) - { op0; } - (if (sel.series_p (0, 1, nelts, 1)) - { op1; } - (with - { - if (!single_arg) - { - if (sel.all_from_input_p (0)) - op1 = op0; - else if (sel.all_from_input_p (1)) + (if (tree_to_vec_perm_builder (&builder, op2)) + (with + { + /* Create a vec_perm_indices for the integer vector. */ + poly_uint64 nelts = TYPE_VECTOR_SUBPARTS (type); + bool single_arg = (op0 == op1); + vec_perm_indices sel (builder, single_arg ? 1 : 2, nelts); + } + (if (sel.series_p (0, 1, 0, 1)) + { op0; } + (if (sel.series_p (0, 1, nelts, 1)) + { op1; } + (with + { + if (!single_arg) + { + if (sel.all_from_input_p (0)) + op1 = op0; + else if (sel.all_from_input_p (1)) + { + op0 = op1; + sel.rotate_inputs (1); + } + else if (known_ge (poly_uint64 (sel[0]), nelts)) + { + std::swap (op0, op1); + sel.rotate_inputs (1); + } + } + gassign *def; + tree cop0 = op0, cop1 = op1; + if (TREE_CODE (op0) == SSA_NAME + && (def = dyn_cast (SSA_NAME_DEF_STMT (op0))) + && gimple_assign_rhs_code (def) == CONSTRUCTOR) + cop0 = gimple_assign_rhs1 (def); + if (TREE_CODE (op1) == SSA_NAME + && (def = dyn_cast (SSA_NAME_DEF_STMT (op1))) + && gimple_assign_rhs_code (def) == CONSTRUCTOR) + cop1 = gimple_assign_rhs1 (def); + tree t; + } + (if ((TREE_CODE (cop0) == VECTOR_CST + || TREE_CODE (cop0) == CONSTRUCTOR) + && (TREE_CODE (cop1) == VECTOR_CST + || TREE_CODE (cop1) == CONSTRUCTOR) + && (t = fold_vec_perm (type, cop0, cop1, sel))) + { t; } + (with + { + bool changed = (op0 == op1 && !single_arg); + tree ins = NULL_TREE; + unsigned at = 0; + + /* See if the permutation is performing a single element + insert from a CONSTRUCTOR or constant and use a BIT_INSERT_EXPR + in that case. But only if the vector mode is supported, + otherwise this is invalid GIMPLE. */ + if (op_mode != BLKmode + && (TREE_CODE (cop0) == VECTOR_CST + || TREE_CODE (cop0) == CONSTRUCTOR + || TREE_CODE (cop1) == VECTOR_CST + || TREE_CODE (cop1) == CONSTRUCTOR)) { - op0 = op1; - sel.rotate_inputs (1); + bool insert_first_p = sel.series_p (1, 1, nelts + 1, 1); + if (insert_first_p) + { + /* After canonicalizing the first elt to come from the + first vector we only can insert the first elt from + the first vector. */ + at = 0; + if ((ins = fold_read_from_vector (cop0, sel[0]))) + op0 = op1; + } + /* The above can fail for two-element vectors which always + appear to insert the first element, so try inserting + into the second lane as well. For more than two + elements that's wasted time. */ + if (!insert_first_p || (!ins && maybe_eq (nelts, 2u))) + { + unsigned int encoded_nelts = sel.encoding ().encoded_nelts (); + for (at = 0; at < encoded_nelts; ++at) + if (maybe_ne (sel[at], at)) + break; + if (at < encoded_nelts + && (known_eq (at + 1, nelts) + || sel.series_p (at + 1, 1, at + 1, 1))) + { + if (known_lt (poly_uint64 (sel[at]), nelts)) + ins = fold_read_from_vector (cop0, sel[at]); + else + ins = fold_read_from_vector (cop1, sel[at] - nelts); + } + } } - else if (known_ge (poly_uint64 (sel[0]), nelts)) + + /* Generate a canonical form of the selector. */ + if (!ins && sel.encoding () != builder) { - std::swap (op0, op1); - sel.rotate_inputs (1); + /* Some targets are deficient and fail to expand a single + argument permutation while still allowing an equivalent + 2-argument version. */ + tree oldop2 = op2; + if (sel.ninputs () == 2 + || can_vec_perm_const_p (result_mode, op_mode, sel, false)) + op2 = vec_perm_indices_to_tree (TREE_TYPE (op2), sel); + else + { + vec_perm_indices sel2 (builder, 2, nelts); + if (can_vec_perm_const_p (result_mode, op_mode, sel2, false)) + op2 = vec_perm_indices_to_tree (TREE_TYPE (op2), sel2); + else + /* Not directly supported with either encoding, + so use the preferred form. */ + op2 = vec_perm_indices_to_tree (TREE_TYPE (op2), sel); + } + if (!operand_equal_p (op2, oldop2, 0)) + changed = true; } - } - gassign *def; - tree cop0 = op0, cop1 = op1; - if (TREE_CODE (op0) == SSA_NAME - && (def = dyn_cast (SSA_NAME_DEF_STMT (op0))) - && gimple_assign_rhs_code (def) == CONSTRUCTOR) - cop0 = gimple_assign_rhs1 (def); - if (TREE_CODE (op1) == SSA_NAME - && (def = dyn_cast (SSA_NAME_DEF_STMT (op1))) - && gimple_assign_rhs_code (def) == CONSTRUCTOR) - cop1 = gimple_assign_rhs1 (def); - - tree t; - } - (if ((TREE_CODE (cop0) == VECTOR_CST - || TREE_CODE (cop0) == CONSTRUCTOR) - && (TREE_CODE (cop1) == VECTOR_CST - || TREE_CODE (cop1) == CONSTRUCTOR) - && (t = fold_vec_perm (type, cop0, cop1, sel))) - { t; } - (with - { - bool changed = (op0 == op1 && !single_arg); - tree ins = NULL_TREE; - unsigned at = 0; - - /* See if the permutation is performing a single element - insert from a CONSTRUCTOR or constant and use a BIT_INSERT_EXPR - in that case. But only if the vector mode is supported, - otherwise this is invalid GIMPLE. */ - if (op_mode != BLKmode - && (TREE_CODE (cop0) == VECTOR_CST - || TREE_CODE (cop0) == CONSTRUCTOR - || TREE_CODE (cop1) == VECTOR_CST - || TREE_CODE (cop1) == CONSTRUCTOR)) - { - bool insert_first_p = sel.series_p (1, 1, nelts + 1, 1); - if (insert_first_p) - { - /* After canonicalizing the first elt to come from the - first vector we only can insert the first elt from - the first vector. */ - at = 0; - if ((ins = fold_read_from_vector (cop0, sel[0]))) - op0 = op1; - } - /* The above can fail for two-element vectors which always - appear to insert the first element, so try inserting - into the second lane as well. For more than two - elements that's wasted time. */ - if (!insert_first_p || (!ins && maybe_eq (nelts, 2u))) - { - unsigned int encoded_nelts = sel.encoding ().encoded_nelts (); - for (at = 0; at < encoded_nelts; ++at) - if (maybe_ne (sel[at], at)) - break; - if (at < encoded_nelts - && (known_eq (at + 1, nelts) - || sel.series_p (at + 1, 1, at + 1, 1))) - { - if (known_lt (poly_uint64 (sel[at]), nelts)) - ins = fold_read_from_vector (cop0, sel[at]); - else - ins = fold_read_from_vector (cop1, sel[at] - nelts); - } - } - } - - /* Generate a canonical form of the selector. */ - if (!ins && sel.encoding () != builder) - { - /* Some targets are deficient and fail to expand a single - argument permutation while still allowing an equivalent - 2-argument version. */ - tree oldop2 = op2; - if (sel.ninputs () == 2 - || can_vec_perm_const_p (result_mode, op_mode, sel, false)) - op2 = vec_perm_indices_to_tree (TREE_TYPE (op2), sel); - else - { - vec_perm_indices sel2 (builder, 2, nelts); - if (can_vec_perm_const_p (result_mode, op_mode, sel2, false)) - op2 = vec_perm_indices_to_tree (TREE_TYPE (op2), sel2); - else - /* Not directly supported with either encoding, - so use the preferred form. */ - op2 = vec_perm_indices_to_tree (TREE_TYPE (op2), sel); - } - if (!operand_equal_p (op2, oldop2, 0)) - changed = true; - } - } - (if (ins) - (bit_insert { op0; } { ins; } - { bitsize_int (at * vector_element_bits (type)); }) - (if (changed) - (vec_perm { op0; } { op1; } { op2; })))))))))) + } + (if (ins) + (bit_insert { op0; } { ins; } + { bitsize_int (at * vector_element_bits (type)); }) + (if (changed) + (vec_perm { op0; } { op1; } { op2; })))))))))))) /* VEC_PERM_EXPR (v, v, mask) -> v where v contains same element. */ @@ -8094,37 +8094,34 @@ and, (simplify (vec_perm (vec_perm@0 @1 @2 VECTOR_CST@3) @0 VECTOR_CST@4) - (with - { - if (!TYPE_VECTOR_SUBPARTS (type).is_constant ()) - return NULL_TREE; - - tree op0; - machine_mode result_mode = TYPE_MODE (type); - machine_mode op_mode = TYPE_MODE (TREE_TYPE (@1)); - int nelts = TYPE_VECTOR_SUBPARTS (type).to_constant (); - vec_perm_builder builder0; - vec_perm_builder builder1; - vec_perm_builder builder2 (nelts, nelts, 1); - - if (!tree_to_vec_perm_builder (&builder0, @3) - || !tree_to_vec_perm_builder (&builder1, @4)) - return NULL_TREE; - - vec_perm_indices sel0 (builder0, 2, nelts); - vec_perm_indices sel1 (builder1, 1, nelts); - - for (int i = 0; i < nelts; i++) - builder2.quick_push (sel0[sel1[i].to_constant ()]); + (if (TYPE_VECTOR_SUBPARTS (type).is_constant ()) + (with + { + machine_mode result_mode = TYPE_MODE (type); + machine_mode op_mode = TYPE_MODE (TREE_TYPE (@1)); + int nelts = TYPE_VECTOR_SUBPARTS (type).to_constant (); + vec_perm_builder builder0; + vec_perm_builder builder1; + vec_perm_builder builder2 (nelts, nelts, 1); + } + (if (tree_to_vec_perm_builder (&builder0, @3) + && tree_to_vec_perm_builder (&builder1, @4)) + (with + { + vec_perm_indices sel0 (builder0, 2, nelts); + vec_perm_indices sel1 (builder1, 1, nelts); - vec_perm_indices sel2 (builder2, 2, nelts); + for (int i = 0; i < nelts; i++) + builder2.quick_push (sel0[sel1[i].to_constant ()]); - if (!can_vec_perm_const_p (result_mode, op_mode, sel2, false)) - return NULL_TREE; + vec_perm_indices sel2 (builder2, 2, nelts); - op0 = vec_perm_indices_to_tree (TREE_TYPE (@4), sel2); - } - (vec_perm @1 @2 { op0; }))) + tree op0 = NULL_TREE; + if (can_vec_perm_const_p (result_mode, op_mode, sel2, false)) + op0 = vec_perm_indices_to_tree (TREE_TYPE (@4), sel2); + } + (if (op0) + (vec_perm @1 @2 { op0; }))))))) /* Match count trailing zeroes for simplify_count_trailing_zeroes in fwprop.