From 44aa71daf083ccfc53498594b853eb022df5dd55 Mon Sep 17 00:00:00 2001 From: Junghee Lim Date: Fri, 10 May 2024 14:20:54 -0400 Subject: [PATCH 1/6] Separate avx512f instruction out of the ex_aligned_data_in_cope test - Introduce check_avx512f_support - Separate avx512f instruction out of the existing test, and create a separate example - Run the test for 64-byte alignment only when the cpu supports avx512f --- .../ex_aligned_data_in_code/Makefile | 6 ++ .../ex_aligned_data_in_code/ex_original2.s | 63 +++++++++++++++++++ tests/misc_test.py | 33 +++++++++- 3 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 examples/asm_examples/ex_aligned_data_in_code/ex_original2.s diff --git a/examples/asm_examples/ex_aligned_data_in_code/Makefile b/examples/asm_examples/ex_aligned_data_in_code/Makefile index c3181abdf..8abd91ad3 100644 --- a/examples/asm_examples/ex_aligned_data_in_code/Makefile +++ b/examples/asm_examples/ex_aligned_data_in_code/Makefile @@ -1,10 +1,16 @@ all: ex_original.s gcc ex_original.s -o ex + gcc ex_original2.s -o ex2 @./ex > out.txt + @./ex2 > out2.txt clean: rm -f ex out.txt rm -fr ex.unstripped ex.s *.old* dl_files *.gtirb + rm -f ex2 out2.txt + rm -fr ex2.unstripped ex2.s check: ./ex > /tmp/res.txt @ diff out.txt /tmp/res.txt && echo TEST OK + ./ex2 > /tmp/res2.txt + @ diff out2.txt /tmp/res2.txt && echo TEST OK diff --git a/examples/asm_examples/ex_aligned_data_in_code/ex_original2.s b/examples/asm_examples/ex_aligned_data_in_code/ex_original2.s new file mode 100644 index 000000000..c103b098e --- /dev/null +++ b/examples/asm_examples/ex_aligned_data_in_code/ex_original2.s @@ -0,0 +1,63 @@ +# This example is to demonostrate that data-in-code is properly aligned +# when it is referenced by instructions that require explicitly aligned memory. +# If not properly aligned, it may cause a segmentation fault due to alignment +# requirement violation. +# See Table 15-6 in https://cdrdv2.intel.com/v1/dl/getContent/671200. +# +# This example tests avx512 instructions. + + .section .text + +.globl main +.type main, @function +main: + call print_message1 + + # Load data into ZMM register using movdqa: `data512` needs to be aligned. + vmovaps data512(%rip), %zmm0 + + # Load data into ZMM register using vmovups: `data512u` does not need to be aligned. + vmovups data512u(%rip), %zmm1 + + call print_message2 + + xorq %rax, %rax + + ret + +.type print_message1, @function +print_message1: + lea message1(%rip), %rdi + call printf + ret + +.align 16 +.type print_message2, @function +print_message2: + lea message2(%rip), %rdi + call printf + ret + .zero 3 + +.align 64 +data512: + .byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 + .byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 + .byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 + .byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 + + .zero 3 +data512u: + .byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 + .byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 + .byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 + .byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 + + .section .data + +message1: + .ascii "Performing SIMD operations...\n" + .byte 0 +message2: + .ascii "SIMD operations completed.\n" + .byte 0 diff --git a/tests/misc_test.py b/tests/misc_test.py index a04e75622..daf3dc165 100644 --- a/tests/misc_test.py +++ b/tests/misc_test.py @@ -152,6 +152,15 @@ def test_lock_cmpxchg(self): self.subtest_lock_cmpxchg(example) +def check_avx512f_support(): + try: + import cpuid + + return cpuid.get_cpuid().ext_avx512f + except ImportError: + return False + + class AuxDataTests(unittest.TestCase): @unittest.skipUnless( platform.system() == "Linux", "This test is linux only." @@ -455,8 +464,28 @@ def test_aligned_data_in_code(self): # alignment=16: `data128.1`, `data128.2`, and `main` self.assertEqual(alignment_list.count(16), 3) - # alignment=32: `data256` - self.assertEqual(alignment_list.count(32), 1) + # alignment=32: `data256` and `_start` + self.assertEqual(alignment_list.count(32), 2) + + @unittest.skipUnless( + platform.system() == "Linux", + "This test is linux only." and not check_avx512f_support(), + ) + def test_aligned_data_in_code512(self): + """ + Test that alignment directives are correctly generated for + data_in_code referenced by instructions that require 64-byte + alignment + """ + binary = "ex2" + with cd(ex_asm_dir / "ex_aligned_data_in_code"): + self.assertTrue(compile("gcc", "g++", "-O0", [])) + ir = disassemble(Path(binary)).ir() + m = ir.modules[0] + + alignments = m.aux_data["alignment"].data.items() + alignment_list = [alignment for uuid, alignment in alignments] + # alignment=64: `data512` and `_start` self.assertEqual(alignment_list.count(64), 2) From 6bad0a27ca8947f737c6ff49b98d0dfe504ddf73 Mon Sep 17 00:00:00 2001 From: Junghee Lim Date: Fri, 10 May 2024 14:24:49 -0400 Subject: [PATCH 2/6] Remove the avx512f instruction from the original example --- .../ex_aligned_data_in_code/ex_original.s | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/examples/asm_examples/ex_aligned_data_in_code/ex_original.s b/examples/asm_examples/ex_aligned_data_in_code/ex_original.s index 368f2e944..65a2ddfa6 100644 --- a/examples/asm_examples/ex_aligned_data_in_code/ex_original.s +++ b/examples/asm_examples/ex_aligned_data_in_code/ex_original.s @@ -14,7 +14,7 @@ main: # Load data into XMM register using movdqa: `data128.1` needs to be aligned. movdqa data128.1(%rip), %xmm0 - # A pair of instructions from an access to `data128.2`, which needs to + # A pair of instructions forms an access to `data128.2`, which needs to # be aligned. lea data128.2(%rip), %rax movdqa 0(%rax), %xmm1 @@ -22,11 +22,8 @@ main: # Load data into YMM register using movdqa: `data256` needs to be aligned. vmovapd data256(%rip), %ymm0 - # Load data into ZMM register using movdqa: `data512` needs to be aligned. - vmovaps data512(%rip), %zmm0 - - # Load data into ZMM register using vmovups: `data512u` does not need to be aligned. - vmovups data512u(%rip), %zmm1 + # Load data into YMM register using vmovups: `data256u` does not need to be aligned. + vmovups data256u(%rip), %ymm1 call print_message2 @@ -58,17 +55,9 @@ data128.2: data256: .byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 .byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 -.align 64 -data512: - .byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 - .byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 - .byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 - .byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 .zero 3 -data512u: - .byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 - .byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 +data256u: .byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 .byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 From db69f843ddeb8fd75eb61dd86f918e83ccabb9fc Mon Sep 17 00:00:00 2001 From: Junghee Lim Date: Fri, 10 May 2024 17:35:41 -0400 Subject: [PATCH 3/6] Fix the way of counting alignments Also, fix the avx512f check --- tests/misc_test.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/tests/misc_test.py b/tests/misc_test.py index daf3dc165..7ebf20904 100644 --- a/tests/misc_test.py +++ b/tests/misc_test.py @@ -459,17 +459,26 @@ def test_aligned_data_in_code(self): ir = disassemble(Path(binary)).ir() m = ir.modules[0] + main_sym = next(m.symbols_named("main")) + main_block = main_sym.referent + alignments = m.aux_data["alignment"].data.items() - alignment_list = [alignment for uuid, alignment in alignments] + alignment_list = [ + alignment + for block, alignment in alignments + if block.address > main_block.address + ] - # alignment=16: `data128.1`, `data128.2`, and `main` - self.assertEqual(alignment_list.count(16), 3) - # alignment=32: `data256` and `_start` - self.assertEqual(alignment_list.count(32), 2) + # alignment=16: `data128.1`, `data128.2` + self.assertEqual(alignment_list.count(16), 2) + # alignment=32: `data256` + self.assertEqual(alignment_list.count(32), 1) @unittest.skipUnless( - platform.system() == "Linux", - "This test is linux only." and not check_avx512f_support(), + platform.system() == "Linux", "This test is linux only." + ) + @unittest.skipUnless( + check_avx512f_support(), "This test requires avx512f." ) def test_aligned_data_in_code512(self): """ From c3362fa8a59a1080da68bb0de2ec772580f54dad Mon Sep 17 00:00:00 2001 From: Junghee Lim Date: Fri, 10 May 2024 17:41:18 -0400 Subject: [PATCH 4/6] Fix the way of counting alignments for the avx512 example --- tests/misc_test.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tests/misc_test.py b/tests/misc_test.py index 7ebf20904..8174b48f3 100644 --- a/tests/misc_test.py +++ b/tests/misc_test.py @@ -492,11 +492,18 @@ def test_aligned_data_in_code512(self): ir = disassemble(Path(binary)).ir() m = ir.modules[0] + main_sym = next(m.symbols_named("main")) + main_block = main_sym.referent + alignments = m.aux_data["alignment"].data.items() - alignment_list = [alignment for uuid, alignment in alignments] + alignment_list = [ + alignment + for block, alignment in alignments + if block.address > main_block.address + ] - # alignment=64: `data512` and `_start` - self.assertEqual(alignment_list.count(64), 2) + # alignment=64: `data512` + self.assertEqual(alignment_list.count(64), 1) class RawGtirbTests(unittest.TestCase): From db0e968609077d47787113e3116b16bf59cc5f38 Mon Sep 17 00:00:00 2001 From: Junghee Lim Date: Mon, 13 May 2024 10:53:05 -0400 Subject: [PATCH 5/6] Use lscpu to check if cpu supports avx512f --- tests/misc_test.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/misc_test.py b/tests/misc_test.py index 8174b48f3..ef4da289a 100644 --- a/tests/misc_test.py +++ b/tests/misc_test.py @@ -153,12 +153,15 @@ def test_lock_cmpxchg(self): def check_avx512f_support(): - try: - import cpuid - - return cpuid.get_cpuid().ext_avx512f - except ImportError: - return False + if platform.system() == "Linux": + try: + output = subprocess.check_output(["lscpu"]) + output = output.decode("utf-8") + if "avx512f" in output: + return True + except FileNotFoundError: + print("lscpu command not found.") + return False class AuxDataTests(unittest.TestCase): From 6fd15bd5f0b71c5871d42966559b8b530e038eaf Mon Sep 17 00:00:00 2001 From: Junghee Lim Date: Mon, 13 May 2024 12:53:01 -0400 Subject: [PATCH 6/6] Remove try-except for lscpu --- tests/misc_test.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/tests/misc_test.py b/tests/misc_test.py index ef4da289a..ff1f1517a 100644 --- a/tests/misc_test.py +++ b/tests/misc_test.py @@ -154,13 +154,10 @@ def test_lock_cmpxchg(self): def check_avx512f_support(): if platform.system() == "Linux": - try: - output = subprocess.check_output(["lscpu"]) - output = output.decode("utf-8") - if "avx512f" in output: - return True - except FileNotFoundError: - print("lscpu command not found.") + output = subprocess.check_output(["lscpu"]) + output = output.decode("utf-8") + if "avx512f" in output: + return True return False