diff options
author | Richard Biener <rguenther@suse.de> | 2022-10-13 12:59:09 +0200 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2022-10-13 13:48:54 +0200 |
commit | 786e4c024f941671a233f5779d73a5d22f4e9588 (patch) | |
tree | 53acf5ed89d025c51d9961c64f2451a4d9071af4 /gcc | |
parent | 9f0d4adabe2035886a1aa8d2ca990a90de000613 (diff) | |
download | gcc-786e4c024f941671a233f5779d73a5d22f4e9588.zip gcc-786e4c024f941671a233f5779d73a5d22f4e9588.tar.gz gcc-786e4c024f941671a233f5779d73a5d22f4e9588.tar.bz2 |
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/genmatch.cc | 7 | ||||
-rw-r--r-- | gcc/match.pd | 293 |
2 files changed, 150 insertions, 150 deletions
diff --git a/gcc/genmatch.cc b/gcc/genmatch.cc index a0b22c5..4a88024 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<user_id *> (idb)) && p->is_oper_list) record_operlist (token->src_loc, p); diff --git a/gcc/match.pd b/gcc/match.pd index 3550c16..fd64ad7 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 <gassign *> (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 <gassign *> (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 <gassign *> (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 <gassign *> (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. |