]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
bitintlower: Padding bit fixes, part 6 [PR123635]
authorJakub Jelinek <jakub@redhat.com>
Wed, 29 Apr 2026 09:12:47 +0000 (11:12 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 29 Apr 2026 09:12:47 +0000 (11:12 +0200)
I've missed torture/bitint-{93,94}.c FAILs on s390x-linux (i.e. big endian).
For __builtin_mul_overflow, the code to extend the partial most significant
limb is done before memmoving it down, so that limb actually isn't on big
endian at offset 0 but is nelts - obj_nelts.  The following patch computes
obj_nelts first, uses it on big-endian and so that the offset checking
asserts don't trigger, on big-endian also uses NULL_TREE first argument to
limb_access.

2026-04-29  Jakub Jelinek  <jakub@redhat.com>

PR middle-end/123635
* gimple-lower-bitint.cc (bitint_large_huge::finish_arith_overflow):
Move obj_nelts/atype computation before bitint_extended handling.  For
bitint_big_endian in the bitint_extended handling use size_zero_node
only for limb_access_type calls, otherwise use
size_int (nelts - obj_nelts) and pass NULL_TREE as first argument to
limb_access calls.

Reviewed-by: Richard Biener <rguenth@suse.de>
gcc/gimple-lower-bitint.cc

index 9c4600121d0a436e35deb06fddb464a854ae4488..7d8ca05f88d057173db3a190b88395f0e0cb3a63 100644 (file)
@@ -4478,6 +4478,13 @@ bitint_large_huge::finish_arith_overflow (tree var, tree obj, tree type,
     {
       unsigned HOST_WIDE_INT obj_nelts = 0;
       tree atype = NULL_TREE;
+      if (obj)
+       {
+         obj_nelts = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (obj))) / limb_prec;
+         if (orig_obj == NULL_TREE)
+           obj_nelts >>= 1;
+         atype = build_array_type_nelts (m_limb_type, obj_nelts);
+       }
       if (bitint_extended && (var || obj))
        {
          unsigned prec = TYPE_PRECISION (type);
@@ -4492,9 +4499,13 @@ bitint_large_huge::finish_arith_overflow (tree var, tree obj, tree type,
          if ((code == MULT_EXPR && (prec % limb_prec) != 0)
              || (ext_ms_limb && !TYPE_UNSIGNED (type)))
            {
-             tree plm1idx = size_int (bitint_big_endian ? 0 : prec_limbs - 1);
-             tree plm1type = limb_access_type (type, plm1idx);
-             tree l = limb_access (type, var ? var : obj, plm1idx, true);
+             tree plm1idx = size_int (bitint_big_endian
+                                      ? nelts - obj_nelts : prec_limbs - 1);
+             tree plm1type
+               = limb_access_type (type, bitint_big_endian
+                                         ? size_zero_node : plm1idx);
+             tree l = limb_access (bitint_big_endian ? NULL_TREE : type,
+                                   var ? var : obj, plm1idx, true);
              tree rhs = make_ssa_name (TREE_TYPE (l));
              g = gimple_build_assign (rhs, l);
              insert_before (g);
@@ -4505,7 +4516,8 @@ bitint_large_huge::finish_arith_overflow (tree var, tree obj, tree type,
                  if (!useless_type_conversion_p (TREE_TYPE (l),
                                                  TREE_TYPE (rhs)))
                    rhs = add_cast (TREE_TYPE (l), rhs);
-                 l = limb_access (type, var ? var : obj, plm1idx, true);
+                 l = limb_access (bitint_big_endian ? NULL_TREE : type,
+                                  var ? var : obj, plm1idx, true);
                  g = gimple_build_assign (l, rhs);
                  insert_before (g);
                }
@@ -4537,13 +4549,6 @@ bitint_large_huge::finish_arith_overflow (tree var, tree obj, tree type,
              insert_before (g);
            }
        }
-      if (obj)
-       {
-         obj_nelts = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (obj))) / limb_prec;
-         if (orig_obj == NULL_TREE)
-           obj_nelts >>= 1;
-         atype = build_array_type_nelts (m_limb_type, obj_nelts);
-       }
       if (var && obj)
        {
          tree v1, v2;