Re: [PATCH v2 1/3] match: allow c variable for the code/operation of the result [PR126912]

Andrea Pinski <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <CALvbMcBc1tHiRerNa+ZO55tZZbkoFteqyf2SiMHMCtmMM=_4Lw@mail.gmail.com>
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.

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.




>
> 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
> >
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.