From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by sourceware.org (Postfix) with ESMTPS id 508F73858C56 for ; Thu, 13 Oct 2022 11:03:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 508F73858C56 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=suse.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=suse.de Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 4A76D1F461 for ; Thu, 13 Oct 2022 11:03:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1665658998; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version:content-type:content-type; bh=/txtS0/+0KFo1ekUTUDa4LFyBqQCUfSg0qm9IYsz4s8=; b=bFJJlPz5QrV091FtFvNir6Kc9FIgXetpJ2dyMMyMeAN26MKcSDxCLQ6xHomsLT7uK6iSeQ 2CDa0OnlGuQ//tDkTuMXQhK1kUrVgLBqXaZP0jk3BoSpx75uWu2sridr4rijc5U6ssYBtC L9u8E8zWBR54VC0f/v9jN9UT1yGzhVc= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1665658998; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version:content-type:content-type; bh=/txtS0/+0KFo1ekUTUDa4LFyBqQCUfSg0qm9IYsz4s8=; b=MCEZo/7f8gJ65tgDmhTxfZFfj7ir1Lac8bLItBHiX/l7rtFHKNn8KdLyYetbYTJ6yFtaLE PY2FZqJSAZPsWwDg== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 34FB413AAA for ; Thu, 13 Oct 2022 11:03:18 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id sDnMC3bwR2ONTwAAMHmgww (envelope-from ) for ; Thu, 13 Oct 2022 11:03:18 +0000 Date: Thu, 13 Oct 2022 13:03:17 +0200 (CEST) From: Richard Biener To: gcc-patches@gcc.gnu.org Subject: [PATCH] Diagnose return statement in match.pd (with { ... } expressions MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Message-Id: <20221013110318.34FB413AAA@imap2.suse-dmz.suse.de> X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: 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. Bootstrap and regtest running on x86_64-unknown-linux-gnu. * genmatch.c (parser::parse_c_expr): Diagnose 'return'. * match.pd: Replace 'return' statements in with expressions with appropriate variants. --- 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. -- 2.35.3