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

commit r14-11898-gd51d503af7db6e4d8ca40e29d9250850f25aee1a
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Fri Jul 18 09:20:30 2025 +0200

    gimple-fold: Fix up big endian _BitInt adjustment [PR121131]
    
    The following testcase ICEs because SCALAR_INT_TYPE_MODE of course
    doesn't work for large BITINT_TYPE types which have BLKmode.
    native_encode* as well as e.g. r14-8276 use in cases like these
    GET_MODE_SIZE (SCALAR_INT_TYPE_MODE ()) and TREE_INT_CST_LOW (TYPE_SIZE_UNIT
    ()) for the BLKmode ones.
    In this case, it wants bits rather than bytes, so I've used
    GET_MODE_BITSIZE like before and TYPE_SIZE otherwise.
    
    Furthermore, the patch only computes encoding_size for big endian
    targets, for little endian we don't really adjust anything, so there
    is no point computing it.
    
    2025-07-18  Jakub Jelinek  <ja...@redhat.com>
    
            PR tree-optimization/121131
            * gimple-fold.cc (fold_nonarray_ctor_reference): Use
            TREE_INT_CST_LOW (TYPE_SIZE ()) instead of
            GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE ()) for BLKmode BITINT_TYPEs.
            Don't compute encoding_size at all for little endian targets.
    
            * gcc.dg/bitint-124.c: New test.
    
    (cherry picked from commit 90955b2f61f787ebc446f0a105b5f49672388d89)

Diff:
---
 gcc/gimple-fold.cc                | 13 ++++++++++---
 gcc/testsuite/gcc.dg/bitint-124.c | 30 ++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index 026dac45deda..cc84d392a83c 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -8243,10 +8243,17 @@ fold_nonarray_ctor_reference (tree type, tree ctor,
            {
              if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
                return NULL_TREE;
-             const unsigned int encoding_size
-               = GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (TREE_TYPE (cfield)));
              if (BYTES_BIG_ENDIAN)
-               inner_offset += encoding_size - wi::to_offset (field_size);
+               {
+                 tree ctype = TREE_TYPE (cfield);
+                 unsigned int encoding_size;
+                 if (TYPE_MODE (ctype) != BLKmode)
+                   encoding_size
+                     = GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (ctype));
+                 else
+                   encoding_size = TREE_INT_CST_LOW (TYPE_SIZE (ctype));
+                 inner_offset += encoding_size - wi::to_offset (field_size);
+               }
            }
 
          return fold_ctor_reference (type, cval,
diff --git a/gcc/testsuite/gcc.dg/bitint-124.c 
b/gcc/testsuite/gcc.dg/bitint-124.c
new file mode 100644
index 000000000000..160a1e3394ab
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/bitint-124.c
@@ -0,0 +1,30 @@
+/* PR tree-optimization/121131 */
+/* { dg-do run { target bitint } } */
+/* { dg-options "-O2" } */
+
+#if __BITINT_MAXWIDTH__ >= 156
+struct A { _BitInt(156) b : 135; };
+
+static inline _BitInt(156)
+foo (struct A *x)
+{
+  return x[1].b;
+}
+
+__attribute__((noipa)) _BitInt(156)
+bar (void)
+{
+  struct A a[] = { 1, 1, -13055525270329736316393717310914023773847wb,
+                  1, 1, 1, 1, 1, 1, 1, 1, 1 };
+  return foo (&a[1]);
+}
+#endif
+
+int
+main ()
+{
+#if __BITINT_MAXWIDTH__ >= 156
+  if (bar () != -13055525270329736316393717310914023773847wb)
+    __builtin_abort ();
+#endif
+}

Reply via email to