On Thu, Aug 20, 2026 at 5:54 AM Andrea Pinski
<[email protected]> wrote:
>
> On Wed, Aug 19, 2026 at 1:56 AM Richard Biener
> <[email protected]> wrote:
> >
> > On Wed, Aug 19, 2026 at 2:34 AM Andrea Pinski
> > <[email protected]> wrote:
> > >
> > > This allows a C variable for the code of the result
> > > to reduce how many for loops are needed and reduces the code size of
> > > the generated files by a factor of 6 (in some cases).
> > > This should allow for arm to build again at -O0.
> > >
> > > Currently this only allows if the variable contains `code` in it.
> > > If the identifier has cmp in it; genmatch assumes it will be a
> > > tcc_comparison for type resultion.
> > >
> > > I can add support for combined_fn and internal_fn later if needed.
> > > From looking into the match patterns right now; there is a few but none
> > > use a for loop for cases but rather just a few (3/4) if statements. So it
> > > was not high on my list of things to support currently.
> >
> > I do not like the automagic ID recognition too much.  Esp. automatically
> > treating anything with 'cmp' as tcc_comparison might lead to wrong code.
> > If we stick with that can you please code-generate runtime checking at 
> > least?
> > There might be more problematic cases for type-inference(?) and most
> > definitely for "escape" handling - capture_info::walk_result checks
> > for COND_EXPR and TRUTH_{AND,OR}IF_EXPR but you do not touch
> > this.  Runtime checking could be done for those as well.
> >
> > But I wonder whether sth like
> >
> > (simplify (...)
> >  (with { tree_code code = ...; }
> >   (code<tcc_comparison> ...)))
> >
> > would be better overall, that is, require the set of possible operators to
> > be specified as declared operator list.  So it would be a user-id
> > declaration at result parsing time.
> >
> > I thought of
> >
> >  (tcc_comparsion code @0 @1)
> >
> > but this doesn't seem lispy syntax.  Alternatively do "toplevel"
> >
> > (simplify (...)
> >  (with { tree_code = ...; }
> >   (with_code code (tcc_comparison)
> >    (code @0 @1)))
> >
> > so similar to (for ..) syntax, have a declare syntax.  Allow
> >
> >   (with_code code (tcc_comparison)
> >                    code2 (plus minus)
> >
> > as well.  I think I prefer (with_code ...)?
>
> What about this:
> (simplify
>   (bit_xor (cmp @@0 @@1) integer_truep)
>   (with_code
>       rescode tcc_comparison
>       resbincode 2
>       resunarycode 1
>       restrianycode 3
>    (with { rescode = invert_tree_comparison (cmp, HONOR_NANS (@0)); }
>     (if (TREE_CODE_CLASS (rescode) == tcc_comparison)
>      (rescode @0 @1)))))
>
> with_code can only contain a `(with` expression too.

So how about extending (with ..) directly then?

 (simplify
  (bit_xor (cmp @@0 @@1) integer_truep)
  (with
     rescode (tcc_comparison)
     resunarycode (tcc_unary)
   {
     tree_code rescode = invert_tree_comparison (cmp, HONOR_NANS (@0));
   }
   (if (TREE_CODE_CLASS (rescode) == tcc_comparison)
    (rescode @0 @1))))

I don't like 'resbincode 2', it should be very easy to enumerate allowed codes
(and we could code generate checking in checking mode if we want).  I'd also
like to re-use the (for ..) operator list syntax, so a paren around
(tcc_comparison),
that can also easily re-use parsing for that plus the representation of the set
itself.

It makes sense to combine with (with ...) since there has to be a with
that actually declares the variable.  Not sure if we should be able to elide
the declaration of the variables in the {}, we could possibly inject

 code_helper <identifier>;

declarations.  I could see use for builtins/ifns when doing target dependent
selection, so it should in princinple be extensible to the function designator
case without syntactic changes (so temporarily only injecting
tree_code <identifier>;
would work for me if code_helper doesn't work downstream w/o big changes)

So to summarize, I now prefer extending (with ...), use the (for ..) operator
list syntax, inject declarations to the start of the with c_expr block.
The last bit is least important, but changing it later would affect
compatibility.

> 3 can't be COND_EXPR/VEC_COND_EXPR. (I can't see where that would
> happen anyways)
> 2 can't be either TRUTH_ANDIF_EXPR/TRUTH_ORIF_EXPR either.
> 1 can be VCE/REAL_PART_EXPR/IMAG_PART_EXPR; otherwise it is tcc_unary.
> 2 can't be tcc_comparison.
>
> Note I can't see any use right now outside of comparison or internal/builtins.
> The MIN/MAX results from minmax_from_comparison is the only other
> place which we could use it though currently an if happens so it could
> simplify the generation code slightly.
>
> Anyways I will try to come up with a patch later this week.

Thanks.
Richard.

>
>
>
>
> >
> > Richard.
> >
> > > Bootstrapped and tested on x86_64-linux-gnu.
> > >
> > >         PR middle-end/126912
> > > gcc/ChangeLog:
> > >
> > >         * doc/match-and-simplify.texi: Document new syntax.
> > >         * genmatch.cc (class c_code_id): New class.
> > >         (c_code_id::get_c_code_id): New method.
> > >         (c_ids): New hashtable.
> > >         (test): Handle C_CODE_ID.
> > >         (lower_for): Handle c_code_id.
> > >         (get_operand_type): Check cmp of c_code_id.
> > >         (expr::gen_transform): Likewise.
> > >         (dt_simplify::gen_1): Handle C_CODE_ID like CODE.
> > >         (parser::parse_operation): Add bool res argument. For unknown id
> > >         see if this can be a c code id for res.
> > >         (parser::parse_expr): Add bool res argument. Pass down to parse_op
> > >         and parse_operation.
> > >         (parser::parse_op): Add bool res argument.
> > >         Pass down to parse_expr and parse_op.
> > >         (parser::parse_result): Pass true to parse_op and parse_expr.
> > >         (parser::parse_simplify): Pass false to parse_op.
> > >         (main): Allocate and free c_ids.
> > >         * match.pd (`(a CMP1 b) bitop (a CMP2 b)`): Remove rcmp
> > >         loop and update for the new syntax.
> > >         (other comparison loops): Update for the new syntax.
> > >
> > > Signed-off-by: Andrea Pinski <[email protected]>
> > > ---
> > >  gcc/doc/match-and-simplify.texi |  13 ++++
> > >  gcc/genmatch.cc                 | 114 ++++++++++++++++++++++++--------
> > >  gcc/match.pd                    |  77 +++++++++------------
> > >  3 files changed, 129 insertions(+), 75 deletions(-)
> > >
> > > diff --git a/gcc/doc/match-and-simplify.texi 
> > > b/gcc/doc/match-and-simplify.texi
> > > index b187dd27561..4f171a36f69 100644
> > > --- a/gcc/doc/match-and-simplify.texi
> > > +++ b/gcc/doc/match-and-simplify.texi
> > > @@ -361,6 +361,19 @@ Usually the types of the generated result 
> > > expressions are
> > >  determined from the context, but sometimes like in the above case
> > >  it is required that you specify them explicitly.
> > >
> > > +In the result of a simplify, a variable defined in @code{with} can be
> > > +use as the resulting tree code if it contains @code{code} in the name.
> > > +Comparisons results need to have cmp in its name to get the correct type 
> > > for it.
> > > +
> > > +@smallexample
> > > + (simplify
> > > +  (bit_xor (cmp @@0 @@1) integer_truep)
> > > +  (with @{ enum tree_code rescmpcode = invert_tree_comparison
> > > +            (cmp, HONOR_NANS (@@0)); @}
> > > +    (if (TREE_CODE_CLASS (rescmpcode) == tcc_comparison)
> > > +     (rescmpcode @@0 @@1))))
> > > +@end smallexample
> > > +
> > >  Another modifier for generated expressions is @code{^} which
> > >  tells the machinery to try more matches for some special cases.
> > >  For example, normally the @code{cond} only allows the gimple
> > > diff --git a/gcc/genmatch.cc b/gcc/genmatch.cc
> > > index 920cf27877d..44da9fa3970 100644
> > > --- a/gcc/genmatch.cc
> > > +++ b/gcc/genmatch.cc
> > > @@ -1121,7 +1121,7 @@ comparison_code_p (enum tree_code code)
> > >  class id_base : public nofree_ptr_hash<id_base>
> > >  {
> > >  public:
> > > -  enum id_kind { CODE, FN, PREDICATE, USER, NULL_ID } kind;
> > > +  enum id_kind { CODE, FN, PREDICATE, USER, C_CODE_ID, NULL_ID } kind;
> > >
> > >    id_base (id_kind, const char *, int = -1);
> > >
> > > @@ -1199,6 +1199,37 @@ public:
> > >    vec<simplify *> matchers;
> > >  };
> > >
> > > +// Identifier that maps to a operator defined by a 'C' identifier.
> > > +// Contains code in the id, also if contains cmp then it is a compare.
> > > +
> > > +class c_code_id : public id_base
> > > +{
> > > +public:
> > > +  c_code_id (const char *id_)
> > > +    : id_base (id_base::C_CODE_ID, xstrdup (id_)),
> > > +      cmp (strstr (id_, "cmp")) {}
> > > +  static id_base *get_c_code_id (const char *);
> > > +  ~c_code_id() { delete const_cast<char*>(id); }
> > > +  bool cmp;
> > > +};
> > > +
> > > +static hash_table<id_base> *c_ids;
> > > +
> > > +id_base *
> > > +c_code_id::get_c_code_id (const char *id)
> > > +{
> > > +  if (!strstr (id, "code"))
> > > +    return nullptr;
> > > +  id_base tem (id_base::C_CODE_ID, id);
> > > +
> > > +  id_base **op = c_ids->find_slot_with_hash (&tem, tem.hashval, INSERT);
> > > +  if (!*op)
> > > +   *op = new c_code_id (id);
> > > +
> > > +  return *op;
> > > +}
> > > +
> > > +
> > >  /* Identifier that maps to a operator defined by a 'for' directive.  */
> > >
> > >  class user_id : public id_base
> > > @@ -1244,6 +1275,14 @@ is_a_helper <user_id *>::test (id_base *id)
> > >    return id->kind == id_base::USER;
> > >  }
> > >
> > > +template<>
> > > +template<>
> > > +inline bool
> > > +is_a_helper <c_code_id *>::test (id_base *id)
> > > +{
> > > +  return id->kind == id_base::C_CODE_ID;
> > > +}
> > > +
> > >  /* If ID has a pair of consecutive, commutative operands, return the
> > >     index of the first, otherwise return -1.  */
> > >
> > > @@ -2301,6 +2340,8 @@ lower_for (simplify *sin, vec<simplify *>& 
> > > simplifiers)
> > >               }
> > >             else if (is_a <fn_id *> (ids[i]->substitutes[j]))
> > >               ;
> > > +           else if (is_a <c_code_id *> (ids[i]->substitutes[j]))
> > > +             ;
> > >             else
> > >               can_delay_subst = false;
> > >         }
> > > @@ -3222,8 +3263,10 @@ get_operand_type (id_base *op, unsigned pos,
> > >    else if (*op == REALPART_EXPR
> > >            || *op == IMAGPART_EXPR)
> > >      return other_oprnd_type;
> > > -  else if (is_a <operator_id *> (op)
> > > -          && strcmp (as_a <operator_id *> (op)->tcc, "tcc_comparison") 
> > > == 0)
> > > +  else if ((is_a <operator_id *> (op)
> > > +           && strcmp (as_a <operator_id *> (op)->tcc, "tcc_comparison") 
> > > == 0)
> > > +          || (is_a <c_code_id *> (op)
> > > +              && as_a <c_code_id *>(op)->cmp))
> > >      return other_oprnd_type;
> > >    else if (*op == COND_EXPR
> > >            && pos == 0)
> > > @@ -3285,8 +3328,10 @@ expr::gen_transform (FILE *f, int indent, const 
> > > char *dest, bool gimple,
> > >                 depth);
> > >        type = optype;
> > >      }
> > > -  else if (is_a <operator_id *> (opr)
> > > -          && !strcmp (as_a <operator_id *> (opr)->tcc, "tcc_comparison"))
> > > +  else if ((is_a <operator_id *> (opr)
> > > +            && !strcmp (as_a <operator_id *> (opr)->tcc, 
> > > "tcc_comparison"))
> > > +           || (is_a <c_code_id *> (opr)
> > > +              && as_a <c_code_id *> (opr)->cmp))
> > >      {
> > >        /* comparisons use boolean_type_node (or what gets in), but
> > >           their operands need to figure out the types themselves.  */
> > > @@ -3451,7 +3496,7 @@ expr::gen_transform (FILE *f, int indent, const 
> > > char *dest, bool gimple,
> > >           fprintf_indent (f, indent + 2, "{\n");
> > >           indent += 4;
> > >         }
> > > -      if (opr->kind == id_base::CODE)
> > > +      if (opr->kind == id_base::CODE || opr->kind == id_base::C_CODE_ID)
> > >         fprintf_indent (f, indent, "_r%d = fold_build%d_loc (loc, %s, %s",
> > >                         depth, ops.length(), opr_name, type);
> > >        else
> > > @@ -3460,7 +3505,7 @@ expr::gen_transform (FILE *f, int indent, const 
> > > char *dest, bool gimple,
> > >        for (unsigned i = 0; i < ops.length (); ++i)
> > >         fprintf (f, ", _o%d[%u]", depth, i);
> > >        fprintf (f, ");\n");
> > > -      if (opr->kind != id_base::CODE)
> > > +      if (opr->kind != id_base::CODE && opr->kind != id_base::C_CODE_ID)
> > >         {
> > >           fprintf_indent (f, indent, "if (!_r%d)\n", depth);
> > >           fprintf_indent (f, indent, "  goto %s;\n", fail_label);
> > > @@ -4630,7 +4675,7 @@ dt_simplify::gen_1 (FILE *f, int indent, bool 
> > > gimple, operand *result)
> > >                                 "_r = non_lvalue_loc (loc, res_op0);\n");
> > >               else
> > >                 {
> > > -                 if (is_a <operator_id *> (opr))
> > > +                 if (is_a <operator_id *> (opr) || is_a <c_code_id *> 
> > > (opr))
> > >                     fprintf_indent (f, indent,
> > >                                     "_r = fold_build%d_loc (loc, %s, 
> > > type",
> > >                                     e->ops.length (),
> > > @@ -4644,7 +4689,7 @@ dt_simplify::gen_1 (FILE *f, int indent, bool 
> > > gimple, operand *result)
> > >                   for (unsigned j = 0; j < e->ops.length (); ++j)
> > >                     fprintf (f, ", res_op%d", j);
> > >                   fprintf (f, ");\n");
> > > -                 if (!is_a <operator_id *> (opr))
> > > +                 if (!is_a <operator_id *> (opr) && !is_a<c_code_id *> 
> > > (opr))
> > >                     {
> > >                       fprintf_indent (f, indent, "if (!_r)\n");
> > >                       fprintf_indent (f, indent, "  goto %s;\n", 
> > > fail_label);
> > > @@ -5146,11 +5191,11 @@ private:
> > >
> > >    unsigned get_internal_capture_id ();
> > >
> > > -  id_base *parse_operation (unsigned char &);
> > > +  id_base *parse_operation (unsigned char &, bool);
> > >    operand *parse_capture (operand *, bool);
> > > -  operand *parse_expr ();
> > > +  operand *parse_expr (bool = false);
> > >    c_expr *parse_c_expr (cpp_ttype);
> > > -  operand *parse_op ();
> > > +  operand *parse_op (bool);
> > >
> > >    void record_operlist (location_t, user_id *);
> > >
> > > @@ -5338,7 +5383,7 @@ parser::record_operlist (location_t loc, user_id *p)
> > >     convert2?  */
> > >
> > >  id_base *
> > > -parser::parse_operation (unsigned char &opt_grp)
> > > +parser::parse_operation (unsigned char &opt_grp, bool res)
> > >  {
> > >    const cpp_token *id_tok = peek ();
> > >    char *alt_id = NULL;
> > > @@ -5365,7 +5410,18 @@ parser::parse_operation (unsigned char &opt_grp)
> > >      }
> > >    id_base *op = get_operator (alt_id ? alt_id : id);
> > >    if (!op)
> > > -    fatal_at (id_tok, "unknown operator %s", alt_id ? alt_id : id);
> > > +    {
> > > +      // An unknown id that contains code in it is considered a C code 
> > > identifier
> > > +      if (res)
> > > +       {
> > > +         if (id_base *op = c_code_id::get_c_code_id (id))
> > > +           {
> > > +             free (alt_id);
> > > +             return op;
> > > +           }
> > > +       }
> > > +      fatal_at (id_tok, "unknown operator %s", alt_id ? alt_id : id);
> > > +    }
> > >    if (alt_id)
> > >      free (alt_id);
> > >    user_id *p = dyn_cast<user_id *> (op);
> > > @@ -5420,11 +5476,11 @@ parser::parse_capture (operand *op, bool 
> > > require_existing)
> > >       expr = '(' <operation>[capture][flag][type] <operand>... ')'  */
> > >
> > >  class operand *
> > > -parser::parse_expr ()
> > > +parser::parse_expr (bool res)
> > >  {
> > >    const cpp_token *token = peek ();
> > >    unsigned char opt_grp;
> > > -  expr *e = new expr (parse_operation (opt_grp), token->src_loc);
> > > +  expr *e = new expr (parse_operation (opt_grp, res), token->src_loc);
> > >    token = peek ();
> > >    operand *op;
> > >    bool is_commutative = false;
> > > @@ -5537,7 +5593,7 @@ parser::parse_expr ()
> > >        else if (!(token->flags & PREV_WHITE))
> > >         fatal_at (token, "expected expression operand");
> > >
> > > -      e->append_op (parse_op ());
> > > +      e->append_op (parse_op (res));
> > >      }
> > >    while (1);
> > >  }
> > > @@ -5602,14 +5658,14 @@ parser::parse_c_expr (cpp_ttype start)
> > >       op = predicate | expr | c_expr | capture  */
> > >
> > >  class operand *
> > > -parser::parse_op ()
> > > +parser::parse_op (bool res)
> > >  {
> > >    const cpp_token *token = peek ();
> > >    class operand *op = NULL;
> > >    if (token->type == CPP_OPEN_PAREN)
> > >      {
> > >        eat_token (CPP_OPEN_PAREN);
> > > -      op = parse_expr ();
> > > +      op = parse_expr (res);
> > >        eat_token (CPP_CLOSE_PAREN);
> > >      }
> > >    else if (token->type == CPP_OPEN_BRACE)
> > > @@ -5695,7 +5751,7 @@ parser::parse_result (operand *result, predicate_id 
> > > *matcher)
> > >  {
> > >    const cpp_token *token = peek ();
> > >    if (token->type != CPP_OPEN_PAREN)
> > > -    return parse_op ();
> > > +    return parse_op (true);
> > >
> > >    eat_token (CPP_OPEN_PAREN);
> > >    if (peek_ident ("if"))
> > > @@ -5709,15 +5765,15 @@ parser::parse_result (operand *result, 
> > > predicate_id *matcher)
> > >           if (peek ()->type == CPP_OPEN_PAREN)
> > >             ife->falseexpr = parse_result (result, matcher);
> > >           else if (peek ()->type != CPP_CLOSE_PAREN)
> > > -           ife->falseexpr = parse_op ();
> > > +           ife->falseexpr = parse_op (true);
> > >         }
> > >        else if (peek ()->type != CPP_CLOSE_PAREN)
> > >         {
> > > -         ife->trueexpr = parse_op ();
> > > +         ife->trueexpr = parse_op (true);
> > >           if (peek ()->type == CPP_OPEN_PAREN)
> > >             ife->falseexpr = parse_result (result, matcher);
> > >           else if (peek ()->type != CPP_CLOSE_PAREN)
> > > -           ife->falseexpr = parse_op ();
> > > +           ife->falseexpr = parse_op (true);
> > >         }
> > >        /* If this if is immediately closed then it contains a
> > >          manual matcher or is part of a predicate definition.  */
> > > @@ -5752,7 +5808,7 @@ parser::parse_result (operand *result, predicate_id 
> > > *matcher)
> > >        if (peek ()->type == CPP_OPEN_PAREN)
> > >         ife->trueexpr = parse_result (result, matcher);
> > >        else
> > > -       ife->trueexpr = parse_op ();
> > > +       ife->trueexpr = parse_op (true);
> > >        eat_token (CPP_CLOSE_PAREN);
> > >        if (peek ()->type != CPP_OPEN_PAREN
> > >           || !peek_ident ("if", 2))
> > > @@ -5771,7 +5827,7 @@ parser::parse_result (operand *result, predicate_id 
> > > *matcher)
> > >                   if (peek ()->type == CPP_OPEN_PAREN)
> > >                     ife->trueexpr = parse_result (result, matcher);
> > >                   else
> > > -                   ife->trueexpr = parse_op ();
> > > +                   ife->trueexpr = parse_op (true);
> > >                   if (peek ()->type == CPP_OPEN_PAREN)
> > >                     fatal_at (peek(), "if inside switch cannot have an 
> > > else");
> > >                   eat_token (CPP_CLOSE_PAREN);
> > > @@ -5787,7 +5843,7 @@ parser::parse_result (operand *result, predicate_id 
> > > *matcher)
> > >           else
> > >             {
> > >               /* switch default clause */
> > > -             ife->falseexpr = parse_op ();
> > > +             ife->falseexpr = parse_op (true);
> > >               eat_token (CPP_CLOSE_PAREN);
> > >               return res;
> > >             }
> > > @@ -5799,7 +5855,7 @@ parser::parse_result (operand *result, predicate_id 
> > > *matcher)
> > >      {
> > >        operand *op = result;
> > >        if (!matcher)
> > > -       op = parse_expr ();
> > > +       op = parse_expr (true);
> > >        eat_token (CPP_CLOSE_PAREN);
> > >        return op;
> > >      }
> > > @@ -5826,7 +5882,7 @@ parser::parse_simplify (simplify::simplify_kind 
> > > kind,
> > >
> > >    const cpp_token *loc = peek ();
> > >    parsing_match_operand = true;
> > > -  class operand *match = parse_op ();
> > > +  class operand *match = parse_op (false);
> > >    finish_match_operand (match);
> > >    parsing_match_operand = false;
> > >    if (match->type == operand::OP_CAPTURE && !matcher)
> > > @@ -6366,6 +6422,7 @@ main (int argc, char **argv)
> > >
> > >    /* Pre-seed operators.  */
> > >    operators = new hash_table<id_base> (1024);
> > > +  c_ids = new hash_table<id_base> (4);
> > >  #define DEFTREECODE(SYM, STRING, TYPE, NARGS) \
> > >    add_operator (SYM, # SYM, # TYPE, NARGS);
> > >  #define END_OF_BASE_TREE_CODES
> > > @@ -6471,6 +6528,7 @@ main (int argc, char **argv)
> > >    cpp_destroy (r);
> > >
> > >    delete operators;
> > > +  delete c_ids;
> > >
> > >    return 0;
> > >  }
> > > diff --git a/gcc/match.pd b/gcc/match.pd
> > > index eae8717bcfe..d255795c8dd 100644
> > > --- a/gcc/match.pd
> > > +++ b/gcc/match.pd
> > > @@ -4006,20 +4006,19 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> > >  (for bitop (bit_and bit_ior)
> > >   (for cmp1 (tcc_comparison)
> > >    (for cmp2 (tcc_comparison)
> > > -   (for rcmp (tcc_comparison)
> > > -    (simplify
> > > -     (bitop (cmp1 @0 @1) (cmp2 @0 @1))
> > > -     (with {
> > > -       tree_code rescode;
> > > -       tree res;
> > > -       bool honor_nans = HONOR_NANS (@0);
> > > -       rescode = combine_comparisons (bitop, cmp1, cmp2,
> > > -                                     type, honor_nans, &res);
> > > -      }
> > > -      (if (rescode == INTEGER_CST)
> > > -       { res; }
> > > -       (if (rescode == rcmp)
> > > -        (rcmp @0 @1)))))))))
> > > +   (simplify
> > > +    (bitop (cmp1 @0 @1) (cmp2 @0 @1))
> > > +    (with {
> > > +      tree_code rescmpcode;
> > > +      tree res;
> > > +      bool honor_nans = HONOR_NANS (@0);
> > > +      rescmpcode = combine_comparisons (bitop, cmp1, cmp2,
> > > +                                       type, honor_nans, &res);
> > > +     }
> > > +     (if (rescmpcode == INTEGER_CST)
> > > +      { res; }
> > > +      (if (TREE_CODE_CLASS (rescmpcode) == tcc_comparison)
> > > +       (rescmpcode @0 @1))))))))
> > >
> > >  /* (type)([0,1]@a != 0) -> (type)a
> > >     (type)([0,1]@a == 1) -> (type)a
> > > @@ -7781,8 +7780,6 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> > >     operator using invert_tree_comparison we have to simulate
> > >     that with expression code iteration.  */
> > >  (for cmp (tcc_comparison)
> > > -     icmp (inverted_tcc_comparison)
> > > -     ncmp (inverted_tcc_comparison_with_nans)
> > >   /* Ideally we'd like to combine the following two patterns
> > >      and handle some more cases by using
> > >        (logical_inverted_value (cmp @0 @1))
> > > @@ -7793,39 +7790,29 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> > >    (if (VECTOR_TYPE_P (type)
> > >         || (INTEGRAL_TYPE_P (type) && TYPE_PRECISION (type) == 1))
> > >     /* Comparison inversion may be impossible for trapping math,
> > > -      invert_tree_comparison will tell us.  But we can't use
> > > -      a computed operator in the replacement tree thus we have
> > > -      to play the trick below.  */
> > > -   (with { enum tree_code ic = invert_tree_comparison
> > > +      invert_tree_comparison will tell us.  */
> > > +   (with { enum tree_code rescmpcode = invert_tree_comparison
> > >               (cmp, HONOR_NANS (@0)); }
> > > -    (if (ic == icmp)
> > > -     (icmp @0 @1)
> > > -     (if (ic == ncmp)
> > > -      (ncmp @0 @1))))))
> > > +    (if (TREE_CODE_CLASS (rescmpcode) == tcc_comparison)
> > > +     (rescmpcode @0 @1)))))
> > >   (simplify
> > >    (bit_xor (cmp @0 @1) integer_truep)
> > > -  (with { enum tree_code ic = invert_tree_comparison
> > > +  (with { enum tree_code rescmpcode = invert_tree_comparison
> > >              (cmp, HONOR_NANS (@0)); }
> > > -   (if (ic == icmp)
> > > -    (icmp @0 @1)
> > > -    (if (ic == ncmp)
> > > -     (ncmp @0 @1)))))
> > > +    (if (TREE_CODE_CLASS (rescmpcode) == tcc_comparison)
> > > +     (rescmpcode @0 @1))))
> > >   /* ((cast)cmp) - 1 -> -(cast)icmp . */
> > >   (simplify
> > >    (plus (convert? (cmp@2 @0 @1)) integer_minus_onep)
> > >    (if (TYPE_PRECISION (type) > 1
> > >         && INTEGRAL_TYPE_P (TREE_TYPE (@2)) && TYPE_PRECISION (TREE_TYPE 
> > > (@2)) == 1)
> > >     /* Comparison inversion may be impossible for trapping math,
> > > -      invert_tree_comparison will tell us.  But we can't use
> > > -      a computed operator in the replacement tree thus we have
> > > -      to play the trick below.  */
> > > -   (with { enum tree_code ic = invert_tree_comparison
> > > +      invert_tree_comparison will tell us.  */
> > > +   (with { enum tree_code rescmpcode = invert_tree_comparison
> > >               (cmp, HONOR_NANS (@0));
> > >             tree cmptype = TREE_TYPE (@2); }
> > > -    (if (ic == icmp)
> > > -     (negate (convert (icmp:cmptype @0 @1)))
> > > -     (if (ic == ncmp)
> > > -      (negate (convert (ncmp:cmptype @0 @1))))))))
> > > +    (if (TREE_CODE_CLASS (rescmpcode) == tcc_comparison)
> > > +     (negate (convert (rescmpcode:cmptype @0 @1)))))))
> > >   /* The following bits are handled by 
> > > fold_binary_op_with_conditional_arg.  */
> > >   (simplify
> > >    (ne (cmp@2 @0 @1) integer_zerop)
> > > @@ -7838,21 +7825,17 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> > >   (simplify
> > >    (ne (cmp@2 @0 @1) integer_truep)
> > >    (if (types_match (type, TREE_TYPE (@2)))
> > > -   (with { enum tree_code ic = invert_tree_comparison
> > > +   (with { enum tree_code rescmpcode = invert_tree_comparison
> > >              (cmp, HONOR_NANS (@0)); }
> > > -    (if (ic == icmp)
> > > -     (icmp @0 @1)
> > > -     (if (ic == ncmp)
> > > -      (ncmp @0 @1))))))
> > > +    (if (TREE_CODE_CLASS (rescmpcode) == tcc_comparison)
> > > +     (rescmpcode @0 @1)))))
> > >   (simplify
> > >    (eq (cmp@2 @0 @1) integer_zerop)
> > >    (if (types_match (type, TREE_TYPE (@2)))
> > > -   (with { enum tree_code ic = invert_tree_comparison
> > > +   (with { enum tree_code rescmpcode = invert_tree_comparison
> > >              (cmp, HONOR_NANS (@0)); }
> > > -    (if (ic == icmp)
> > > -     (icmp @0 @1)
> > > -     (if (ic == ncmp)
> > > -      (ncmp @0 @1)))))))
> > > +    (if (TREE_CODE_CLASS (rescmpcode) == tcc_comparison)
> > > +     (rescmpcode @0 @1))))))
> > >
> > >  /* Transform comparisons of the form X - Y CMP 0 to X CMP Y.
> > >     ??? The transformation is valid for the other operators if overflow
> > > --
> > > 2.43.0
> > >

Reply via email to