[Lldb-commits] [lldb] [lldb][AArch64] Add isAArch64SMEFA64 check to SME testing (PR #68094)

David Spickett via lldb-commits lldb-commits at lists.llvm.org
Wed Oct 4 01:00:54 PDT 2023


https://github.com/DavidSpickett updated https://github.com/llvm/llvm-project/pull/68094

>From 3816b0fbc31825d3878b031a49fb78dd7c256278 Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at linaro.org>
Date: Tue, 3 Oct 2023 11:44:17 +0100
Subject: [PATCH 1/3] [lldb][AArch64] Add isAArch64SMEFA64 check to SME testing

FEAT_SME_FA64 (smefa64 in Linux cpuinfo) allows the use of the full
A64 instruction set while in streaming SVE mode.

See https://developer.arm.com/documentation/ddi0616/latest/ for
details.

This means for example if we want to write to the ffr register during
or use floating point registers while in streaming mode, we need this extension.

I initially was using QEMU which has it by default, and switched to
Arm's FVP which does not. So this change adds a more strict check and
converts most of the tests to use that.

It would be possible in some cases to avoid the offending instructions
but it would be a lot of effort and liable to fail randomly as the C
library changes.

It is also my assumption that the majority of systems will have
smefa64 as QEMU has chosen to have. If I turn out to be wrong, we
can make the effort to get the tests working without smefa64.
---
 lldb/packages/Python/lldbsuite/test/lldbtest.py        |  6 ++++++
 .../aarch64_dynamic_regset/TestArm64DynamicRegsets.py  |  4 ++--
 .../rw_access_dynamic_resize/TestSVEThreadedDynamic.py | 10 ++++++----
 .../rw_access_static_config/TestSVERegisters.py        |  5 +++--
 .../aarch64_sve_simd_registers/TestSVESIMDRegisters.py |  5 +++--
 .../za_dynamic_resize/TestZAThreadedDynamic.py         |  6 ++++--
 .../aarch64_za_register/za_dynamic_resize/main.c       |  1 +
 .../za_save_restore/TestZARegisterSaveRestore.py       |  4 ++--
 8 files changed, 27 insertions(+), 14 deletions(-)

diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index c8670b208ec3f0c..2f4130d3ce68ae0 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -1271,6 +1271,12 @@ def isAArch64SVE(self):
     def isAArch64SME(self):
         return self.isAArch64() and "sme" in self.getCPUInfo()
 
+    def isAArch64SMEFA64(self):
+        # smefa64 allows the use of the full A64 instruction set in streaming
+        # mode. This is required by certain test programs to setup register
+        # state.
+        return self.isAArch64SME() and "smefa64" in self.getCPUInfo()
+
     def isAArch64MTE(self):
         return self.isAArch64() and "mte" in self.getCPUInfo()
 
diff --git a/lldb/test/API/commands/register/register/aarch64_dynamic_regset/TestArm64DynamicRegsets.py b/lldb/test/API/commands/register/register/aarch64_dynamic_regset/TestArm64DynamicRegsets.py
index 2fb8b33126417c2..0ad69c268a9fd29 100644
--- a/lldb/test/API/commands/register/register/aarch64_dynamic_regset/TestArm64DynamicRegsets.py
+++ b/lldb/test/API/commands/register/register/aarch64_dynamic_regset/TestArm64DynamicRegsets.py
@@ -142,8 +142,8 @@ def make_za_value(self, vl, generator):
     def test_aarch64_dynamic_regset_config_sme(self):
         """Test AArch64 Dynamic Register sets configuration, but only SME
         registers."""
-        if not self.isAArch64SME():
-            self.skipTest("SME must be present.")
+        if not self.isAArch64SMEFA64():
+            self.skipTest("SME and the smefa64 extension must be present")
 
         register_sets = self.setup_register_config_test("sme")
 
diff --git a/lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_dynamic_resize/TestSVEThreadedDynamic.py b/lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_dynamic_resize/TestSVEThreadedDynamic.py
index 8bcb76776459d01..b19039f0b5212b4 100644
--- a/lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_dynamic_resize/TestSVEThreadedDynamic.py
+++ b/lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_dynamic_resize/TestSVEThreadedDynamic.py
@@ -108,8 +108,9 @@ def run_sve_test(self, mode):
         if (mode == Mode.SVE) and not self.isAArch64SVE():
             self.skipTest("SVE registers must be supported.")
 
-        if (mode == Mode.SSVE) and not self.isAArch64SME():
-            self.skipTest("Streaming SVE registers must be supported.")
+        if (mode == Mode.SSVE) and not self.isAArch64SMEFA64():
+            self.skipTest("Streaming SVE registers must be supported and the "
+                          "smefa64 extension must be present.")
 
         self.build_for_mode(mode)
 
@@ -201,8 +202,9 @@ def test_ssve_registers_dynamic_config(self):
 
     def setup_svg_test(self, mode):
         # Even when running in SVE mode, we need access to SVG for these tests.
-        if not self.isAArch64SME():
-            self.skipTest("Streaming SVE registers must be present.")
+        if not self.isAArch64SMEFA64():
+            self.skipTest("Streaming SVE registers must be present and the "
+                          "smefa64 extension must be present.")
 
         self.build_for_mode(mode)
 
diff --git a/lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_static_config/TestSVERegisters.py b/lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_static_config/TestSVERegisters.py
index 82b79b8d4b6cc2b..ac99652442b5ddd 100644
--- a/lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_static_config/TestSVERegisters.py
+++ b/lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_static_config/TestSVERegisters.py
@@ -85,8 +85,9 @@ def skip_if_needed(self, mode):
         if (mode == Mode.SVE) and not self.isAArch64SVE():
             self.skipTest("SVE registers must be supported.")
 
-        if (mode == Mode.SSVE) and not self.isAArch64SME():
-            self.skipTest("SSVE registers must be supported.")
+        if (mode == Mode.SSVE) and not self.isAArch64SMEFA64():
+            self.skipTest("SSVE registers must be supported and the smefa64 "
+                          "extension must be present.")
 
     def sve_registers_configuration_impl(self, mode):
         self.skip_if_needed(mode)
diff --git a/lldb/test/API/commands/register/register/aarch64_sve_simd_registers/TestSVESIMDRegisters.py b/lldb/test/API/commands/register/register/aarch64_sve_simd_registers/TestSVESIMDRegisters.py
index 814ca98369fca57..def93c78abc2745 100644
--- a/lldb/test/API/commands/register/register/aarch64_sve_simd_registers/TestSVESIMDRegisters.py
+++ b/lldb/test/API/commands/register/register/aarch64_sve_simd_registers/TestSVESIMDRegisters.py
@@ -41,8 +41,9 @@ def skip_if_needed(self, mode):
         if (mode == Mode.SVE) and not self.isAArch64SVE():
             self.skipTest("SVE registers must be supported.")
 
-        if (mode == Mode.SSVE) and not self.isAArch64SME():
-            self.skipTest("SSVE registers must be supported.")
+        if (mode == Mode.SSVE) and not self.isAArch64SMEFA64():
+            self.skipTest("SSVE registers must be supported and the smefa64 "
+                          "extension must be present.")
 
     def make_simd_value(self, n):
         pad = " ".join(["0x00"] * 7)
diff --git a/lldb/test/API/commands/register/register/aarch64_za_register/za_dynamic_resize/TestZAThreadedDynamic.py b/lldb/test/API/commands/register/register/aarch64_za_register/za_dynamic_resize/TestZAThreadedDynamic.py
index 65d1071c26b2a34..884340b395a448d 100644
--- a/lldb/test/API/commands/register/register/aarch64_za_register/za_dynamic_resize/TestZAThreadedDynamic.py
+++ b/lldb/test/API/commands/register/register/aarch64_za_register/za_dynamic_resize/TestZAThreadedDynamic.py
@@ -65,8 +65,10 @@ def check_disabled_za_register(self, svg):
         self.expect("register read za", substrs=[self.gen_za_value(svg, lambda r: 0)])
 
     def za_test_impl(self, enable_za):
-        if not self.isAArch64SME():
-            self.skipTest("SME must be present.")
+        # Although the test program doesn't obviously do any operations that
+        # would need smefa64, calls to libc functions like memset may do.
+        if not self.isAArch64SMEFA64():
+            self.skipTest("SME and the sm3fa64 extension must be present")
 
         self.build()
         supported_vg = self.get_supported_vg()
diff --git a/lldb/test/API/commands/register/register/aarch64_za_register/za_dynamic_resize/main.c b/lldb/test/API/commands/register/register/aarch64_za_register/za_dynamic_resize/main.c
index fd2590dbe411f7f..05839c26336cc8e 100644
--- a/lldb/test/API/commands/register/register/aarch64_za_register/za_dynamic_resize/main.c
+++ b/lldb/test/API/commands/register/register/aarch64_za_register/za_dynamic_resize/main.c
@@ -29,6 +29,7 @@ void set_za_register(int svl, int value_offset) {
   // you have. So setting one that didn't exist would actually set one that did.
   // That's why we need the streaming vector length here.
   for (int i = 0; i < svl; ++i) {
+    // This may involve instructions that require the smefa64 extension.
     memset(data, i + value_offset, MAX_VL_BYTES);
     // Each one of these loads a VL sized row of ZA.
     asm volatile("mov w12, %w0\n\t"
diff --git a/lldb/test/API/commands/register/register/aarch64_za_register/za_save_restore/TestZARegisterSaveRestore.py b/lldb/test/API/commands/register/register/aarch64_za_register/za_save_restore/TestZARegisterSaveRestore.py
index 910966a0b3b0bc5..a647c91f71119ec 100644
--- a/lldb/test/API/commands/register/register/aarch64_za_register/za_save_restore/TestZARegisterSaveRestore.py
+++ b/lldb/test/API/commands/register/register/aarch64_za_register/za_save_restore/TestZARegisterSaveRestore.py
@@ -106,8 +106,8 @@ def check_za_disabled(self, vl):
         self.expect("register read za", substrs=[self.make_za_value(vl, lambda row: 0)])
 
     def za_expr_test_impl(self, sve_mode, za_state, swap_start_vl):
-        if not self.isAArch64SME():
-            self.skipTest("SME must be present.")
+        if not self.isAArch64SMEFA64():
+            self.skipTest("SME and the smefa64 extension must be present.")
 
         supported_svg = self.get_supported_svg()
         if len(supported_svg) < 2:

>From 4fb5205f9ea5298c7826be8629acaea31fa32837 Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at linaro.org>
Date: Tue, 3 Oct 2023 13:24:39 +0100
Subject: [PATCH 2/3] Fix python formatting.

---
 .../TestSVEThreadedDynamic.py                        | 12 ++++++++----
 .../rw_access_static_config/TestSVERegisters.py      |  6 ++++--
 .../TestSVESIMDRegisters.py                          |  6 ++++--
 3 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_dynamic_resize/TestSVEThreadedDynamic.py b/lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_dynamic_resize/TestSVEThreadedDynamic.py
index b19039f0b5212b4..5d5914bef354655 100644
--- a/lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_dynamic_resize/TestSVEThreadedDynamic.py
+++ b/lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_dynamic_resize/TestSVEThreadedDynamic.py
@@ -109,8 +109,10 @@ def run_sve_test(self, mode):
             self.skipTest("SVE registers must be supported.")
 
         if (mode == Mode.SSVE) and not self.isAArch64SMEFA64():
-            self.skipTest("Streaming SVE registers must be supported and the "
-                          "smefa64 extension must be present.")
+            self.skipTest(
+                "Streaming SVE registers must be supported and the "
+                "smefa64 extension must be present."
+            )
 
         self.build_for_mode(mode)
 
@@ -203,8 +205,10 @@ def test_ssve_registers_dynamic_config(self):
     def setup_svg_test(self, mode):
         # Even when running in SVE mode, we need access to SVG for these tests.
         if not self.isAArch64SMEFA64():
-            self.skipTest("Streaming SVE registers must be present and the "
-                          "smefa64 extension must be present.")
+            self.skipTest(
+                "Streaming SVE registers must be present and the "
+                "smefa64 extension must be present."
+            )
 
         self.build_for_mode(mode)
 
diff --git a/lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_static_config/TestSVERegisters.py b/lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_static_config/TestSVERegisters.py
index ac99652442b5ddd..f198d4716e8ee18 100644
--- a/lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_static_config/TestSVERegisters.py
+++ b/lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_static_config/TestSVERegisters.py
@@ -86,8 +86,10 @@ def skip_if_needed(self, mode):
             self.skipTest("SVE registers must be supported.")
 
         if (mode == Mode.SSVE) and not self.isAArch64SMEFA64():
-            self.skipTest("SSVE registers must be supported and the smefa64 "
-                          "extension must be present.")
+            self.skipTest(
+                "SSVE registers must be supported and the smefa64 "
+                "extension must be present."
+            )
 
     def sve_registers_configuration_impl(self, mode):
         self.skip_if_needed(mode)
diff --git a/lldb/test/API/commands/register/register/aarch64_sve_simd_registers/TestSVESIMDRegisters.py b/lldb/test/API/commands/register/register/aarch64_sve_simd_registers/TestSVESIMDRegisters.py
index def93c78abc2745..ce4c725714d23cc 100644
--- a/lldb/test/API/commands/register/register/aarch64_sve_simd_registers/TestSVESIMDRegisters.py
+++ b/lldb/test/API/commands/register/register/aarch64_sve_simd_registers/TestSVESIMDRegisters.py
@@ -42,8 +42,10 @@ def skip_if_needed(self, mode):
             self.skipTest("SVE registers must be supported.")
 
         if (mode == Mode.SSVE) and not self.isAArch64SMEFA64():
-            self.skipTest("SSVE registers must be supported and the smefa64 "
-                          "extension must be present.")
+            self.skipTest(
+                "SSVE registers must be supported and the smefa64 "
+                "extension must be present."
+            )
 
     def make_simd_value(self, n):
         pad = " ".join(["0x00"] * 7)

>From 050a344b9467c113a1a79e3c6df8f505af2d572d Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at linaro.org>
Date: Wed, 4 Oct 2023 09:00:25 +0100
Subject: [PATCH 3/3] Only read cpuinfo once.

---
 lldb/packages/Python/lldbsuite/test/lldbtest.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index 2f4130d3ce68ae0..e3a56f9853130d3 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -1275,7 +1275,9 @@ def isAArch64SMEFA64(self):
         # smefa64 allows the use of the full A64 instruction set in streaming
         # mode. This is required by certain test programs to setup register
         # state.
-        return self.isAArch64SME() and "smefa64" in self.getCPUInfo()
+        return self.isAArch64SME() and set(["sme", "smefa64"]).issuperset(
+            set(self.getCPUInfo())
+        )
 
     def isAArch64MTE(self):
         return self.isAArch64() and "mte" in self.getCPUInfo()



More information about the lldb-commits mailing list