On Sat, May 9, 2026 at 2:09 AM Li, Pan2 <[email protected]> wrote:
>
> > Add a small comment on what is being included here.
> > Like:
> > /* Include the saturation alu match patterns.  */
>
> Thanks Pinski, will commit with the comment if OK from Richard.

LGTM

> Pan
>
> -----Original Message-----
> From: Andrew Pinski <[email protected]>
> Sent: Saturday, May 9, 2026 7:55 AM
> To: Li, Pan2 <[email protected]>
> Cc: [email protected]; [email protected]; [email protected]; 
> [email protected]; [email protected]; Chen, Ken <[email protected]>; 
> Liu, Hongtao <[email protected]>; [email protected]
> Subject: Re: [PATCH v2] Match: Move saturation alu patterns into 
> match-sat-alu.pd [NFC]
>
> On Fri, May 8, 2026 at 4:26 PM <[email protected]> wrote:
> >
> > From: Pan Li <[email protected]>
> >
> > Given there are lots of sat alu patterns in match.pd, and
> > there will more in short future.  Move all of them into
> > a separated file for better org.
> >
> > The below test suites are passed for this patch:
> > 1. The rv64gcv fully regression tests.
> > 2. The x86 bootstrap tests.
> > 3. The x86 fully regression tests.
> >
> > gcc/ChangeLog:
> >
> >         * Makefile.in: Add match-sat-alu.pd as dependency.
> >         * match.pd: Remove saturation alu related patterns.
> >         * match-sat-alu.pd: Add new file for saturation alu patterns.
>
> LGTM. Give Richard B. until Tuesday to review it.
> Just a small change I request ...
>
> >
> > Signed-off-by: Pan Li <[email protected]>
> > ---
> >  gcc/Makefile.in      |   2 +-
> >  gcc/match-sat-alu.pd | 566 ++++++++++++++++++++++++++++++++++++++++++
> >  gcc/match.pd         | 572 ++-----------------------------------------
> >  3 files changed, 584 insertions(+), 556 deletions(-)
> >  create mode 100644 gcc/match-sat-alu.pd
> >
> > diff --git a/gcc/Makefile.in b/gcc/Makefile.in
> > index 5e656c3c25b..e86884853bc 100644
> > --- a/gcc/Makefile.in
> > +++ b/gcc/Makefile.in
> > @@ -3055,7 +3055,7 @@ $(GENERIC_MATCH_PD_SEQ_SRC): s-generic-match 
> > generic-match-head.cc; @true
> >  generic-match-auto.h: s-generic-match; @true
> >
> >  s-gimple-match: build/genmatch$(build_exeext) \
> > -           $(srcdir)/match.pd cfn-operators.pd
> > +           $(srcdir)/match.pd $(srcdir)/match-sat-alu.pd cfn-operators.pd
> >         $(RUN_GEN) build/genmatch$(build_exeext) --gimple \
> >             --header=tmp-gimple-match-auto.h --include=gimple-match-auto.h \
> >             $(srcdir)/match.pd $(patsubst %, tmp-%, 
> > $(GIMPLE_MATCH_PD_SEQ_SRC))
> > diff --git a/gcc/match-sat-alu.pd b/gcc/match-sat-alu.pd
> > new file mode 100644
> > index 00000000000..483c37b6d9f
> > --- /dev/null
> > +++ b/gcc/match-sat-alu.pd
> > @@ -0,0 +1,566 @@
> > +/* Match-and-simplify Saturation ALU patterns for shared GENERIC and GIMPLE
> > +   folding,  included by match.pd for clear organizational structure.
> > +   This file is consumed by genmatch which produces gimple-match.cc
> > +   and generic-match.cc from it.
> > +
> > +   Copyright (C) 2014-2026 Free Software Foundation, Inc.
> > +   Contributed by Pan Li <[email protected]>
> > +
> > +This file is part of GCC.
> > +
> > +GCC is free software; you can redistribute it and/or modify it under
> > +the terms of the GNU General Public License as published by the Free
> > +Software Foundation; either version 3, or (at your option) any later
> > +version.
> > +
> > +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> > +WARRANTY; without even the implied warranty of MERCHANTABILITY or
> > +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> > +for more details.
> > +
> > +You should have received a copy of the GNU General Public License
> > +along with GCC; see the file COPYING3.  If not see
> > +<http://www.gnu.org/licenses/>.  */
> > +
> > +
> > +/* Saturation add for unsigned integer.  */
> > +(if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type))
> > + (match (usadd_overflow_mask @0 @1)
> > +  /* SAT_U_ADD = (X + Y) | -(X > (X + Y)).
> > +     Overflow_Mask = -(X > (X + Y)).  */
> > +  (negate (convert (gt @0 (plus:c @0 @1))))
> > +  (if (types_match (type, @0, @1))))
> > + (match (usadd_overflow_mask @0 @1)
> > +  /* SAT_U_ADD = (X + Y) | -(X > (X + Y)).
> > +     Overflow_Mask = -((X + Y) < X).  */
> > +  (negate (convert (lt (plus:c @0 @1) @0)))
> > +  (if (types_match (type, @0, @1))))
> > + (match (unsigned_integer_sat_add @0 @1)
> > +  /* SAT_U_ADD = (X + Y) | Overflow_Mask  */
> > +  (bit_ior:c (plus:c @0 @1) (usadd_overflow_mask @0 @1))
> > +  (if (types_match (type, @0, @1))))
> > + (match (unsigned_integer_sat_add @0 @1)
> > +  /* SAT_U_ADD = (X + Y) >= X ? (X + Y) : -1  */
> > +  (cond^ (ge (plus:c@2 @0 @1) @0) @2 integer_minus_onep)
> > +  (if (types_match (type, @0, @1))))
> > + (match (unsigned_integer_sat_add @0 @1)
> > +  /* SAT_U_ADD = (X + Y) < X ? -1 : (X + Y)  */
> > +  (cond^ (lt (plus:c@2 @0 @1) @0) integer_minus_onep @2)
> > +  (if (types_match (type, @0, @1))))
> > + (match (unsigned_integer_sat_add @0 @1)
> > +  /* SAT_U_ADD = X <= (X + Y) ? (X + Y) : -1  */
> > +  (cond^ (le @0 (plus:c@2 @0 @1)) @2 integer_minus_onep)
> > +  (if (types_match (type, @0, @1))))
> > + (match (unsigned_integer_sat_add @0 @1)
> > +  /* SAT_U_ADD = X > (X + Y) ? -1 : (X + Y)  */
> > +  (cond^ (gt @0 (plus:c@2 @0 @1)) integer_minus_onep @2)
> > +  (if (types_match (type, @0, @1))))
> > + (match (unsigned_integer_sat_add @0 @1)
> > +  /* SAT_U_ADD = (X + IMM) >= x ? (X + IMM) : -1  */
> > +  (plus (min @0 INTEGER_CST@2) INTEGER_CST@1)
> > +  (if (types_match (type, @0, @1))
> > +   (with
> > +    {
> > +     unsigned precision = TYPE_PRECISION (type);
> > +     wide_int cst_1 = wi::to_wide (@1);
> > +     wide_int cst_2 = wi::to_wide (@2);
> > +     wide_int max = wi::mask (precision, false, precision);
> > +     wide_int sum = wi::add (cst_1, cst_2);
> > +    }
> > +    (if (wi::eq_p (max, sum))))))
> > + (match (unsigned_integer_sat_add @0 @1)
> > +  /* SUM = ADD_OVERFLOW (X, Y)
> > +     SAT_U_ADD = REALPART (SUM) | -IMAGPART (SUM)   */
> > +  (bit_ior:c (realpart (IFN_ADD_OVERFLOW@2 @0 @1)) (negate (imagpart @2)))
> > +  (if (types_match (type, @0, @1))))
> > + (match (unsigned_integer_sat_add @0 @1)
> > +  /* SUM = ADD_OVERFLOW (X, Y)
> > +     SAT_U_ADD = REALPART (SUM) | -(IMAGPART (SUM) != 0)   */
> > +  (bit_ior:c (realpart (IFN_ADD_OVERFLOW@2 @0 @1))
> > +            (negate (convert (ne (imagpart @2) integer_zerop))))
> > +  (if (types_match (type, @0, @1))))
> > + (match (unsigned_integer_sat_add @0 @1)
> > +  /* SUM = ADD_OVERFLOW (X, Y)
> > +     SAT_U_ADD = IMAGPART (SUM) == 0 ? REALPART (SUM) : -1   */
> > +  (cond^ (eq (imagpart (IFN_ADD_OVERFLOW@2 @0 @1)) integer_zerop)
> > +        (realpart @2) integer_minus_onep)
> > +  (if (types_match (type, @0, @1))))
> > + (match (unsigned_integer_sat_add @0 @1)
> > +  /* SUM = ADD_OVERFLOW (X, Y)
> > +     SAT_U_ADD = IMAGPART (SUM) != 0 ? -1 : REALPART (SUM)  */
> > +  (cond^ (ne (imagpart (IFN_ADD_OVERFLOW@2 @0 @1)) integer_zerop)
> > +        integer_minus_onep (realpart @2))
> > +  (if (types_match (type, @0, @1))))
> > + (match (unsigned_integer_sat_add @0 @1)
> > +  /* SUM = ADD_OVERFLOW (X, IMM)
> > +     SAT_U_ADD = IMAGPART (SUM) != 0 ? -1 : REALPART (SUM)  */
> > +  (cond^ (ne (imagpart (IFN_ADD_OVERFLOW@2 @0 INTEGER_CST@1)) 
> > integer_zerop)
> > +        integer_minus_onep (realpart @2))
> > +  (if (types_match (type, @0) && int_fits_type_p (@1, type))))
> > + (match (unsigned_integer_sat_add @0 @1)
> > +  /* WIDEN_SUM = (WT)X + (WT)Y
> > +     SAT_U_ADD = WIDEN_SUM > MAX ? MAX : (NT)WIDEN_SUM  */
> > +  (cond^ (le (plus (convert@2 @0) (convert@3 @1)) INTEGER_CST@4)
> > +        (plus:c @0 @1) integer_minus_onep)
> > +  (if (types_match (type, @0, @1) && types_match (@2, @3))
> > +   (with
> > +    {
> > +     unsigned precision = TYPE_PRECISION (type);
> > +     unsigned widen_precision = TYPE_PRECISION (TREE_TYPE (@2));
> > +     wide_int max = wi::mask (precision, false, widen_precision);
> > +     wide_int c4 = wi::to_wide (@4);
> > +    }
> > +    (if (wi::eq_p (c4, max) && widen_precision > precision))))))
> > +
> > +/* Saturation sub for unsigned integer.  */
> > +(if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type))
> > + (match (unsigned_integer_sat_sub @0 @1)
> > +  /* SAT_U_SUB = X > Y ? X - Y : 0  */
> > +  (cond^ (gt @0 @1) (minus @0 @1) integer_zerop)
> > +  (if (types_match (type, @0, @1))))
> > + (match (unsigned_integer_sat_sub @0 @1)
> > +  /* SAT_U_SUB = X >= Y ? X - Y : 0  */
> > +  (cond^ (ge @0 @1) (convert? (minus (convert1? @0) (convert1? @1)))
> > +                   integer_zerop)
> > +  (if (TYPE_UNSIGNED (TREE_TYPE (@0)) && types_match (@0, @1))))
> > + (match (unsigned_integer_sat_sub @0 @1)
> > +  /* SAT_U_SUB = (X - Y) * (X > Y)  */
> > +  (mult:c (minus @0 @1) (convert (gt @0 @1)))
> > +  (if (types_match (type, @0, @1))))
> > + (match (unsigned_integer_sat_sub @0 @1)
> > +  /* SAT_U_SUB = (X - Y) * (X >= Y)  */
> > +  (mult:c (minus @0 @1) (convert (ge @0 @1)))
> > +  (if (types_match (type, @0, @1))))
> > + (match (unsigned_integer_sat_sub @0 @1)
> > +  /* DIFF = SUB_OVERFLOW (X, Y)
> > +     SAT_U_SUB = REALPART (DIFF) | (IMAGPART (DIFF) + (-1))  */
> > +  (bit_and:c (realpart (IFN_SUB_OVERFLOW@2 @0 @1))
> > +   (plus (imagpart @2) integer_minus_onep))
> > +  (if (types_match (type, @0, @1))))
> > + (match (unsigned_integer_sat_sub @0 @1)
> > +  /* DIFF = SUB_OVERFLOW (X, Y)
> > +     SAT_U_SUB = REALPART (DIFF) * (IMAGPART (DIFF) ^ (1))  */
> > +  (mult:c (realpart (IFN_SUB_OVERFLOW@2 @0 @1))
> > +   (bit_xor (imagpart @2) integer_onep))
> > +  (if (types_match (type, @0, @1))))
> > + (match (unsigned_integer_sat_sub @0 @1)
> > +  /* DIFF = SUB_OVERFLOW (X, Y)
> > +     SAT_U_SUB = IMAGPART (DIFF) == 0 ? REALPART (DIFF) : 0  */
> > +  (cond^ (eq (imagpart (IFN_SUB_OVERFLOW@2 @0 @1)) integer_zerop)
> > +        (realpart @2) integer_zerop)
> > +  (if (types_match (type, @0, @1))))
> > + (match (unsigned_integer_sat_sub @0 @1)
> > +  /* DIFF = SUB_OVERFLOW (X, Y)
> > +     SAT_U_SUB = IMAGPART (DIFF) != 0 ? 0 : REALPART (DIFF)  */
> > +  (cond^ (ne (imagpart (IFN_SUB_OVERFLOW@2 @0 @1)) integer_zerop)
> > +        integer_zerop (realpart @2))
> > +  (if (types_match (type, @0, @1))))
> > + (match (unsigned_integer_sat_sub @0 @1)
> > +  /* SAT_U_SUB = IMM > Y ? (IMM - Y) : 0
> > +     SAT_U_SUB = IMM >= Y ? (IMM - Y) : 0  */
> > +  (cond^ (le @1 INTEGER_CST@2) (minus INTEGER_CST@0 @1) integer_zerop)
> > +  (if (types_match (type, @1) && int_fits_type_p (@0, type))
> > +   (with
> > +    {
> > +     unsigned precision = TYPE_PRECISION (type);
> > +     wide_int max = wi::mask (precision, false, precision);
> > +     wide_int c0 = wi::to_wide (@0);
> > +     wide_int c2 = wi::to_wide (@2);
> > +     wide_int c2_add_1 = wi::add (c2, wi::uhwi (1, precision));
> > +     bool equal_p = wi::eq_p (c0, c2);
> > +     bool less_than_1_p = !wi::eq_p (c2, max) && wi::eq_p (c2_add_1, c0);
> > +    }
> > +    (if (equal_p || less_than_1_p)))))
> > + (match (unsigned_integer_sat_sub @0 @1)
> > +  /* SAT_U_SUB = (MAX - 1) >= Y ? ((MAX - 1) - Y) : 0  */
> > +  (cond^ (ne @1 INTEGER_CST@2) (minus INTEGER_CST@0 @1) integer_zerop)
> > +  (if (types_match (type, @1))
> > +   (with
> > +    {
> > +     unsigned precision = TYPE_PRECISION (type);
> > +     wide_int max = wi::mask (precision, false, precision);
> > +     wide_int c0 = wi::to_wide (@0);
> > +     wide_int c2 = wi::to_wide (@2);
> > +     wide_int c0_add_1 = wi::add (c0, wi::uhwi (1, precision));
> > +    }
> > +    (if (wi::eq_p (c2, max) && wi::eq_p (c0_add_1, max))))))
> > + (match (unsigned_integer_sat_sub @0 @1)
> > +  /* SAT_U_SUB = 1 >= Y ? (1 - Y) : 0  */
> > +  (cond^ (le @1 integer_onep@0) (bit_xor @1 integer_onep@0) integer_zerop)
> > +  (if (types_match (type, @1))))
> > + (match (unsigned_integer_sat_sub @0 @1)
> > +  /* SAT_U_SUB = X > IMM  ? (X - IMM) : 0.
> > +     SAT_U_SUB = X >= IMM ? (X - IMM) : 0.  */
> > +  (plus (max @0 INTEGER_CST@1) INTEGER_CST@2)
> > +  (if (types_match (type, @1) && int_fits_type_p (@1, type))
> > +   (with
> > +    {
> > +     unsigned precision = TYPE_PRECISION (type);
> > +     wide_int c1 = wi::to_wide (@1);
> > +     wide_int c2 = wi::to_wide (@2);
> > +     wide_int sum = wi::add (c1, c2);
> > +    }
> > +    (if (wi::eq_p (sum, wi::uhwi (0, precision))))))))
> > +
> > +(if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type))
> > + (match (unsigned_integer_narrow_clip @0)
> > +  /* SAT_U_TRUNC<NT>(MAX (0, X)) =
> > +            (UT)X & ~(NT)(-1) ? (-X) >> TYPE_PRECISION(X) - 1 : X
> > +
> > +     The gimple representation uses X > ~(NT)(-1) instead of
> > +     using & so match on gt instead of bit_and.  */
> > +  (convert (cond^ (gt (nop_convert? @0) INTEGER_CST@1)
> > +        (rshift:s (nop_convert? (negate (nop_convert? @0))) INTEGER_CST@2)
> > +        @0))
> > +  (if (! TYPE_UNSIGNED (TREE_TYPE (@0)))
> > +   (with
> > +    {
> > +     unsigned itype_precision = TYPE_PRECISION (TREE_TYPE (@0));
> > +     unsigned otype_precision = TYPE_PRECISION (type);
> > +     wide_int trunc_max = wi::mask (otype_precision, false, 
> > itype_precision);
> > +     wide_int int_cst_1 = wi::to_wide (@1, itype_precision);
> > +     wide_int int_cst_2 = wi::to_wide (@2, itype_precision);
> > +     wide_int shift_amount = wi::uhwi (itype_precision - 1,
> > +                                 itype_precision); // AKA itype_bits - 1
> > +     int cmp = 0;
> > +     cmp = wi::cmp (int_cst_2, shift_amount, TYPE_SIGN (TREE_TYPE (@0)));
> > +    }
> > +    (if (otype_precision < itype_precision && wi::eq_p (trunc_max,
> > +    int_cst_1) && (cmp >= 0)))))))
> > +
> > +/* Saturation truncate for unsigned integer.  */
> > +(if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type))
> > + (match (unsigned_integer_sat_trunc @0)
> > +  /* SAT_U_TRUNC = (NT)x | (NT)(-(X > (WT)(NT)(-1)))  */
> > +  (bit_ior:c (negate (convert (gt @0 INTEGER_CST@1))) (convert @0))
> > +  (if (TYPE_UNSIGNED (TREE_TYPE (@0)))
> > +   (with
> > +    {
> > +     unsigned itype_precision = TYPE_PRECISION (TREE_TYPE (@0));
> > +     unsigned otype_precision = TYPE_PRECISION (type);
> > +     wide_int trunc_max = wi::mask (otype_precision, false, 
> > itype_precision);
> > +     wide_int int_cst = wi::to_wide (@1, itype_precision);
> > +    }
> > +    (if (otype_precision < itype_precision && wi::eq_p (trunc_max, 
> > int_cst))))))
> > + (match (unsigned_integer_sat_trunc @0)
> > +  /* SAT_U_TRUNC = (NT)(MIN_EXPR (X, IMM))
> > +     If Op_0 def is MIN_EXPR and not single_use.  Aka below pattern:
> > +
> > +     _18 = MIN_EXPR <left_8, 4294967295>; // op_0 def
> > +     iftmp.0_11 = (unsigned int) _18;     // op_0
> > +     stream.avail_out = iftmp.0_11;
> > +     left_37 = left_8 - _18;              // op_0 use
> > +
> > +     Transfer to .SAT_TRUNC will have MIN_EXPR still live.  Then the 
> > backend
> > +     (for example x86/riscv) will have 2-3 more insns generation for 
> > .SAT_TRUNC
> > +     besides the MIN_EXPR.  Thus,  keep the normal truncation as is should 
> > be
> > +     the better choose.  */
> > +  (convert (min@2 @0 INTEGER_CST@1))
> > +  (if (TYPE_UNSIGNED (TREE_TYPE (@0)) && single_use (@2))
> > +   (with
> > +    {
> > +     unsigned itype_precision = TYPE_PRECISION (TREE_TYPE (@0));
> > +     unsigned otype_precision = TYPE_PRECISION (type);
> > +     wide_int trunc_max = wi::mask (otype_precision, false, 
> > itype_precision);
> > +     wide_int int_cst = wi::to_wide (@1, itype_precision);
> > +    }
> > +    (if (otype_precision < itype_precision && wi::eq_p (trunc_max, 
> > int_cst))))))
> > + (match (unsigned_integer_sat_trunc @0)
> > +  /* SAT_U_TRUNC = (NT)X | ((NT)(X <= (WT)-1) + (NT)-1)  */
> > +  (bit_ior:c (plus:c (convert (le @0 INTEGER_CST@1)) INTEGER_CST@2)
> > +            (convert @0))
> > +  (if (TYPE_UNSIGNED (TREE_TYPE (@0)))
> > +   (with
> > +    {
> > +     unsigned itype_precision = TYPE_PRECISION (TREE_TYPE (@0));
> > +     unsigned otype_precision = TYPE_PRECISION (type);
> > +     wide_int trunc_max = wi::mask (otype_precision, false, 
> > itype_precision);
> > +     wide_int max = wi::mask (otype_precision, false, otype_precision);
> > +     wide_int int_cst_1 = wi::to_wide (@1);
> > +     wide_int int_cst_2 = wi::to_wide (@2);
> > +    }
> > +    (if (wi::eq_p (trunc_max, int_cst_1) && wi::eq_p (max, int_cst_2)))))))
> > +
> > +(if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type))
> > + /* SAT_VAL = (-(T)(X < 0) ^ MAX)  */
> > + (match (signed_integer_sat_val @0)
> > +  (bit_xor:c (nop_convert? (negate
> > +                           (nop_convert? (convert (lt @0 integer_zerop)))))
> > +            max_value)))
> > +
> > +/* Saturation add for signed integer.  */
> > +(if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type))
> > + (match (signed_integer_sat_add @0 @1)
> > +  /* T SUM = (T)((UT)X + (UT)Y)
> > +     SAT_S_ADD = (X ^ SUM) & !(X ^ Y) < 0 ? (-(T)(X < 0) ^ MAX) : SUM  */
> > +  (cond^ (lt (bit_and:c (bit_xor:c @0 (nop_convert@2 (plus (nop_convert @0)
> > +                                                          (nop_convert 
> > @1))))
> > +                       (bit_not (bit_xor:c @0 @1)))
> > +            integer_zerop)
> > +        (signed_integer_sat_val @0)
> > +        @2))
> > + (match (signed_integer_sat_add @0 @1)
> > +  /* T SUM = (T)((UT)X + (UT)Y)
> > +     SAT_S_ADD = (X ^ SUM) & !(X ^ Y) >= 0 ? SUM : (-(T)(X < 0) ^ MAX)  */
> > +  (cond^ (ge (bit_and:c (bit_xor @0 (nop_convert@2 (plus (nop_convert @0)
> > +                                                        (nop_convert @1))))
> > +                       (bit_not (bit_xor:c @0 @1)))
> > +            integer_zerop)
> > +        @2
> > +        (bit_xor:c (negate (convert (lt @0 integer_zerop))) max_value)))
> > + (match (signed_integer_sat_add @0 @1)
> > +  /* T SUM = (T)((UT)X + (UT)Y)
> > +     SAT_S_ADD = (X ^ Y) < 0 && (X ^ SUM) >= 0 ? (-(T)(X < 0) ^ MAX) : SUM 
> >  */
> > +  (cond^ (bit_and:c (lt (bit_xor @0 (nop_convert@2 (plus (nop_convert @0)
> > +                                                        (nop_convert @1))))
> > +                       integer_zerop)
> > +                   (ge (bit_xor:c @0 @1) integer_zerop))
> > +        (signed_integer_sat_val @0)
> > +        @2))
> > + (match (signed_integer_sat_add @0 @1)
> > +  /* T SUM = (T)((UT)X + (UT)IMM)
> > +     SAT_S_ADD = (X ^ SUM) < 0 && (X ^ IMM) >= 0 ? (-(T)(X < 0) ^ MAX) : 
> > SUM  */
> > +  (cond^ (bit_and:c (lt (bit_xor @0 (nop_convert@2 (plus (nop_convert @0)
> > +                                                        INTEGER_CST@1)))
> > +                       integer_zerop)
> > +                   (ge (bit_xor:c @0 INTEGER_CST@3) integer_zerop))
> > +        (signed_integer_sat_val @0)
> > +        @2)
> > +  (if (wi::eq_p (wi::to_wide (@1), wi::to_wide (@3)))))
> > + (match (signed_integer_sat_add @0 @1)
> > +   /* SUM = .ADD_OVERFLOW (X, Y)
> > +      SAT_S_ADD = IMAGPART_EXPR (SUM) != 0 ? (-(T)(X < 0) ^ MAX) : SUM  */
> > +  (cond^ (ne (imagpart (IFN_ADD_OVERFLOW:c@2 @0 @1)) integer_zerop)
> > +        (signed_integer_sat_val @0)
> > +        (realpart @2)))
> > + (match (signed_integer_sat_add @0 @1)
> > +  /* T SUM = (T)((UT)X + (UT)Y)
> > +     SAT_S_ADD = (X ^ SUM) < 0 & ~((X ^ Y) < 0) ? (-(T)(X < 0) ^ MAX) : 
> > SUM  */
> > +  (cond^ (bit_and:c (lt (bit_xor @0 (nop_convert@2 (plus (nop_convert @0)
> > +                                                        (nop_convert @1))))
> > +                       integer_zerop)
> > +                   (bit_not (lt (bit_xor:c @0 @1) integer_zerop)))
> > +        (signed_integer_sat_val @0)
> > +        @2))
> > + (match (signed_integer_sat_add @0 @1)
> > +  /* T SUM = (T)((UT)X + (UT)IMM);
> > +     SAT_S_ADD = (X ^ IMM) < 0 ? SUM : (X ^ SUM) >= 0 ? SUM
> > +                                                     : (x < 0) ? MIN : MAX 
> >  */
> > +  (cond^ (lt (bit_and:c (bit_xor:c @0 (nop_convert@2 (plus (nop_convert @0)
> > +                                                          INTEGER_CST@1)))
> > +                       (bit_xor:c @0 INTEGER_CST@3)) integer_zerop)
> > +        (signed_integer_sat_val @0)
> > +        @2)
> > +  (if (wi::bit_and (wi::to_wide (@1), wi::to_wide (@3)) == 0)))
> > +
> > +(match (signed_integer_sat_add @0 @1)
> > +  /* T SUM = (T)((UT)X + (UT)-1);
> > +     SAT_S_ADD = (X ^ -1) < 0 ? SUM : (X ^ SUM) >= 0 ? SUM
> > +                                                     : (x < 0) ? MIN : MAX 
> >  */
> > +  (convert (cond^ (lt (bit_and:c @0 (nop_convert (negate (nop_convert 
> > @0))))
> > +             integer_zerop)
> > +        INTEGER_CST@2
> > +        (plus (nop_convert @0) integer_all_onesp@1)))
> > +   (with
> > +    {
> > +     unsigned precision = TYPE_PRECISION (type);
> > +     wide_int c1 = wi::to_wide (@1);
> > +     wide_int c2 = wi::to_wide (@2);
> > +     wide_int sum = wi::add (c1, c2);
> > +    }
> > +    (if (wi::eq_p (sum, wi::max_value (precision, SIGNED))))))
> > +
> > +(match (signed_integer_sat_add @0 @1)
> > +  /* T SUM = (T)((UT)X + (UT)IMM)
> > +     SAT_S_ADD = (X ^ SUM) < 0 && (X ^ IMM) >= 0 ? (-(T)(X < 0) ^ MAX) : 
> > SUM  */
> > +   (cond^ (ge (bit_ior:c (bit_xor:c @0 INTEGER_CST@1)
> > +                       (bit_not (bit_xor:c @0 (nop_convert@2 (plus 
> > (nop_convert @0)
> > +                       INTEGER_CST@3)))))
> > +                   integer_zerop)
> > +           (signed_integer_sat_val @0)
> > +           @2)
> > +   (if (wi::eq_p (wi::to_wide (@1), wi::to_wide (@3))))))
> > +
> > +/* Saturation sub for signed integer.  */
> > +(if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type))
> > + (match (signed_integer_sat_sub @0 @1)
> > +  /* T Z = (T)((UT)X - (UT)Y);
> > +     SAT_S_SUB = (X ^ Y) & (X ^ Z) < 0 ? (-(T)(X < 0) ^ MAX) : Z  */
> > +  (cond^ (lt (bit_and:c (bit_xor:c @0 @1)
> > +                       (bit_xor @0 (nop_convert@2 (minus (nop_convert @0)
> > +                                                         (nop_convert 
> > @1)))))
> > +            integer_zerop)
> > +        (signed_integer_sat_val @0)
> > +        @2))
> > + (match (signed_integer_sat_sub @0 @1)
> > +  /* T Z = (T)((UT)X - (UT)Y);
> > +     SAT_S_SUB = (X ^ Y) & (X ^ Z) >= 0 ? Z : (-(T)(X < 0) ^ MAX)  */
> > +  (cond^ (ge (bit_and:c (bit_xor:c @0 @1)
> > +                       (bit_xor @0 (nop_convert@2 (minus (nop_convert @0)
> > +                                                         (nop_convert 
> > @1)))))
> > +            integer_zerop)
> > +        @2
> > +        (signed_integer_sat_val @0)))
> > + (match (signed_integer_sat_sub @0 @1)
> > +  /* T Z = (T)((UT)X - (UT)Y);
> > +     SAT_S_SUB = (X ^ Y) < 0 & (X ^ Z) < 0 ? (-(T)(X < 0) ^ MAX) : Z  */
> > +  (cond^ (bit_and:c (lt (bit_xor @0 (nop_convert@2 (minus (nop_convert @0)
> > +                                                         (nop_convert 
> > @1))))
> > +                       integer_zerop)
> > +                   (lt (bit_xor:c @0 @1) integer_zerop))
> > +        (signed_integer_sat_val @0)
> > +        @2))
> > + (match (signed_integer_sat_sub @0 @1)
> > +  /* Z = .SUB_OVERFLOW (X, Y)
> > +     SAT_S_SUB = IMAGPART (Z) != 0 ? (-(T)(X < 0) ^ MAX) : REALPART (Z)  */
> > +  (cond^ (ne (imagpart (IFN_SUB_OVERFLOW@2 @0 @1)) integer_zerop)
> > +        (signed_integer_sat_val @0)
> > +        (realpart @2))
> > +  (if (types_match (type, @0, @1)))))
> > +
> > +/* Saturation truncate for signed integer.  */
> > +(if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type))
> > + (match (signed_integer_sat_trunc @0)
> > +  /* SAT_S_TRUNC(X) = (unsigned)X + NT_MAX + 1  > Unsigned_MAX ? (NT)X  */
> > +  (cond^ (gt (plus:c (convert@4 @0) INTEGER_CST@1) INTEGER_CST@2)
> > +        (bit_xor:c (nop_convert?
> > +                    (negate (nop_convert? (convert (lt @0 
> > integer_zerop)))))
> > +                   INTEGER_CST@3)
> > +        (convert @0))
> > +  (if (!TYPE_UNSIGNED (TREE_TYPE (@0)) && TYPE_UNSIGNED (TREE_TYPE (@4)))
> > +   (with
> > +    {
> > +     unsigned itype_prec = TYPE_PRECISION (TREE_TYPE (@0));
> > +     unsigned otype_prec = TYPE_PRECISION (type);
> > +     wide_int offset = wi::uhwi (HOST_WIDE_INT_1U << (otype_prec - 1),
> > +                                itype_prec); // Aka 128 for int8_t
> > +     wide_int limit_0 = wi::mask (otype_prec, false, itype_prec); // Aka 
> > 255
> > +     wide_int limit_1 = wi::uhwi ((HOST_WIDE_INT_1U << otype_prec) - 3,
> > +                                 itype_prec); // Aka 253
> > +     wide_int limit_2 = wi::uhwi ((HOST_WIDE_INT_1U << otype_prec) - 2,
> > +                                 itype_prec); // Aka 254
> > +     wide_int otype_max = wi::mask (otype_prec - 1, false, otype_prec);
> > +     wide_int itype_max = wi::mask (otype_prec - 1, false, itype_prec);
> > +     wide_int int_cst_1 = wi::to_wide (@1);
> > +     wide_int int_cst_2 = wi::to_wide (@2);
> > +     wide_int int_cst_3 = wi::to_wide (@3);
> > +    }
> > +    (if (((wi::eq_p (int_cst_1, offset) && wi::eq_p (int_cst_2, limit_0))
> > +        || (wi::eq_p (int_cst_1, itype_max) && wi::eq_p (int_cst_2, 
> > limit_2))
> > +        || (wi::eq_p (int_cst_1, offset) && wi::eq_p (int_cst_2, limit_2))
> > +        || (wi::eq_p (int_cst_1, itype_max) && wi::eq_p (int_cst_2, 
> > limit_1)))
> > +        && wi::eq_p (int_cst_3, otype_max)))))))
> > +
> > +/* Saturation mult for unsigned integer.  */
> > +(if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type))
> > + (for mult_op (mult widen_mult)
> > +  (match (usmul_widen_mult @0 @1)
> > +   (mult_op:c (convert@2 @0) (convert @1))
> > +    (if (types_match (@0, @1) && TYPE_UNSIGNED (TREE_TYPE (@0)))
> > +     (with
> > +      {
> > +       unsigned prec = TYPE_PRECISION (TREE_TYPE (@0));
> > +       unsigned cvt2_prec = TYPE_PRECISION (TREE_TYPE (@2));
> > +       bool widen_cvt_p = cvt2_prec > prec;
> > +      }
> > +      (if (widen_cvt_p))))))
> > + (match (usmul_widen_mult @0 @1)
> > +  (widen_mult:c @0 @1)
> > +   (if (types_match (@0, @1))))
> > + (match (unsigned_integer_sat_mul @0 @1)
> > +  /* SAT_U_MUL (X, Y) = {
> > +       WT x = (WT)a * (WT)b;
> > +       T max = -1;
> > +       if (x > (WT)(max))
> > +        return max;
> > +       else
> > +        return (T)x;
> > +     }
> > +     while WT is uint128_t, T is uint8_t, uint16_t, uint32_t or uint64_t.  
> > */
> > +  (convert (min (usmul_widen_mult@3 @0 @1) INTEGER_CST@2))
> > +  (if (types_match (type, @0, @1))
> > +   (with
> > +    {
> > +      unsigned prec = TYPE_PRECISION (type);
> > +      unsigned widen_prec = TYPE_PRECISION (TREE_TYPE (@3));
> > +      wide_int max = wi::mask (prec, false, widen_prec);
> > +      bool c2_is_max_p = wi::eq_p (wi::to_wide (@2), max);
> > +    }
> > +    (if (c2_is_max_p)))))
> > +  (match (unsigned_integer_sat_mul @0 @1)
> > +   /* SAT_U_MUL (X, Y) = {
> > +       T result;
> > +       if (__builtin_mul_overflow (X, Y, &result))
> > +         return -1;
> > +       else
> > +         return result;
> > +      }
> > +      while T can be uint8_t, uint16_t, uint32_t and uint64_t.  */
> > +   (cond^ (ne (imagpart (IFN_MUL_OVERFLOW:c@2 @0 @1)) integer_zerop)
> > +          integer_minus_onep (realpart @2))
> > +   (if (types_match (type, @0, @1))))
> > +  (match (unsigned_integer_sat_mul @0 @1)
> > +   /* SAT_U_MUL (X, Y) = {
> > +       WT x = (WT)a * (WT)b;
> > +       if ((x >> sizeof(a) * 8) == 0)
> > +         return (T)x;
> > +       else
> > +         return (T)-1;
> > +      }
> > +      while WT is uint128_t, T is uint8_t, uint16_t, uint32_t or uint64_t. 
> >  */
> > +   (convert (cond^ (eq (rshift (mult:c@3 (convert @0) (convert @1))
> > +                              INTEGER_CST@2)
> > +                      integer_zerop)
> > +                  @3 INTEGER_CST@4))
> > +   (if (types_match (type, @0, @1))
> > +    (with
> > +     {
> > +      unsigned prec = TYPE_PRECISION (type);
> > +      unsigned widen_prec = TYPE_PRECISION (TREE_TYPE (@3));
> > +      wide_int c4 = wi::to_wide (@4);
> > +      wide_int max = wi::mask (prec, false, widen_prec);
> > +      bool c4_is_max_p = wi::eq_p (c4, max);
> > +      unsigned c2 = tree_to_uhwi (@2);
> > +      bool c2_is_type_precision_p = c2 == prec;
> > +     }
> > +     (if (widen_prec > prec && c2_is_type_precision_p && c4_is_max_p)))))
> > +  (match (unsigned_integer_sat_mul @0 @1)
> > +   /* SAT_U_MUL (X, Y) = {
> > +       WT x = (WT)a * (WT)b;
> > +       NT hi = x >> (sizeof(NT) * 8);
> > +       NT lo = (NT)x;
> > +       return lo | -!!hi;
> > +      } while WT is uint128_t, uint64_t, uint32_t, uint16_t,
> > +       and T is uint64_t, uint32_t, uint16_t, uint8_t.  */
> > +   (bit_ior:c
> > +    (convert?
> > +     (negate
> > +      (convert (ne (convert2? (rshift @3 INTEGER_CST@2)) integer_zerop))))
> > +    (convert (usmul_widen_mult@3 @0 @1)))
> > +   (if (types_match (type, @0, @1))
> > +    (with
> > +     {
> > +      unsigned prec = TYPE_PRECISION (type);
> > +      bool c2_is_type_precision_p = tree_to_uhwi (@2) == prec;
> > +     }
> > +     (if (c2_is_type_precision_p)))))
> > +  (match (unsigned_integer_sat_mul @0 @1)
> > +   /* SAT_U_MUL (X, Y) = {
> > +       WT x = (WT)a * (WT)b;
> > +       NT max = -1;
> > +       bool overflow_p = x > (WT)max;
> > +       return -(NT)(overflow_p) | (NT)x;
> > +      } while WT is uint128_t, uint64_t, uint32_t, uint16_t,
> > +       and T is uint64_t, uint32_t, uint16_t, uint8_t.  */
> > +   (bit_ior:c (negate (convert (gt @3 INTEGER_CST@2)))
> > +             (convert (usmul_widen_mult@3 @0 @1)))
> > +   (if (types_match (type, @0, @1))
> > +    (with
> > +     {
> > +      unsigned prec = TYPE_PRECISION (type);
> > +      unsigned widen_prec = TYPE_PRECISION (TREE_TYPE (@3));
> > +      wide_int max = wi::mask (prec, false, widen_prec);
> > +      bool c2_is_max_p = wi::eq_p (wi::to_wide (@2), max);
> > +     }
> > +     (if (c2_is_max_p)))))
> > +)
> > diff --git a/gcc/match.pd b/gcc/match.pd
> > index 7db8ce7580f..4d8cdd68d4c 100644
> > --- a/gcc/match.pd
> > +++ b/gcc/match.pd
> > @@ -3321,561 +3321,6 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> >         || POINTER_TYPE_P (itype))
> >        && wi::eq_p (wi::to_wide (int_cst), wi::max_value (itype))))))
> >
> > -#if GIMPLE
> > -/* Saturation add for unsigned integer.  */
> > -(if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type))
> > - (match (usadd_overflow_mask @0 @1)
> > -  /* SAT_U_ADD = (X + Y) | -(X > (X + Y)).
> > -     Overflow_Mask = -(X > (X + Y)).  */
> > -  (negate (convert (gt @0 (plus:c @0 @1))))
> > -  (if (types_match (type, @0, @1))))
> > - (match (usadd_overflow_mask @0 @1)
> > -  /* SAT_U_ADD = (X + Y) | -(X > (X + Y)).
> > -     Overflow_Mask = -((X + Y) < X).  */
> > -  (negate (convert (lt (plus:c @0 @1) @0)))
> > -  (if (types_match (type, @0, @1))))
> > - (match (unsigned_integer_sat_add @0 @1)
> > -  /* SAT_U_ADD = (X + Y) | Overflow_Mask  */
> > -  (bit_ior:c (plus:c @0 @1) (usadd_overflow_mask @0 @1))
> > -  (if (types_match (type, @0, @1))))
> > - (match (unsigned_integer_sat_add @0 @1)
> > -  /* SAT_U_ADD = (X + Y) >= X ? (X + Y) : -1  */
> > -  (cond^ (ge (plus:c@2 @0 @1) @0) @2 integer_minus_onep)
> > -  (if (types_match (type, @0, @1))))
> > - (match (unsigned_integer_sat_add @0 @1)
> > -  /* SAT_U_ADD = (X + Y) < X ? -1 : (X + Y)  */
> > -  (cond^ (lt (plus:c@2 @0 @1) @0) integer_minus_onep @2)
> > -  (if (types_match (type, @0, @1))))
> > - (match (unsigned_integer_sat_add @0 @1)
> > -  /* SAT_U_ADD = X <= (X + Y) ? (X + Y) : -1  */
> > -  (cond^ (le @0 (plus:c@2 @0 @1)) @2 integer_minus_onep)
> > -  (if (types_match (type, @0, @1))))
> > - (match (unsigned_integer_sat_add @0 @1)
> > -  /* SAT_U_ADD = X > (X + Y) ? -1 : (X + Y)  */
> > -  (cond^ (gt @0 (plus:c@2 @0 @1)) integer_minus_onep @2)
> > -  (if (types_match (type, @0, @1))))
> > - (match (unsigned_integer_sat_add @0 @1)
> > -  /* SAT_U_ADD = (X + IMM) >= x ? (X + IMM) : -1  */
> > -  (plus (min @0 INTEGER_CST@2) INTEGER_CST@1)
> > -  (if (types_match (type, @0, @1))
> > -   (with
> > -    {
> > -     unsigned precision = TYPE_PRECISION (type);
> > -     wide_int cst_1 = wi::to_wide (@1);
> > -     wide_int cst_2 = wi::to_wide (@2);
> > -     wide_int max = wi::mask (precision, false, precision);
> > -     wide_int sum = wi::add (cst_1, cst_2);
> > -    }
> > -    (if (wi::eq_p (max, sum))))))
> > - (match (unsigned_integer_sat_add @0 @1)
> > -  /* SUM = ADD_OVERFLOW (X, Y)
> > -     SAT_U_ADD = REALPART (SUM) | -IMAGPART (SUM)   */
> > -  (bit_ior:c (realpart (IFN_ADD_OVERFLOW@2 @0 @1)) (negate (imagpart @2)))
> > -  (if (types_match (type, @0, @1))))
> > - (match (unsigned_integer_sat_add @0 @1)
> > -  /* SUM = ADD_OVERFLOW (X, Y)
> > -     SAT_U_ADD = REALPART (SUM) | -(IMAGPART (SUM) != 0)   */
> > -  (bit_ior:c (realpart (IFN_ADD_OVERFLOW@2 @0 @1))
> > -            (negate (convert (ne (imagpart @2) integer_zerop))))
> > -  (if (types_match (type, @0, @1))))
> > - (match (unsigned_integer_sat_add @0 @1)
> > -  /* SUM = ADD_OVERFLOW (X, Y)
> > -     SAT_U_ADD = IMAGPART (SUM) == 0 ? REALPART (SUM) : -1   */
> > -  (cond^ (eq (imagpart (IFN_ADD_OVERFLOW@2 @0 @1)) integer_zerop)
> > -        (realpart @2) integer_minus_onep)
> > -  (if (types_match (type, @0, @1))))
> > - (match (unsigned_integer_sat_add @0 @1)
> > -  /* SUM = ADD_OVERFLOW (X, Y)
> > -     SAT_U_ADD = IMAGPART (SUM) != 0 ? -1 : REALPART (SUM)  */
> > -  (cond^ (ne (imagpart (IFN_ADD_OVERFLOW@2 @0 @1)) integer_zerop)
> > -        integer_minus_onep (realpart @2))
> > -  (if (types_match (type, @0, @1))))
> > - (match (unsigned_integer_sat_add @0 @1)
> > -  /* SUM = ADD_OVERFLOW (X, IMM)
> > -     SAT_U_ADD = IMAGPART (SUM) != 0 ? -1 : REALPART (SUM)  */
> > -  (cond^ (ne (imagpart (IFN_ADD_OVERFLOW@2 @0 INTEGER_CST@1)) 
> > integer_zerop)
> > -        integer_minus_onep (realpart @2))
> > -  (if (types_match (type, @0) && int_fits_type_p (@1, type))))
> > - (match (unsigned_integer_sat_add @0 @1)
> > -  /* WIDEN_SUM = (WT)X + (WT)Y
> > -     SAT_U_ADD = WIDEN_SUM > MAX ? MAX : (NT)WIDEN_SUM  */
> > -  (cond^ (le (plus (convert@2 @0) (convert@3 @1)) INTEGER_CST@4)
> > -        (plus:c @0 @1) integer_minus_onep)
> > -  (if (types_match (type, @0, @1) && types_match (@2, @3))
> > -   (with
> > -    {
> > -     unsigned precision = TYPE_PRECISION (type);
> > -     unsigned widen_precision = TYPE_PRECISION (TREE_TYPE (@2));
> > -     wide_int max = wi::mask (precision, false, widen_precision);
> > -     wide_int c4 = wi::to_wide (@4);
> > -    }
> > -    (if (wi::eq_p (c4, max) && widen_precision > precision))))))
> > -
> > -/* Saturation sub for unsigned integer.  */
> > -(if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type))
> > - (match (unsigned_integer_sat_sub @0 @1)
> > -  /* SAT_U_SUB = X > Y ? X - Y : 0  */
> > -  (cond^ (gt @0 @1) (minus @0 @1) integer_zerop)
> > -  (if (types_match (type, @0, @1))))
> > - (match (unsigned_integer_sat_sub @0 @1)
> > -  /* SAT_U_SUB = X >= Y ? X - Y : 0  */
> > -  (cond^ (ge @0 @1) (convert? (minus (convert1? @0) (convert1? @1)))
> > -                   integer_zerop)
> > -  (if (TYPE_UNSIGNED (TREE_TYPE (@0)) && types_match (@0, @1))))
> > - (match (unsigned_integer_sat_sub @0 @1)
> > -  /* SAT_U_SUB = (X - Y) * (X > Y)  */
> > -  (mult:c (minus @0 @1) (convert (gt @0 @1)))
> > -  (if (types_match (type, @0, @1))))
> > - (match (unsigned_integer_sat_sub @0 @1)
> > -  /* SAT_U_SUB = (X - Y) * (X >= Y)  */
> > -  (mult:c (minus @0 @1) (convert (ge @0 @1)))
> > -  (if (types_match (type, @0, @1))))
> > - (match (unsigned_integer_sat_sub @0 @1)
> > -  /* DIFF = SUB_OVERFLOW (X, Y)
> > -     SAT_U_SUB = REALPART (DIFF) | (IMAGPART (DIFF) + (-1))  */
> > -  (bit_and:c (realpart (IFN_SUB_OVERFLOW@2 @0 @1))
> > -   (plus (imagpart @2) integer_minus_onep))
> > -  (if (types_match (type, @0, @1))))
> > - (match (unsigned_integer_sat_sub @0 @1)
> > -  /* DIFF = SUB_OVERFLOW (X, Y)
> > -     SAT_U_SUB = REALPART (DIFF) * (IMAGPART (DIFF) ^ (1))  */
> > -  (mult:c (realpart (IFN_SUB_OVERFLOW@2 @0 @1))
> > -   (bit_xor (imagpart @2) integer_onep))
> > -  (if (types_match (type, @0, @1))))
> > - (match (unsigned_integer_sat_sub @0 @1)
> > -  /* DIFF = SUB_OVERFLOW (X, Y)
> > -     SAT_U_SUB = IMAGPART (DIFF) == 0 ? REALPART (DIFF) : 0  */
> > -  (cond^ (eq (imagpart (IFN_SUB_OVERFLOW@2 @0 @1)) integer_zerop)
> > -        (realpart @2) integer_zerop)
> > -  (if (types_match (type, @0, @1))))
> > - (match (unsigned_integer_sat_sub @0 @1)
> > -  /* DIFF = SUB_OVERFLOW (X, Y)
> > -     SAT_U_SUB = IMAGPART (DIFF) != 0 ? 0 : REALPART (DIFF)  */
> > -  (cond^ (ne (imagpart (IFN_SUB_OVERFLOW@2 @0 @1)) integer_zerop)
> > -        integer_zerop (realpart @2))
> > -  (if (types_match (type, @0, @1))))
> > - (match (unsigned_integer_sat_sub @0 @1)
> > -  /* SAT_U_SUB = IMM > Y ? (IMM - Y) : 0
> > -     SAT_U_SUB = IMM >= Y ? (IMM - Y) : 0  */
> > -  (cond^ (le @1 INTEGER_CST@2) (minus INTEGER_CST@0 @1) integer_zerop)
> > -  (if (types_match (type, @1) && int_fits_type_p (@0, type))
> > -   (with
> > -    {
> > -     unsigned precision = TYPE_PRECISION (type);
> > -     wide_int max = wi::mask (precision, false, precision);
> > -     wide_int c0 = wi::to_wide (@0);
> > -     wide_int c2 = wi::to_wide (@2);
> > -     wide_int c2_add_1 = wi::add (c2, wi::uhwi (1, precision));
> > -     bool equal_p = wi::eq_p (c0, c2);
> > -     bool less_than_1_p = !wi::eq_p (c2, max) && wi::eq_p (c2_add_1, c0);
> > -    }
> > -    (if (equal_p || less_than_1_p)))))
> > - (match (unsigned_integer_sat_sub @0 @1)
> > -  /* SAT_U_SUB = (MAX - 1) >= Y ? ((MAX - 1) - Y) : 0  */
> > -  (cond^ (ne @1 INTEGER_CST@2) (minus INTEGER_CST@0 @1) integer_zerop)
> > -  (if (types_match (type, @1))
> > -   (with
> > -    {
> > -     unsigned precision = TYPE_PRECISION (type);
> > -     wide_int max = wi::mask (precision, false, precision);
> > -     wide_int c0 = wi::to_wide (@0);
> > -     wide_int c2 = wi::to_wide (@2);
> > -     wide_int c0_add_1 = wi::add (c0, wi::uhwi (1, precision));
> > -    }
> > -    (if (wi::eq_p (c2, max) && wi::eq_p (c0_add_1, max))))))
> > - (match (unsigned_integer_sat_sub @0 @1)
> > -  /* SAT_U_SUB = 1 >= Y ? (1 - Y) : 0  */
> > -  (cond^ (le @1 integer_onep@0) (bit_xor @1 integer_onep@0) integer_zerop)
> > -  (if (types_match (type, @1))))
> > - (match (unsigned_integer_sat_sub @0 @1)
> > -  /* SAT_U_SUB = X > IMM  ? (X - IMM) : 0.
> > -     SAT_U_SUB = X >= IMM ? (X - IMM) : 0.  */
> > -  (plus (max @0 INTEGER_CST@1) INTEGER_CST@2)
> > -  (if (types_match (type, @1) && int_fits_type_p (@1, type))
> > -   (with
> > -    {
> > -     unsigned precision = TYPE_PRECISION (type);
> > -     wide_int c1 = wi::to_wide (@1);
> > -     wide_int c2 = wi::to_wide (@2);
> > -     wide_int sum = wi::add (c1, c2);
> > -    }
> > -    (if (wi::eq_p (sum, wi::uhwi (0, precision))))))))
> > -
> > -(if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type))
> > - (match (unsigned_integer_narrow_clip @0)
> > -  /* SAT_U_TRUNC<NT>(MAX (0, X)) =
> > -            (UT)X & ~(NT)(-1) ? (-X) >> TYPE_PRECISION(X) - 1 : X
> > -
> > -     The gimple representation uses X > ~(NT)(-1) instead of
> > -     using & so match on gt instead of bit_and.  */
> > -  (convert (cond^ (gt (nop_convert? @0) INTEGER_CST@1)
> > -        (rshift:s (nop_convert? (negate (nop_convert? @0))) INTEGER_CST@2)
> > -        @0))
> > -  (if (! TYPE_UNSIGNED (TREE_TYPE (@0)))
> > -   (with
> > -    {
> > -     unsigned itype_precision = TYPE_PRECISION (TREE_TYPE (@0));
> > -     unsigned otype_precision = TYPE_PRECISION (type);
> > -     wide_int trunc_max = wi::mask (otype_precision, false, 
> > itype_precision);
> > -     wide_int int_cst_1 = wi::to_wide (@1, itype_precision);
> > -     wide_int int_cst_2 = wi::to_wide (@2, itype_precision);
> > -     wide_int shift_amount = wi::uhwi (itype_precision - 1,
> > -                                 itype_precision); // AKA itype_bits - 1
> > -     int cmp = 0;
> > -     cmp = wi::cmp (int_cst_2, shift_amount, TYPE_SIGN (TREE_TYPE (@0)));
> > -    }
> > -    (if (otype_precision < itype_precision && wi::eq_p (trunc_max,
> > -    int_cst_1) && (cmp >= 0)))))))
> > -
> > -/* Saturation truncate for unsigned integer.  */
> > -(if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type))
> > - (match (unsigned_integer_sat_trunc @0)
> > -  /* SAT_U_TRUNC = (NT)x | (NT)(-(X > (WT)(NT)(-1)))  */
> > -  (bit_ior:c (negate (convert (gt @0 INTEGER_CST@1))) (convert @0))
> > -  (if (TYPE_UNSIGNED (TREE_TYPE (@0)))
> > -   (with
> > -    {
> > -     unsigned itype_precision = TYPE_PRECISION (TREE_TYPE (@0));
> > -     unsigned otype_precision = TYPE_PRECISION (type);
> > -     wide_int trunc_max = wi::mask (otype_precision, false, 
> > itype_precision);
> > -     wide_int int_cst = wi::to_wide (@1, itype_precision);
> > -    }
> > -    (if (otype_precision < itype_precision && wi::eq_p (trunc_max, 
> > int_cst))))))
> > - (match (unsigned_integer_sat_trunc @0)
> > -  /* SAT_U_TRUNC = (NT)(MIN_EXPR (X, IMM))
> > -     If Op_0 def is MIN_EXPR and not single_use.  Aka below pattern:
> > -
> > -     _18 = MIN_EXPR <left_8, 4294967295>; // op_0 def
> > -     iftmp.0_11 = (unsigned int) _18;     // op_0
> > -     stream.avail_out = iftmp.0_11;
> > -     left_37 = left_8 - _18;              // op_0 use
> > -
> > -     Transfer to .SAT_TRUNC will have MIN_EXPR still live.  Then the 
> > backend
> > -     (for example x86/riscv) will have 2-3 more insns generation for 
> > .SAT_TRUNC
> > -     besides the MIN_EXPR.  Thus,  keep the normal truncation as is should 
> > be
> > -     the better choose.  */
> > -  (convert (min@2 @0 INTEGER_CST@1))
> > -  (if (TYPE_UNSIGNED (TREE_TYPE (@0)) && single_use (@2))
> > -   (with
> > -    {
> > -     unsigned itype_precision = TYPE_PRECISION (TREE_TYPE (@0));
> > -     unsigned otype_precision = TYPE_PRECISION (type);
> > -     wide_int trunc_max = wi::mask (otype_precision, false, 
> > itype_precision);
> > -     wide_int int_cst = wi::to_wide (@1, itype_precision);
> > -    }
> > -    (if (otype_precision < itype_precision && wi::eq_p (trunc_max, 
> > int_cst))))))
> > - (match (unsigned_integer_sat_trunc @0)
> > -  /* SAT_U_TRUNC = (NT)X | ((NT)(X <= (WT)-1) + (NT)-1)  */
> > -  (bit_ior:c (plus:c (convert (le @0 INTEGER_CST@1)) INTEGER_CST@2)
> > -            (convert @0))
> > -  (if (TYPE_UNSIGNED (TREE_TYPE (@0)))
> > -   (with
> > -    {
> > -     unsigned itype_precision = TYPE_PRECISION (TREE_TYPE (@0));
> > -     unsigned otype_precision = TYPE_PRECISION (type);
> > -     wide_int trunc_max = wi::mask (otype_precision, false, 
> > itype_precision);
> > -     wide_int max = wi::mask (otype_precision, false, otype_precision);
> > -     wide_int int_cst_1 = wi::to_wide (@1);
> > -     wide_int int_cst_2 = wi::to_wide (@2);
> > -    }
> > -    (if (wi::eq_p (trunc_max, int_cst_1) && wi::eq_p (max, int_cst_2)))))))
> > -
> > -(if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type))
> > - /* SAT_VAL = (-(T)(X < 0) ^ MAX)  */
> > - (match (signed_integer_sat_val @0)
> > -  (bit_xor:c (nop_convert? (negate
> > -                           (nop_convert? (convert (lt @0 integer_zerop)))))
> > -            max_value)))
> > -
> > -/* Saturation add for signed integer.  */
> > -(if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type))
> > - (match (signed_integer_sat_add @0 @1)
> > -  /* T SUM = (T)((UT)X + (UT)Y)
> > -     SAT_S_ADD = (X ^ SUM) & !(X ^ Y) < 0 ? (-(T)(X < 0) ^ MAX) : SUM  */
> > -  (cond^ (lt (bit_and:c (bit_xor:c @0 (nop_convert@2 (plus (nop_convert @0)
> > -                                                          (nop_convert 
> > @1))))
> > -                       (bit_not (bit_xor:c @0 @1)))
> > -            integer_zerop)
> > -        (signed_integer_sat_val @0)
> > -        @2))
> > - (match (signed_integer_sat_add @0 @1)
> > -  /* T SUM = (T)((UT)X + (UT)Y)
> > -     SAT_S_ADD = (X ^ SUM) & !(X ^ Y) >= 0 ? SUM : (-(T)(X < 0) ^ MAX)  */
> > -  (cond^ (ge (bit_and:c (bit_xor @0 (nop_convert@2 (plus (nop_convert @0)
> > -                                                        (nop_convert @1))))
> > -                       (bit_not (bit_xor:c @0 @1)))
> > -            integer_zerop)
> > -        @2
> > -        (bit_xor:c (negate (convert (lt @0 integer_zerop))) max_value)))
> > - (match (signed_integer_sat_add @0 @1)
> > -  /* T SUM = (T)((UT)X + (UT)Y)
> > -     SAT_S_ADD = (X ^ Y) < 0 && (X ^ SUM) >= 0 ? (-(T)(X < 0) ^ MAX) : SUM 
> >  */
> > -  (cond^ (bit_and:c (lt (bit_xor @0 (nop_convert@2 (plus (nop_convert @0)
> > -                                                        (nop_convert @1))))
> > -                       integer_zerop)
> > -                   (ge (bit_xor:c @0 @1) integer_zerop))
> > -        (signed_integer_sat_val @0)
> > -        @2))
> > - (match (signed_integer_sat_add @0 @1)
> > -  /* T SUM = (T)((UT)X + (UT)IMM)
> > -     SAT_S_ADD = (X ^ SUM) < 0 && (X ^ IMM) >= 0 ? (-(T)(X < 0) ^ MAX) : 
> > SUM  */
> > -  (cond^ (bit_and:c (lt (bit_xor @0 (nop_convert@2 (plus (nop_convert @0)
> > -                                                        INTEGER_CST@1)))
> > -                       integer_zerop)
> > -                   (ge (bit_xor:c @0 INTEGER_CST@3) integer_zerop))
> > -        (signed_integer_sat_val @0)
> > -        @2)
> > -  (if (wi::eq_p (wi::to_wide (@1), wi::to_wide (@3)))))
> > - (match (signed_integer_sat_add @0 @1)
> > -   /* SUM = .ADD_OVERFLOW (X, Y)
> > -      SAT_S_ADD = IMAGPART_EXPR (SUM) != 0 ? (-(T)(X < 0) ^ MAX) : SUM  */
> > -  (cond^ (ne (imagpart (IFN_ADD_OVERFLOW:c@2 @0 @1)) integer_zerop)
> > -        (signed_integer_sat_val @0)
> > -        (realpart @2)))
> > - (match (signed_integer_sat_add @0 @1)
> > -  /* T SUM = (T)((UT)X + (UT)Y)
> > -     SAT_S_ADD = (X ^ SUM) < 0 & ~((X ^ Y) < 0) ? (-(T)(X < 0) ^ MAX) : 
> > SUM  */
> > -  (cond^ (bit_and:c (lt (bit_xor @0 (nop_convert@2 (plus (nop_convert @0)
> > -                                                        (nop_convert @1))))
> > -                       integer_zerop)
> > -                   (bit_not (lt (bit_xor:c @0 @1) integer_zerop)))
> > -        (signed_integer_sat_val @0)
> > -        @2))
> > - (match (signed_integer_sat_add @0 @1)
> > -  /* T SUM = (T)((UT)X + (UT)IMM);
> > -     SAT_S_ADD = (X ^ IMM) < 0 ? SUM : (X ^ SUM) >= 0 ? SUM
> > -                                                     : (x < 0) ? MIN : MAX 
> >  */
> > -  (cond^ (lt (bit_and:c (bit_xor:c @0 (nop_convert@2 (plus (nop_convert @0)
> > -                                                          INTEGER_CST@1)))
> > -                       (bit_xor:c @0 INTEGER_CST@3)) integer_zerop)
> > -        (signed_integer_sat_val @0)
> > -        @2)
> > -  (if (wi::bit_and (wi::to_wide (@1), wi::to_wide (@3)) == 0)))
> > -
> > -(match (signed_integer_sat_add @0 @1)
> > -  /* T SUM = (T)((UT)X + (UT)-1);
> > -     SAT_S_ADD = (X ^ -1) < 0 ? SUM : (X ^ SUM) >= 0 ? SUM
> > -                                                     : (x < 0) ? MIN : MAX 
> >  */
> > -  (convert (cond^ (lt (bit_and:c @0 (nop_convert (negate (nop_convert 
> > @0))))
> > -             integer_zerop)
> > -        INTEGER_CST@2
> > -        (plus (nop_convert @0) integer_all_onesp@1)))
> > -   (with
> > -    {
> > -     unsigned precision = TYPE_PRECISION (type);
> > -     wide_int c1 = wi::to_wide (@1);
> > -     wide_int c2 = wi::to_wide (@2);
> > -     wide_int sum = wi::add (c1, c2);
> > -    }
> > -    (if (wi::eq_p (sum, wi::max_value (precision, SIGNED))))))
> > -
> > -(match (signed_integer_sat_add @0 @1)
> > -  /* T SUM = (T)((UT)X + (UT)IMM)
> > -     SAT_S_ADD = (X ^ SUM) < 0 && (X ^ IMM) >= 0 ? (-(T)(X < 0) ^ MAX) : 
> > SUM  */
> > -   (cond^ (ge (bit_ior:c (bit_xor:c @0 INTEGER_CST@1)
> > -                       (bit_not (bit_xor:c @0 (nop_convert@2 (plus 
> > (nop_convert @0)
> > -                       INTEGER_CST@3)))))
> > -                   integer_zerop)
> > -           (signed_integer_sat_val @0)
> > -           @2)
> > -   (if (wi::eq_p (wi::to_wide (@1), wi::to_wide (@3))))))
> > -
> > -/* Saturation sub for signed integer.  */
> > -(if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type))
> > - (match (signed_integer_sat_sub @0 @1)
> > -  /* T Z = (T)((UT)X - (UT)Y);
> > -     SAT_S_SUB = (X ^ Y) & (X ^ Z) < 0 ? (-(T)(X < 0) ^ MAX) : Z  */
> > -  (cond^ (lt (bit_and:c (bit_xor:c @0 @1)
> > -                       (bit_xor @0 (nop_convert@2 (minus (nop_convert @0)
> > -                                                         (nop_convert 
> > @1)))))
> > -            integer_zerop)
> > -        (signed_integer_sat_val @0)
> > -        @2))
> > - (match (signed_integer_sat_sub @0 @1)
> > -  /* T Z = (T)((UT)X - (UT)Y);
> > -     SAT_S_SUB = (X ^ Y) & (X ^ Z) >= 0 ? Z : (-(T)(X < 0) ^ MAX)  */
> > -  (cond^ (ge (bit_and:c (bit_xor:c @0 @1)
> > -                       (bit_xor @0 (nop_convert@2 (minus (nop_convert @0)
> > -                                                         (nop_convert 
> > @1)))))
> > -            integer_zerop)
> > -        @2
> > -        (signed_integer_sat_val @0)))
> > - (match (signed_integer_sat_sub @0 @1)
> > -  /* T Z = (T)((UT)X - (UT)Y);
> > -     SAT_S_SUB = (X ^ Y) < 0 & (X ^ Z) < 0 ? (-(T)(X < 0) ^ MAX) : Z  */
> > -  (cond^ (bit_and:c (lt (bit_xor @0 (nop_convert@2 (minus (nop_convert @0)
> > -                                                         (nop_convert 
> > @1))))
> > -                       integer_zerop)
> > -                   (lt (bit_xor:c @0 @1) integer_zerop))
> > -        (signed_integer_sat_val @0)
> > -        @2))
> > - (match (signed_integer_sat_sub @0 @1)
> > -  /* Z = .SUB_OVERFLOW (X, Y)
> > -     SAT_S_SUB = IMAGPART (Z) != 0 ? (-(T)(X < 0) ^ MAX) : REALPART (Z)  */
> > -  (cond^ (ne (imagpart (IFN_SUB_OVERFLOW@2 @0 @1)) integer_zerop)
> > -        (signed_integer_sat_val @0)
> > -        (realpart @2))
> > -  (if (types_match (type, @0, @1)))))
> > -
> > -/* Saturation truncate for signed integer.  */
> > -(if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type))
> > - (match (signed_integer_sat_trunc @0)
> > -  /* SAT_S_TRUNC(X) = (unsigned)X + NT_MAX + 1  > Unsigned_MAX ? (NT)X  */
> > -  (cond^ (gt (plus:c (convert@4 @0) INTEGER_CST@1) INTEGER_CST@2)
> > -        (bit_xor:c (nop_convert?
> > -                    (negate (nop_convert? (convert (lt @0 
> > integer_zerop)))))
> > -                   INTEGER_CST@3)
> > -        (convert @0))
> > -  (if (!TYPE_UNSIGNED (TREE_TYPE (@0)) && TYPE_UNSIGNED (TREE_TYPE (@4)))
> > -   (with
> > -    {
> > -     unsigned itype_prec = TYPE_PRECISION (TREE_TYPE (@0));
> > -     unsigned otype_prec = TYPE_PRECISION (type);
> > -     wide_int offset = wi::uhwi (HOST_WIDE_INT_1U << (otype_prec - 1),
> > -                                itype_prec); // Aka 128 for int8_t
> > -     wide_int limit_0 = wi::mask (otype_prec, false, itype_prec); // Aka 
> > 255
> > -     wide_int limit_1 = wi::uhwi ((HOST_WIDE_INT_1U << otype_prec) - 3,
> > -                                 itype_prec); // Aka 253
> > -     wide_int limit_2 = wi::uhwi ((HOST_WIDE_INT_1U << otype_prec) - 2,
> > -                                 itype_prec); // Aka 254
> > -     wide_int otype_max = wi::mask (otype_prec - 1, false, otype_prec);
> > -     wide_int itype_max = wi::mask (otype_prec - 1, false, itype_prec);
> > -     wide_int int_cst_1 = wi::to_wide (@1);
> > -     wide_int int_cst_2 = wi::to_wide (@2);
> > -     wide_int int_cst_3 = wi::to_wide (@3);
> > -    }
> > -    (if (((wi::eq_p (int_cst_1, offset) && wi::eq_p (int_cst_2, limit_0))
> > -        || (wi::eq_p (int_cst_1, itype_max) && wi::eq_p (int_cst_2, 
> > limit_2))
> > -        || (wi::eq_p (int_cst_1, offset) && wi::eq_p (int_cst_2, limit_2))
> > -        || (wi::eq_p (int_cst_1, itype_max) && wi::eq_p (int_cst_2, 
> > limit_1)))
> > -        && wi::eq_p (int_cst_3, otype_max)))))))
> > -
> > -/* Saturation mult for unsigned integer.  */
> > -(if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type))
> > - (for mult_op (mult widen_mult)
> > -  (match (usmul_widen_mult @0 @1)
> > -   (mult_op:c (convert@2 @0) (convert @1))
> > -    (if (types_match (@0, @1) && TYPE_UNSIGNED (TREE_TYPE (@0)))
> > -     (with
> > -      {
> > -       unsigned prec = TYPE_PRECISION (TREE_TYPE (@0));
> > -       unsigned cvt2_prec = TYPE_PRECISION (TREE_TYPE (@2));
> > -       bool widen_cvt_p = cvt2_prec > prec;
> > -      }
> > -      (if (widen_cvt_p))))))
> > - (match (usmul_widen_mult @0 @1)
> > -  (widen_mult:c @0 @1)
> > -   (if (types_match (@0, @1))))
> > - (match (unsigned_integer_sat_mul @0 @1)
> > -  /* SAT_U_MUL (X, Y) = {
> > -       WT x = (WT)a * (WT)b;
> > -       T max = -1;
> > -       if (x > (WT)(max))
> > -        return max;
> > -       else
> > -        return (T)x;
> > -     }
> > -     while WT is uint128_t, T is uint8_t, uint16_t, uint32_t or uint64_t.  
> > */
> > -  (convert (min (usmul_widen_mult@3 @0 @1) INTEGER_CST@2))
> > -  (if (types_match (type, @0, @1))
> > -   (with
> > -    {
> > -      unsigned prec = TYPE_PRECISION (type);
> > -      unsigned widen_prec = TYPE_PRECISION (TREE_TYPE (@3));
> > -      wide_int max = wi::mask (prec, false, widen_prec);
> > -      bool c2_is_max_p = wi::eq_p (wi::to_wide (@2), max);
> > -    }
> > -    (if (c2_is_max_p)))))
> > -  (match (unsigned_integer_sat_mul @0 @1)
> > -   /* SAT_U_MUL (X, Y) = {
> > -       T result;
> > -       if (__builtin_mul_overflow (X, Y, &result))
> > -         return -1;
> > -       else
> > -         return result;
> > -      }
> > -      while T can be uint8_t, uint16_t, uint32_t and uint64_t.  */
> > -   (cond^ (ne (imagpart (IFN_MUL_OVERFLOW:c@2 @0 @1)) integer_zerop)
> > -          integer_minus_onep (realpart @2))
> > -   (if (types_match (type, @0, @1))))
> > -  (match (unsigned_integer_sat_mul @0 @1)
> > -   /* SAT_U_MUL (X, Y) = {
> > -       WT x = (WT)a * (WT)b;
> > -       if ((x >> sizeof(a) * 8) == 0)
> > -         return (T)x;
> > -       else
> > -         return (T)-1;
> > -      }
> > -      while WT is uint128_t, T is uint8_t, uint16_t, uint32_t or uint64_t. 
> >  */
> > -   (convert (cond^ (eq (rshift (mult:c@3 (convert @0) (convert @1))
> > -                              INTEGER_CST@2)
> > -                      integer_zerop)
> > -                  @3 INTEGER_CST@4))
> > -   (if (types_match (type, @0, @1))
> > -    (with
> > -     {
> > -      unsigned prec = TYPE_PRECISION (type);
> > -      unsigned widen_prec = TYPE_PRECISION (TREE_TYPE (@3));
> > -      wide_int c4 = wi::to_wide (@4);
> > -      wide_int max = wi::mask (prec, false, widen_prec);
> > -      bool c4_is_max_p = wi::eq_p (c4, max);
> > -      unsigned c2 = tree_to_uhwi (@2);
> > -      bool c2_is_type_precision_p = c2 == prec;
> > -     }
> > -     (if (widen_prec > prec && c2_is_type_precision_p && c4_is_max_p)))))
> > -  (match (unsigned_integer_sat_mul @0 @1)
> > -   /* SAT_U_MUL (X, Y) = {
> > -       WT x = (WT)a * (WT)b;
> > -       NT hi = x >> (sizeof(NT) * 8);
> > -       NT lo = (NT)x;
> > -       return lo | -!!hi;
> > -      } while WT is uint128_t, uint64_t, uint32_t, uint16_t,
> > -       and T is uint64_t, uint32_t, uint16_t, uint8_t.  */
> > -   (bit_ior:c
> > -    (convert?
> > -     (negate
> > -      (convert (ne (convert2? (rshift @3 INTEGER_CST@2)) integer_zerop))))
> > -    (convert (usmul_widen_mult@3 @0 @1)))
> > -   (if (types_match (type, @0, @1))
> > -    (with
> > -     {
> > -      unsigned prec = TYPE_PRECISION (type);
> > -      bool c2_is_type_precision_p = tree_to_uhwi (@2) == prec;
> > -     }
> > -     (if (c2_is_type_precision_p)))))
> > -  (match (unsigned_integer_sat_mul @0 @1)
> > -   /* SAT_U_MUL (X, Y) = {
> > -       WT x = (WT)a * (WT)b;
> > -       NT max = -1;
> > -       bool overflow_p = x > (WT)max;
> > -       return -(NT)(overflow_p) | (NT)x;
> > -      } while WT is uint128_t, uint64_t, uint32_t, uint16_t,
> > -       and T is uint64_t, uint32_t, uint16_t, uint8_t.  */
> > -   (bit_ior:c (negate (convert (gt @3 INTEGER_CST@2)))
> > -             (convert (usmul_widen_mult@3 @0 @1)))
> > -   (if (types_match (type, @0, @1))
> > -    (with
> > -     {
> > -      unsigned prec = TYPE_PRECISION (type);
> > -      unsigned widen_prec = TYPE_PRECISION (TREE_TYPE (@3));
> > -      wide_int max = wi::mask (prec, false, widen_prec);
> > -      bool c2_is_max_p = wi::eq_p (wi::to_wide (@2), max);
> > -     }
> > -     (if (c2_is_max_p)))))
> > -)
> > -#endif
> > -
> > -/* The boundary condition for case 10: IMM = 1:
> > -   SAT_U_SUB = X >= IMM ? (X - IMM) : 0.
> > -   simplify (X != 0 ? X + ~0 : 0) to X - (X != 0).  */
> > -(simplify
> > - (cond (ne@1 @0 integer_zerop)
> > -       (nop_convert1? (plus (nop_convert2?@2 @0) integer_all_onesp))
> > -       integer_zerop)
> > - (if (INTEGRAL_TYPE_P (type))
> > -   (with { tree itype = TREE_TYPE (@2); }
> > -    (convert (minus @2 (convert:itype @1))))))
> > -
> >  /* x >  y  &&  x != XXX_MIN  -->  x > y
> >     x >  y  &&  x == XXX_MIN  -->  false . */
> >  (for eqne (eq ne)
> > @@ -12410,3 +11855,20 @@ and,
> >  (simplify
> >   (BUILT_IN_CONSTANT_P (nop_convert@1 @0))
> >   (BUILT_IN_CONSTANT_P @0))
> > +
> > +#if GIMPLE
> > +
> > +#include "match-sat-alu.pd"
> > +
> > +#endif
>
> Add a small comment on what is being included here.
> Like:
> /* Include the saturation alu match patterns.  */
>
> Thanks,
> Andrea
>
> > +
> > +/* The boundary condition for case 10: IMM = 1:
> > +   SAT_U_SUB = X >= IMM ? (X - IMM) : 0.
> > +   simplify (X != 0 ? X + ~0 : 0) to X - (X != 0).  */
> > +(simplify
> > + (cond (ne@1 @0 integer_zerop)
> > +       (nop_convert1? (plus (nop_convert2?@2 @0) integer_all_onesp))
> > +       integer_zerop)
> > + (if (INTEGRAL_TYPE_P (type))
> > +   (with { tree itype = TREE_TYPE (@2); }
> > +    (convert (minus @2 (convert:itype @1))))))
> > --
> > 2.43.0
> >

Reply via email to