[llvm-branch-commits] [lldb] 4d30813 - [LLDB] Test SVE dynamic resize with multiple threads

Muhammad Omair Javaid via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Jan 19 02:06:06 PST 2021


Author: Muhammad Omair Javaid
Date: 2021-01-19T15:01:32+05:00
New Revision: 4d3081331ad854e0bff5032c818ec6414fb974c0

URL: https://github.com/llvm/llvm-project/commit/4d3081331ad854e0bff5032c818ec6414fb974c0
DIFF: https://github.com/llvm/llvm-project/commit/4d3081331ad854e0bff5032c818ec6414fb974c0.diff

LOG: [LLDB] Test SVE dynamic resize with multiple threads

This patch adds a new test case which depends on AArch64 SVE support and
dynamic resize capability enabled. It created two seperate threads which
have different values of sve registers and SVE vector granule at various
points during execution.

We test that LLDB is doing the size and offset updates properly for all
of the threads including the main thread and when we VG is updated using
prctl call or by 'register write vg' command the appropriate changes are
also update in register infos.

Reviewed By: labath

Differential Revision: https://reviews.llvm.org/D82866

Added: 
    lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_dynamic_resize/Makefile
    lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_dynamic_resize/TestSVEThreadedDynamic.py
    lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_dynamic_resize/main.c

Modified: 
    

Removed: 
    


