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

commit r15-10621-gba39d22f0b3f01195d8164649fc025653827f6b6
Author: Yury Khrustalev <[email protected]>
Date:   Wed Sep 3 12:46:33 2025 +0100

    dwarf: Save bit stride information for array type entry [PR121964]
    
    Lack of DW_AT_bit_stride in a DW_TAG_array_type entry causes GDB to infer
    incorrect element size for vector types. The causes incorrect display of
    SVE predicate variables as well as out of bounds memory access when reading
    contents of SVE predicates from memory in GDB.
    
    We also locate DIE referenced by DW_AT_type and set DW_AT_bit_size 1 in it.
    
            PR debug/121964
    
    gcc/
            * dwarf2out.cc (gen_array_type_die): Add DW_AT_bit_stride attribute
            for array types based on element type bit precision for integer and
            boolean element types.
    
    gcc/testsuite/
            * g++.target/aarch64/dwarf-bit-stride-func.C: New test.
            * g++.target/aarch64/dwarf-bit-stride-pragma.C: New test.
            * g++.target/aarch64/dwarf-bit-stride-pragma-sme.C: New test.
            * g++.target/aarch64/sve/dwarf-bit-stride.C: New test.
            * gcc.target/aarch64/dwarf-bit-stride-func.c: New test.
            * gcc.target/aarch64/dwarf-bit-stride-pragma.c: New test.
            * gcc.target/aarch64/dwarf-bit-stride-pragma-sme.c: New test.
            * gcc.target/aarch64/sve/dwarf-bit-stride.c: New test.
    
    (cherry picked from commit 5a8746df980e3532bf6f293f086db21758e90a9e)

Diff:
---
 gcc/dwarf2out.cc                                   | 22 ++++++++++++++++++++++
 .../g++.target/aarch64/dwarf-bit-stride-func.C     | 16 ++++++++++++++++
 .../aarch64/dwarf-bit-stride-pragma-sme.C          | 16 ++++++++++++++++
 .../g++.target/aarch64/dwarf-bit-stride-pragma.C   | 17 +++++++++++++++++
 .../g++.target/aarch64/sve/dwarf-bit-stride.C      | 15 +++++++++++++++
 .../gcc.target/aarch64/dwarf-bit-stride-func.c     | 16 ++++++++++++++++
 .../aarch64/dwarf-bit-stride-pragma-sme.c          | 14 ++++++++++++++
 .../gcc.target/aarch64/dwarf-bit-stride-pragma.c   | 17 +++++++++++++++++
 .../gcc.target/aarch64/sve/dwarf-bit-stride.c      | 15 +++++++++++++++
 9 files changed, 148 insertions(+)

diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index 2437610d48da..9dda6a648cdc 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -22721,6 +22721,28 @@ gen_array_type_die (tree type, dw_die_ref context_die)
                      && TYPE_REVERSE_STORAGE_ORDER (type),
                      context_die);
 
+  /* Add bit stride information to boolean vectors of single bits so that
+     elements can be correctly read and displayed by a debugger.  */
+  if (VECTOR_BOOLEAN_TYPE_P (type))
+    {
+      enum machine_mode tmode = TYPE_MODE_RAW (type);
+      if (GET_MODE_CLASS (tmode) == MODE_VECTOR_BOOL)
+       {
+         /* Calculate bit-size of element based on mnode.  */
+         poly_uint16 bit_size = exact_div (GET_MODE_BITSIZE (tmode),
+                                           GET_MODE_NUNITS (tmode));
+         /* Set bit stride in the array type DIE.  */
+         add_AT_unsigned (array_die, DW_AT_bit_stride, bit_size.coeffs[0]);
+         /* Find DIE corresponding to the element type so that we could
+            add DW_AT_bit_size to it.  */
+         dw_die_ref elem_die = get_AT_ref (array_die, DW_AT_type);
+         /* Avoid adding DW_AT_bit_size twice.  */
+         if (get_AT (elem_die, DW_AT_bit_size) == NULL)
+           add_AT_unsigned (elem_die, DW_AT_bit_size,
+                            TYPE_PRECISION (element_type));
+       }
+    }
+
   add_gnat_descriptive_type_attribute (array_die, type, context_die);
   if (TYPE_ARTIFICIAL (type))
     add_AT_flag (array_die, DW_AT_artificial, 1);
