On Wed, 15 Oct 2025, Yury Khrustalev wrote:

> 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.
> ---
> Passes regression on aarch64. OK for trunk?
> 
> Base-commit: 599d2902b0a
> 
> Changes in v2:
>  - Fixed patch based on feedback for v1.
>  - Detect if we work with a packed boolean vector using a combination
>    of VECTOR_BOOLEAN_TYPE_P and GET_MODE_CLASS (TYPE_MODE_RAW (type)).
>  - Set DW_AT_bit_size to 1 in the referenced DIE.
>  - Added more tests.
>  - v1: https://patchwork.sourceware.org/project/gcc/list/?series=52149
> 
> ---
>  gcc/dwarf2out.cc                                | 16 ++++++++++++++++
>  .../g++.target/aarch64/dwarf-bit-stride-func.C  | 16 ++++++++++++++++
>  .../aarch64/dwarf-bit-stride-pragma-sme.C       | 16 ++++++++++++++++
>  .../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 ++++++++++++++
>  .../aarch64/dwarf-bit-stride-pragma.c           | 17 +++++++++++++++++
>  .../gcc.target/aarch64/sve/dwarf-bit-stride.c   | 15 +++++++++++++++
>  9 files changed, 142 insertions(+)
>  create mode 100644 gcc/testsuite/g++.target/aarch64/dwarf-bit-stride-func.C
>  create mode 100644 
> gcc/testsuite/g++.target/aarch64/dwarf-bit-stride-pragma-sme.C
>  create mode 100644 gcc/testsuite/g++.target/aarch64/dwarf-bit-stride-pragma.C
>  create mode 100644 gcc/testsuite/g++.target/aarch64/sve/dwarf-bit-stride.C
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/dwarf-bit-stride-func.c
>  create mode 100644 
> gcc/testsuite/gcc.target/aarch64/dwarf-bit-stride-pragma-sme.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/dwarf-bit-stride-pragma.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/dwarf-bit-stride.c
> 
> diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
> index a817c69c95a..5e531277804 100644
> --- a/gcc/dwarf2out.cc
> +++ b/gcc/dwarf2out.cc
> @@ -23034,6 +23034,22 @@ 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)
> +    && GET_MODE_CLASS (TYPE_MODE_RAW (type)) == MODE_VECTOR_BOOL)
> +    {
> +      /* MODE_VECTOR_BOOL implies that bit stride and bit size
> +      for element type must be 1.  */

Is that so?  I thought it wasn't.

I also think you don't want to look at modes, instead why don't
you check known_eq (TYPE_PRECISION (TREE_TYPE (type)), 1)?

> +      add_AT_unsigned (array_die, DW_AT_bit_stride, 1);
> +      /* 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, 1);
> +    }
> +
>    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 00000000000..1917d9116b0
> --- /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 00000000000..4b73cbc55ff
> --- /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 00000000000..64b02cc8927
> --- /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 00000000000..80224d45f78
> --- /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 00000000000..654bae54e5f
> --- /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 00000000000..4bd0da5a8a5
> --- /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 00000000000..77a0d801876
> --- /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 00000000000..3f34348ff91
> --- /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);
> +}
> 

-- 
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)

Reply via email to