################################################################################
diff  --git a/lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_dynamic_resize/Makefile b/lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_dynamic_resize/Makefile
new file mode 100644
index 000000000000..efa5ca913f6e
--- /dev/null
+++ b/lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_dynamic_resize/Makefile
@@ -0,0 +1,5 @@
+C_SOURCES := main.c
+
+CFLAGS_EXTRAS := -march=armv8-a+sve -lpthread
+
+include Makefile.rules

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
new file mode 100644
index 000000000000..4d9cb686818e
--- /dev/null
+++ b/lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_dynamic_resize/TestSVEThreadedDynamic.py
@@ -0,0 +1,138 @@
+"""
+Test the AArch64 SVE registers dynamic resize with multiple threads.
+"""
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class RegisterCommandsTestCase(TestBase):
+
+    def check_sve_registers(self, vg_test_value):
+        z_reg_size = vg_test_value * 8
+        p_reg_size = int(z_reg_size / 8)
+
+        p_value_bytes = ['0xff', '0x55', '0x11', '0x01', '0x00']
+
+        for i in range(32):
+            s_reg_value = 's%i = 0x' % (i) + \
+                ''.join('{:02x}'.format(i + 1) for _ in range(4))
+
+            d_reg_value = 'd%i = 0x' % (i) + \
+                ''.join('{:02x}'.format(i + 1) for _ in range(8))
+
+            v_reg_value = 'v%i = 0x' % (i) + \
+                ''.join('{:02x}'.format(i + 1) for _ in range(16))
+
+            z_reg_value = '{' + \
+                ' '.join('0x{:02x}'.format(i + 1)
+                         for _ in range(z_reg_size)) + '}'
+
+            self.expect("register read -f hex " + 's%i' %
+                        (i), substrs=[s_reg_value])
+
+            self.expect("register read -f hex " + 'd%i' %
+                        (i), substrs=[d_reg_value])
+
+            self.expect("register read -f hex " + 'v%i' %
+                        (i), substrs=[v_reg_value])
+
+            self.expect("register read " + 'z%i' %
+                        (i), substrs=[z_reg_value])
+
+        for i in range(16):
+            p_regs_value = '{' + \
+                ' '.join(p_value_bytes[i % 5] for _ in range(p_reg_size)) + '}'
+            self.expect("register read " + 'p%i' % (i), substrs=[p_regs_value])
+
+        self.expect("register read ffr", substrs=[p_regs_value])
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @no_debug_info_test
+    @skipIf(archs=no_match(["aarch64"]))
+    @skipIf(oslist=no_match(['linux']))
+    def test_sve_registers_dynamic_config(self):
+        """Test AArch64 SVE registers multi-threaded dynamic resize. """
+
+        self.build()
+        exe = self.getBuildArtifact("a.out")
+        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+        if not self.isAArch64SVE():
+            self.skipTest('SVE registers must be supported.')
+
+        main_thread_stop_line = line_number(
+            "main.c", "// Break in main thread")
+        lldbutil.run_break_set_by_file_and_line(
+            self, "main.c", main_thread_stop_line)
+
+        thX_break_line1 = line_number("main.c", "// Thread X breakpoint 1")
+        lldbutil.run_break_set_by_file_and_line(
+            self, "main.c", thX_break_line1)
+
+        thX_break_line2 = line_number("main.c", "// Thread X breakpoint 2")
+        lldbutil.run_break_set_by_file_and_line(
+            self, "main.c", thX_break_line2)
+
+        thY_break_line1 = line_number("main.c", "// Thread Y breakpoint 1")
+        lldbutil.run_break_set_by_file_and_line(
+            self, "main.c", thY_break_line1)
+
+        thY_break_line2 = line_number("main.c", "// Thread Y breakpoint 2")
+        lldbutil.run_break_set_by_file_and_line(
+            self, "main.c", thY_break_line2)
+
+        self.runCmd("run", RUN_SUCCEEDED)
+
+        process = self.dbg.GetSelectedTarget().GetProcess()
+
+        thread1 = process.GetThreadAtIndex(0)
+
+        self.expect("thread info 1", STOPPED_DUE_TO_BREAKPOINT,
+                    substrs=["stop reason = breakpoint"])
+
+        self.check_sve_registers(8)
+
+        self.runCmd("process continue", RUN_SUCCEEDED)
+
+        for idx in range(1, process.GetNumThreads()):
+            thread = process.GetThreadAtIndex(idx)
+            if thread.GetStopReason() != lldb.eStopReasonBreakpoint:
+                self.runCmd("thread continue %d" % (idx + 1))
+                self.assertEqual(thread.GetStopReason(),
+                                 lldb.eStopReasonBreakpoint)
+
+            stopped_at_line_number = thread.GetFrameAtIndex(
+                0).GetLineEntry().GetLine()
+
+            if stopped_at_line_number == thX_break_line1:
+                self.runCmd("thread select %d" % (idx + 1))
+                self.check_sve_registers(4)
+                self.runCmd('register write vg 2')
+
+            elif stopped_at_line_number == thY_break_line1:
+                self.runCmd("thread select %d" % (idx + 1))
+                self.check_sve_registers(2)
+                self.runCmd('register write vg 4')
+
+        self.runCmd("thread continue 2")
+        self.runCmd("thread continue 3")
+
+        for idx in range(1, process.GetNumThreads()):
+            thread = process.GetThreadAtIndex(idx)
+            self.assertEqual(thread.GetStopReason(),
+                             lldb.eStopReasonBreakpoint)
+
+            stopped_at_line_number = thread.GetFrameAtIndex(
+                0).GetLineEntry().GetLine()
+
+            if stopped_at_line_number == thX_break_line2:
+                self.runCmd("thread select %d" % (idx + 1))
+                self.check_sve_registers(2)
+
+            elif stopped_at_line_number == thY_break_line2:
+                self.runCmd("thread select %d" % (idx + 1))
+                self.check_sve_registers(4)

