https://gcc.gnu.org/g:35f5a18872127e18aadcbbc08df7885974280c79

commit r16-2058-g35f5a18872127e18aadcbbc08df7885974280c79
Author: Pan Li <pan2...@intel.com>
Date:   Wed Jul 2 09:46:08 2025 +0800

    Internal-fn: Introduce new IFN_SAT_MUL for unsigned int
    
    This patch would like to add the middle-end presentation for the
    unsigend saturation mul.  Aka set the result of mul to the max
    when overflow.
    
    Take uint8_t as example, we will have:
    
    * SAT_MUL (1, 127)   => 127.
    * SAT_MUL (2, 127)   => 254.
    * SAT_MUL (3, 127)   => 255.
    * SAT_MUL (255, 127) => 255.
    
    Given below example for uint16_t from uint128_t
    
      #define DEF_SAT_U_MUL_FMT_1(NT, WT)             \
      NT __attribute__((noinline))                    \
      sat_u_mul_##NT##_from_##WT##_fmt_1 (NT a, NT b) \
      {                                               \
        WT x = (WT)a * (WT)b;                         \
        NT max = -1;                                  \
        if (x > (WT)(max))                            \
          return max;                                 \
        else                                          \
          return (NT)x;                               \
      }
    
      DEF_SAT_U_MUL_FMT_1(uint16_t, uint128_t)
    
    Before this patch:
      15   │   <bb 2> [local count: 1073741824]:
      16   │   _1 = (__int128 unsigned) a_4(D);
      17   │   _2 = (__int128 unsigned) b_5(D);
      18   │   _9 = (unsigned long) _1;
      19   │   _10 = (unsigned long) _2;
      20   │   x_6 = _9 w* _10;
      21   │   _7 = MIN_EXPR <x_6, 255>;
      22   │   _3 = (uint8_t) _7;
      23   │   return _3;
    
    After this patch:
       9   │   <bb 2> [local count: 1073741824]:
      10   │   _3 = .SAT_MUL (a_4(D), b_5(D)); [tail call]
      11   │   return _3;
    
    gcc/ChangeLog:
    
            * internal-fn.cc (commutative_binary_fn_p): Add new case
            for SAT_MUL.
            * internal-fn.def (SAT_MUL): Add new IFN_SAT_MUL.
            * optabs.def (OPTAB_NL): Remove fixed point limitation.
    
    Signed-off-by: Pan Li <pan2...@intel.com>

Diff:
---
 gcc/internal-fn.cc  | 1 +
 gcc/internal-fn.def | 1 +
 gcc/optabs.def      | 4 ++--
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc
index 39048d77d23b..ed6ef0e4c647 100644
--- a/gcc/internal-fn.cc
+++ b/gcc/internal-fn.cc
@@ -4428,6 +4428,7 @@ commutative_binary_fn_p (internal_fn fn)
     case IFN_ADD_OVERFLOW:
     case IFN_MUL_OVERFLOW:
     case IFN_SAT_ADD:
+    case IFN_SAT_MUL:
     case IFN_VEC_WIDEN_PLUS:
     case IFN_VEC_WIDEN_PLUS_LO:
     case IFN_VEC_WIDEN_PLUS_HI:
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index 8edfa3540f8c..914ee9f278cd 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -282,6 +282,7 @@ DEF_INTERNAL_SIGNED_OPTAB_FN (MULHRS, ECF_CONST | 
ECF_NOTHROW, first,
 
 DEF_INTERNAL_SIGNED_OPTAB_FN (SAT_ADD, ECF_CONST, first, ssadd, usadd, binary)
 DEF_INTERNAL_SIGNED_OPTAB_FN (SAT_SUB, ECF_CONST, first, sssub, ussub, binary)
+DEF_INTERNAL_SIGNED_OPTAB_FN (SAT_MUL, ECF_CONST, first, ssmul, usmul, binary)
 
 DEF_INTERNAL_SIGNED_OPTAB_FN (SAT_TRUNC, ECF_CONST, first, sstrunc, ustrunc, 
unary_convert)
 
diff --git a/gcc/optabs.def b/gcc/optabs.def
index 0c1435d4ecd7..87a8b85da159 100644
--- a/gcc/optabs.def
+++ b/gcc/optabs.def
@@ -134,8 +134,8 @@ OPTAB_NX(smul_optab, "mul$P$a3")
 OPTAB_NX(smul_optab, "mul$F$a3")
 OPTAB_VL(smulv_optab, "mulv$I$a3", MULT, "mul", '3', gen_intv_fp_libfunc)
 OPTAB_VX(smulv_optab, "mul$F$a3")
-OPTAB_NL(ssmul_optab, "ssmul$Q$a3", SS_MULT, "ssmul", '3', 
gen_signed_fixed_libfunc)
-OPTAB_NL(usmul_optab, "usmul$Q$a3", US_MULT, "usmul", '3', 
gen_unsigned_fixed_libfunc)
+OPTAB_NL(ssmul_optab, "ssmul$a3", SS_MULT, "ssmul", '3', 
gen_signed_fixed_libfunc)
+OPTAB_NL(usmul_optab, "usmul$a3", US_MULT, "usmul", '3', 
gen_unsigned_fixed_libfunc)
 OPTAB_NL(sdiv_optab, "div$a3", DIV, "div", '3', 
gen_int_fp_signed_fixed_libfunc)
 OPTAB_VL(sdivv_optab, "divv$I$a3", DIV, "divv", '3', gen_int_libfunc)
 OPTAB_VX(sdivv_optab, "div$F$a3")

Reply via email to