diff --git a/gcc/testsuite/g++.target/aarch64/dwarf-bit-stride-func.C 
b/gcc/testsuite/g++.target/aarch64/dwarf-bit-stride-func.C
new file mode 100644
index 000000000000..1917d9116b04
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/dwarf-bit-stride-func.C
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+// { dg-options "-g -dA" }
+// { dg-final { scan-assembler-times "DW_AT_name: \"svbool_t\"" 1 } }
+// { dg-final { scan-assembler-times ".byte    0x1     // DW_AT_bit_stride" 1 
} }
+// { dg-final { scan-assembler-times ".byte    0x1     // DW_AT_bit_size" 1 } }
+
+#include <arm_sve.h>
+
+[[gnu::target ("arch=armv9-a+sve")]]
+void fun ()
+{
+  volatile svbool_t pred8 = svwhilelt_b8_u32 (0u, 1u);
+  volatile svbool_t pred16 = svwhilelt_b16_u32 (0u, 3u);
+  volatile svbool_t pred32 = svwhilelt_b32_u32 (0u, 7u);
+  volatile svbool_t pred64 = svwhilelt_b64_u32 (0u, 11u);
+}
diff --git a/gcc/testsuite/g++.target/aarch64/dwarf-bit-stride-pragma-sme.C 
b/gcc/testsuite/g++.target/aarch64/dwarf-bit-stride-pragma-sme.C
new file mode 100644
index 000000000000..4b73cbc55ff2
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/dwarf-bit-stride-pragma-sme.C
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+// { dg-options "-g -dA" }
+// { dg-final { scan-assembler-times "DW_AT_name: \"svbool_t\"" 1 } }
+// { dg-final { scan-assembler-times "DW_AT_name: \"svcount_t\"" 1 } }
+// { dg-final { scan-assembler-times ".byte    0x1     // DW_AT_bit_stride" 1 
} }
+// { dg-final { scan-assembler-times ".byte    0x1     // DW_AT_bit_size" 1 } }
+
+#include <arm_sme.h>
+
+#pragma GCC target "+sve2p1+sme2"
+
+void fun ()
+{
+  volatile svbool_t pred;
+  volatile svcount_t count;
+}
diff --git a/gcc/testsuite/g++.target/aarch64/dwarf-bit-stride-pragma.C 
b/gcc/testsuite/g++.target/aarch64/dwarf-bit-stride-pragma.C
new file mode 100644
index 000000000000..64b02cc89277
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/dwarf-bit-stride-pragma.C
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+// { dg-options "-g -dA" }
+// { dg-final { scan-assembler-times "DW_AT_name: \"svbool_t\"" 1 } }
+// { dg-final { scan-assembler-times ".byte    0x1     // DW_AT_bit_stride" 1 
} }
+// { dg-final { scan-assembler-times ".byte    0x1     // DW_AT_bit_size" 1 } }
+
+#include <arm_sve.h>
+
+#pragma GCC target "+sve"
+
+void fun ()
+{
+  volatile svbool_t pred8 = svwhilelt_b8_u32 (0u, 1u);
+  volatile svbool_t pred16 = svwhilelt_b16_u32 (0u, 3u);
+  volatile svbool_t pred32 = svwhilelt_b32_u32 (0u, 7u);
+  volatile svbool_t pred64 = svwhilelt_b64_u32 (0u, 11u);
+}
diff --git a/gcc/testsuite/g++.target/aarch64/sve/dwarf-bit-stride.C 
b/gcc/testsuite/g++.target/aarch64/sve/dwarf-bit-stride.C
new file mode 100644
index 000000000000..80224d45f789
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/sve/dwarf-bit-stride.C
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+// { dg-options "-g -dA" }
+// { dg-final { scan-assembler-times "DW_AT_name: \"svbool_t\"" 1 } }
+// { dg-final { scan-assembler-times ".byte    0x1     // DW_AT_bit_stride" 1 
} }
+// { dg-final { scan-assembler-times ".byte    0x1     // DW_AT_bit_size" 1 } }
+
+#include <arm_sve.h>
+
+void fun ()
+{
+  volatile svbool_t pred8 = svwhilelt_b8_u32 (0u, 1u);
+  volatile svbool_t pred16 = svwhilelt_b16_u32 (0u, 3u);
+  volatile svbool_t pred32 = svwhilelt_b32_u32 (0u, 7u);
+  volatile svbool_t pred64 = svwhilelt_b64_u32 (0u, 11u);
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/dwarf-bit-stride-func.c 
b/gcc/testsuite/gcc.target/aarch64/dwarf-bit-stride-func.c
new file mode 100644
index 000000000000..654bae54e5f5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/dwarf-bit-stride-func.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+// { dg-options "-g -dA" }
+// { dg-final { scan-assembler-times "DW_AT_name: \"__SVBool_t\"" 1 } }
+// { dg-final { scan-assembler-times ".byte    0x1     // DW_AT_bit_stride" 1 
} }
+// { dg-final { scan-assembler-times ".byte    0x1     // DW_AT_bit_size" 1 } }
+
+#include <arm_sve.h>
+
+__attribute__((target("arch=armv9-a+sve")))
+void fun ()
+{
+  volatile svbool_t pred8 = svwhilelt_b8_u32 (0u, 1u);
+  volatile svbool_t pred16 = svwhilelt_b16_u32 (0u, 3u);
+  volatile svbool_t pred32 = svwhilelt_b32_u32 (0u, 7u);
+  volatile svbool_t pred64 = svwhilelt_b64_u32 (0u, 11u);
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/dwarf-bit-stride-pragma-sme.c 
b/gcc/testsuite/gcc.target/aarch64/dwarf-bit-stride-pragma-sme.c
new file mode 100644
index 000000000000..4bd0da5a8a5f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/dwarf-bit-stride-pragma-sme.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+// { dg-options "-g -dA" }
+// { dg-final { scan-assembler-times "DW_AT_name: \"__SVBool_t\"" 2 } }
+// { dg-final { scan-assembler-times "DW_AT_name: \"__SVCount_t\"" 1 } }
+// { dg-final { scan-assembler-times ".byte    0x1     // DW_AT_bit_stride" 2 
} }
+// { dg-final { scan-assembler-times ".byte    0x1     // DW_AT_bit_size" 1 } }
+
+#pragma GCC target "+sve2p1+sme2"
+
+void fun ()
+{
+  volatile __SVBool_t pred;
+  volatile __SVCount_t count;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/dwarf-bit-stride-pragma.c 
b/gcc/testsuite/gcc.target/aarch64/dwarf-bit-stride-pragma.c
new file mode 100644
index 000000000000..77a0d801876b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/dwarf-bit-stride-pragma.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+// { dg-options "-g -dA" }
+// { dg-final { scan-assembler-times "DW_AT_name: \"__SVBool_t\"" 1 } }
+// { dg-final { scan-assembler-times ".byte    0x1     // DW_AT_bit_stride" 1 
} }
+// { dg-final { scan-assembler-times ".byte    0x1     // DW_AT_bit_size" 1 } }
+
+#include <arm_sve.h>
+
+#pragma GCC target "+sve"
+
+void fun ()
+{
+  volatile svbool_t pred8 = svwhilelt_b8_u32 (0u, 1u);
+  volatile svbool_t pred16 = svwhilelt_b16_u32 (0u, 3u);
+  volatile svbool_t pred32 = svwhilelt_b32_u32 (0u, 7u);
+  volatile svbool_t pred64 = svwhilelt_b64_u32 (0u, 11u);
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/dwarf-bit-stride.c 
b/gcc/testsuite/gcc.target/aarch64/sve/dwarf-bit-stride.c
new file mode 100644
index 000000000000..3f34348ff916
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/dwarf-bit-stride.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+// { dg-options "-g -dA" }
+// { dg-final { scan-assembler-times "DW_AT_name: \"__SVBool_t\"" 1 } }
+// { dg-final { scan-assembler-times ".byte    0x1     // DW_AT_bit_stride" 1 
} }
+// { dg-final { scan-assembler-times ".byte    0x1     // DW_AT_bit_size" 1 } }
+
+#include <arm_sve.h>
+
+void fun ()
+{
+  volatile svbool_t pred8 = svwhilelt_b8_u32 (0u, 1u);
+  volatile svbool_t pred16 = svwhilelt_b16_u32 (0u, 3u);
+  volatile svbool_t pred32 = svwhilelt_b32_u32 (0u, 7u);
+  volatile svbool_t pred64 = svwhilelt_b64_u32 (0u, 11u);
+}

Reply via email to