* [PATCH] Diagnose return statement in match.pd (with { ... } expressions
@ 2022-10-13 11:03 Richard Biener
0 siblings, 0 replies; only message in thread
From: Richard Biener @ 2022-10-13 11:03 UTC (permalink / raw)
To: gcc-patches
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<user_id *> (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 <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.
--
2.35.3
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-10-13 11:03 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-13 11:03 [PATCH] Diagnose return statement in match.pd (with { ... } expressions Richard Biener
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).