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. */
+ 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);
+}
--
2.47.3