https://gcc.gnu.org/g:c7206efa282bdd121ae4bd5227b487d06c3874c2

commit r16-6478-gc7206efa282bdd121ae4bd5227b487d06c3874c2
Author: Jakub Jelinek <[email protected]>
Date:   Sat Jan 3 14:27:41 2026 +0100

    widening_mul: Fix up .SAT_{ADD,SUB,MUL} pattern recognition [PR123372]
    
    The following testcase ICEs since r15-1671, because the match.pd pattern
    now allows a cast and the function checks whether the ifn is supported
    on a wrong type.  .SAT_{ADD,SUB,MUL} are binary ifns, so they care about
    the type of their first operand:
      #define binary_direct { 0, 0, true }
    where
      /* optabs can be parameterized by one or two modes.  These fields describe
         how to select those modes from the types of the return value and
         arguments.  A value of -1 says that the mode is determined by the
         return type while a value N >= 0 says that the mode is determined by
         the type of argument N.  A value of -2 says that this internal
         function isn't directly mapped to an optab.  */
    but in this function (unlike the function right below it for the
    same ifns) checks the type of the lhs which since that change can be
    actually a different type (expansion performs the operation on the
    argument types and then casts the result to the lhs type).
    So, e.g. on x86_64 -m32, it checks wether ussubsi3 insn can be used
    (which it can), but then actually uses it on DImode arguments and
    ussubdi3 is TARGET_64BIT only.  Similarly for -m64 it checks ussubsi3 too
    instead of ussubti3 (which doesn't exist).
    
    2026-01-03  Jakub Jelinek  <[email protected]>
    
            PR tree-optimization/123372
            * tree-ssa-math-opts.cc
            (build_saturation_binary_arith_call_and_replace): Pass type of op_0
            rather than type of lhs as second argument to
            direct_internal_fn_supported_p.
    
            * gcc.dg/tree-ssa/pr123372.c: New test.

Diff:
---
 gcc/testsuite/gcc.dg/tree-ssa/pr123372.c | 25 +++++++++++++++++++++++++
 gcc/tree-ssa-math-opts.cc                |  2 +-
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr123372.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr123372.c
new file mode 100644
index 000000000000..953b2792a5ff
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr123372.c
@@ -0,0 +1,25 @@
+/* PR tree-optimization/123372 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fgimple" } */
+
+#ifdef __SIZEOF_INT128__
+#define T unsigned __int128
+#else
+#define T unsigned long long
+#endif
+
+unsigned int __GIMPLE (ssa,startwith("phiopt4"))
+foo (T a, T b)
+{
+  T _4;
+  unsigned int _1;
+  bool _5;
+  unsigned int _6;
+
+  __BB(2):
+  _5 = a_2(D) >= b_3(D);
+  _4 = a_2(D) - b_3(D);
+  _6 = (unsigned int) _4;
+  _1 = _5 ? _6 : 0U;
+  return _1;
+}
diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc
index 74e970f22d66..4c3fb0f4fc53 100644
--- a/gcc/tree-ssa-math-opts.cc
+++ b/gcc/tree-ssa-math-opts.cc
@@ -4083,7 +4083,7 @@ build_saturation_binary_arith_call_and_replace 
(gimple_stmt_iterator *gsi,
                                                internal_fn fn, tree lhs,
                                                tree op_0, tree op_1)
 {
-  if (direct_internal_fn_supported_p (fn, TREE_TYPE (lhs), OPTIMIZE_FOR_BOTH))
+  if (direct_internal_fn_supported_p (fn, TREE_TYPE (op_0), OPTIMIZE_FOR_BOTH))
     {
       gcall *call = gimple_build_call_internal (fn, 2, op_0, op_1);
       gimple_call_set_lhs (call, lhs);

Reply via email to