https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127517

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
--- a/gcc/internal-fn.cc        2026-09-16 22:17:08.000000000 +0200
+++ b/gcc/internal-fn.cc        2026-09-23 19:59:09.255514356 +0200
@@ -1764,10 +1764,26 @@ expand_mul_overflow (location_t loc, tre
   do_error = gen_label_rtx ();

   do_pending_stack_adjust ();
+
+  scalar_int_mode mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg0));
+  /* If the operand types don't have mode precision, extend them
+     to mode precision.  */
+  if (TYPE_PRECISION (TREE_TYPE (arg0)) < GET_MODE_PRECISION (mode))
+    {
+      tree type = build_nonstandard_integer_type (GET_MODE_PRECISION (mode),
+                                                 uns0_p);
+      arg0 = fold_convert_loc (loc, type, arg0);
+    }
+  if (TYPE_PRECISION (TREE_TYPE (arg1)) < GET_MODE_PRECISION (mode))
+    {
+      tree type = build_nonstandard_integer_type (GET_MODE_PRECISION (mode),
+                                                 uns1_p);
+      arg1 = fold_convert_loc (loc, type, arg1);
+    }
+
   op0 = expand_normal (arg0);
   op1 = expand_normal (arg1);

-  scalar_int_mode mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg0));
   bool uns = unsr_p;
   if (lhs)
     {
@@ -1829,12 +1845,6 @@ expand_mul_overflow (location_t loc, tre

   int pos_neg0 = get_range_pos_neg (arg0, currently_expanding_gimple_stmt);
   int pos_neg1 = get_range_pos_neg (arg1, currently_expanding_gimple_stmt);
-  /* Unsigned types with smaller than mode precision, even if they have most
-     significant bit set, are still zero-extended.  */
-  if (uns0_p && TYPE_PRECISION (TREE_TYPE (arg0)) < GET_MODE_PRECISION (mode))
-    pos_neg0 = 1;
-  if (uns1_p && TYPE_PRECISION (TREE_TYPE (arg1)) < GET_MODE_PRECISION (mode))
-    pos_neg1 = 1;

   /* s1 * u2 -> ur  */
   if (!uns0_p && uns1_p && unsr_p)
fixes this, will see if it doesn't break something else.

Reply via email to