diff  --git a/lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_dynamic_resize/main.c b/lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_dynamic_resize/main.c
new file mode 100644
index 000000000000..b14ba280bb73
--- /dev/null
+++ b/lldb/test/API/commands/register/register/aarch64_sve_registers/rw_access_dynamic_resize/main.c
@@ -0,0 +1,96 @@
+#include <pthread.h>
+#include <sys/prctl.h>
+
+static inline void write_sve_registers() {
+  asm volatile("setffr\n\t");
+  asm volatile("ptrue p0.b\n\t");
+  asm volatile("ptrue p1.h\n\t");
+  asm volatile("ptrue p2.s\n\t");
+  asm volatile("ptrue p3.d\n\t");
+  asm volatile("pfalse p4.b\n\t");
+  asm volatile("ptrue p5.b\n\t");
+  asm volatile("ptrue p6.h\n\t");
+  asm volatile("ptrue p7.s\n\t");
+  asm volatile("ptrue p8.d\n\t");
+  asm volatile("pfalse p9.b\n\t");
+  asm volatile("ptrue p10.b\n\t");
+  asm volatile("ptrue p11.h\n\t");
+  asm volatile("ptrue p12.s\n\t");
+  asm volatile("ptrue p13.d\n\t");
+  asm volatile("pfalse p14.b\n\t");
+  asm volatile("ptrue p15.b\n\t");
+
+  asm volatile("cpy  z0.b, p0/z, #1\n\t");
+  asm volatile("cpy  z1.b, p5/z, #2\n\t");
+  asm volatile("cpy  z2.b, p10/z, #3\n\t");
+  asm volatile("cpy  z3.b, p15/z, #4\n\t");
+  asm volatile("cpy  z4.b, p0/z, #5\n\t");
+  asm volatile("cpy  z5.b, p5/z, #6\n\t");
+  asm volatile("cpy  z6.b, p10/z, #7\n\t");
+  asm volatile("cpy  z7.b, p15/z, #8\n\t");
+  asm volatile("cpy  z8.b, p0/z, #9\n\t");
+  asm volatile("cpy  z9.b, p5/z, #10\n\t");
+  asm volatile("cpy  z10.b, p10/z, #11\n\t");
+  asm volatile("cpy  z11.b, p15/z, #12\n\t");
+  asm volatile("cpy  z12.b, p0/z, #13\n\t");
+  asm volatile("cpy  z13.b, p5/z, #14\n\t");
+  asm volatile("cpy  z14.b, p10/z, #15\n\t");
+  asm volatile("cpy  z15.b, p15/z, #16\n\t");
+  asm volatile("cpy  z16.b, p0/z, #17\n\t");
+  asm volatile("cpy  z17.b, p5/z, #18\n\t");
+  asm volatile("cpy  z18.b, p10/z, #19\n\t");
+  asm volatile("cpy  z19.b, p15/z, #20\n\t");
+  asm volatile("cpy  z20.b, p0/z, #21\n\t");
+  asm volatile("cpy  z21.b, p5/z, #22\n\t");
+  asm volatile("cpy  z22.b, p10/z, #23\n\t");
+  asm volatile("cpy  z23.b, p15/z, #24\n\t");
+  asm volatile("cpy  z24.b, p0/z, #25\n\t");
+  asm volatile("cpy  z25.b, p5/z, #26\n\t");
+  asm volatile("cpy  z26.b, p10/z, #27\n\t");
+  asm volatile("cpy  z27.b, p15/z, #28\n\t");
+  asm volatile("cpy  z28.b, p0/z, #29\n\t");
+  asm volatile("cpy  z29.b, p5/z, #30\n\t");
+  asm volatile("cpy  z30.b, p10/z, #31\n\t");
+  asm volatile("cpy  z31.b, p15/z, #32\n\t");
+}
+
+void *threadX_func(void *x_arg) {
+  prctl(PR_SVE_SET_VL, 8 * 4);
+  write_sve_registers();
+  write_sve_registers(); // Thread X breakpoint 1
+  return NULL;           // Thread X breakpoint 2
+}
+
+void *threadY_func(void *y_arg) {
+  prctl(PR_SVE_SET_VL, 8 * 2);
+  write_sve_registers();
+  write_sve_registers(); // Thread Y breakpoint 1
+  return NULL;           // Thread Y breakpoint 2
+}
+
+int main() {
+  /* this variable is our reference to the second thread */
+  pthread_t x_thread, y_thread;
+
+  /* Set vector length to 8 and write SVE registers values */
+  prctl(PR_SVE_SET_VL, 8 * 8);
+  write_sve_registers();
+
+  /* create a second thread which executes with argument x */
+  if (pthread_create(&x_thread, NULL, threadX_func, 0)) // Break in main thread
+    return 1;
+
+  /* create a second thread which executes with argument y */
+  if (pthread_create(&y_thread, NULL, threadY_func, 0))
+    return 1;
+
+  /* wait for the first thread to finish */
+  if (pthread_join(x_thread, NULL))
+    return 2;
+
+  /* wait for the second thread to finish */
+  if (pthread_join(y_thread, NULL))
+    return 2;
+
+  return 0;
+}


        


More information about the llvm-branch-commits mailing list