Skip to content

Conversation

@mstorsjo
Copy link
Member

These fixes improve consistency in the testcases.

@llvmbot
Copy link
Member

llvmbot commented Nov 28, 2025

@llvm/pr-subscribers-backend-aarch64

Author: Martin Storsjö (mstorsjo)

Changes

These fixes improve consistency in the testcases.


Full diff: https://github.com/llvm/llvm-project/pull/169920.diff

4 Files Affected:

  • (modified) llvm/test/MC/AArch64/seh-large-func-multi-epilog.s (+19-19)
  • (modified) llvm/test/MC/AArch64/seh-packed-epilog.s (+1-1)
  • (modified) llvm/test/MC/AArch64/seh-packed-unwind.s (+2-2)
  • (modified) llvm/test/MC/AArch64/seh.s (+64-42)
diff --git a/llvm/test/MC/AArch64/seh-large-func-multi-epilog.s b/llvm/test/MC/AArch64/seh-large-func-multi-epilog.s
index c2d7f94f7b11f..8c6864fe9e196 100644
--- a/llvm/test/MC/AArch64/seh-large-func-multi-epilog.s
+++ b/llvm/test/MC/AArch64/seh-large-func-multi-epilog.s
@@ -198,7 +198,7 @@ multi_epilog:
 	.seh_save_regp x25, 192
 	stp	x27, x28, [sp, #176]
 	.seh_save_regp x27, 176
-	mov	x29, fp
+	mov	x29, sp
 	.seh_set_fp
 	.seh_endprologue
         .rept 30
@@ -210,13 +210,13 @@ multi_epilog:
 	.seh_startepilogue
 	mov	sp, x29
 	.seh_set_fp
-	stp	x27, x28, [sp, #176]
+	ldp	x27, x28, [sp, #176]
 	.seh_save_regp x27, 176
-	stp	x25, x26, [sp, #192]
+	ldp	x25, x26, [sp, #192]
 	.seh_save_regp x25, 192
-	stp	x23, x24, [sp, #208]
+	ldp	x23, x24, [sp, #208]
 	.seh_save_regp x23, 208
-	stp	x21, x22, [sp, #224]
+	ldp	x21, x22, [sp, #224]
 	.seh_save_regp x21, 224
 	ldp	x19, x20, [sp, #240]
 	.seh_save_regp x19, 240
@@ -226,11 +226,11 @@ multi_epilog:
 	ret
 // epilog2 - a subsequence at the end of prolog, can use prolog's opcodes.
 	.seh_startepilogue
-	stp	x25, x26, [sp, #192]
+	ldp	x25, x26, [sp, #192]
 	.seh_save_regp x25, 192
-	stp	x23, x24, [sp, #208]
+	ldp	x23, x24, [sp, #208]
 	.seh_save_regp x23, 208
-	stp	x21, x22, [sp, #224]
+	ldp	x21, x22, [sp, #224]
 	.seh_save_regp x21, 224
 	ldp	x19, x20, [sp, #240]
 	.seh_save_regp x19, 240
@@ -242,9 +242,9 @@ multi_epilog:
 	.seh_startepilogue
 	mov	sp, x29
 	.seh_set_fp
-	stp	x23, x24, [sp, #208]
+	ldp	x23, x24, [sp, #208]
 	.seh_save_regp x23, 208
-	stp	x21, x22, [sp, #224]
+	ldp	x21, x22, [sp, #224]
 	.seh_save_regp x21, 224
 	ldp	x19, x20, [sp, #240]
 	.seh_save_regp x19, 240
@@ -261,13 +261,13 @@ multi_epilog:
 	.seh_startepilogue
 	mov	sp, x29
 	.seh_set_fp
-	stp	x27, x28, [sp, #176]
+	ldp	x27, x28, [sp, #176]
 	.seh_save_regp x27, 176
-	stp	x25, x26, [sp, #192]
+	ldp	x25, x26, [sp, #192]
 	.seh_save_regp x25, 192
-	stp	x23, x24, [sp, #208]
+	ldp	x23, x24, [sp, #208]
 	.seh_save_regp x23, 208
-	stp	x21, x22, [sp, #224]
+	ldp	x21, x22, [sp, #224]
 	.seh_save_regp x21, 224
 	ldp	x19, x20, [sp, #240]
 	.seh_save_regp x19, 240
@@ -277,11 +277,11 @@ multi_epilog:
 	ret
 // epilog5 - same as epilog2, its start index should be: 1 + epilog2's index.
 	.seh_startepilogue
-	stp	x25, x26, [sp, #192]
+	ldp	x25, x26, [sp, #192]
 	.seh_save_regp x25, 192
-	stp	x23, x24, [sp, #208]
+	ldp	x23, x24, [sp, #208]
 	.seh_save_regp x23, 208
-	stp	x21, x22, [sp, #224]
+	ldp	x21, x22, [sp, #224]
 	.seh_save_regp x21, 224
 	ldp	x19, x20, [sp, #240]
 	.seh_save_regp x19, 240
@@ -294,9 +294,9 @@ multi_epilog:
 	.seh_startepilogue
 	mov	sp, x29
 	.seh_set_fp
-	stp	x23, x24, [sp, #208]
+	ldp	x23, x24, [sp, #208]
 	.seh_save_regp x23, 208
-	stp	x21, x22, [sp, #224]
+	ldp	x21, x22, [sp, #224]
 	.seh_save_regp x21, 224
 	ldp	x19, x20, [sp, #240]
 	.seh_save_regp x19, 240
diff --git a/llvm/test/MC/AArch64/seh-packed-epilog.s b/llvm/test/MC/AArch64/seh-packed-epilog.s
index 85ac8e80dbdda..9fee71a10d445 100644
--- a/llvm/test/MC/AArch64/seh-packed-epilog.s
+++ b/llvm/test/MC/AArch64/seh-packed-epilog.s
@@ -126,7 +126,7 @@ func:
     .seh_set_fp
     ldp x29, x30, [sp, #16]
     .seh_save_fplr 16
-    ldp x29, x30, [sp, #-48]!
+    ldp x29, x30, [sp], #48
     .seh_save_fplr_x 48
     ldp x21, x22, [sp, #16]
     .seh_save_next
diff --git a/llvm/test/MC/AArch64/seh-packed-unwind.s b/llvm/test/MC/AArch64/seh-packed-unwind.s
index 5b86ab4bc0d49..9ffeef87803d7 100644
--- a/llvm/test/MC/AArch64/seh-packed-unwind.s
+++ b/llvm/test/MC/AArch64/seh-packed-unwind.s
@@ -814,7 +814,7 @@ nonpacked1:
     // Can't be packed; can't save integer registers after float registers.
     stp d8,  d9,  [sp, #-32]!
     .seh_save_fregp_x d8, 32
-    stp x19, x20, [sp, #16]!
+    stp x19, x20, [sp, #16]
     .seh_save_regp x19, 16
     .seh_endprologue
     nop
@@ -932,7 +932,7 @@ nonpacked6:
     .seh_startepilogue
     mov sp,  x29
     .seh_set_fp
-    ldp x29, lr,  [sp], #32
+    ldp x29, lr,  [sp], #16
     .seh_save_fplr_x 16
     ldr lr, [sp, #16]
     .seh_save_reg lr, 16
diff --git a/llvm/test/MC/AArch64/seh.s b/llvm/test/MC/AArch64/seh.s
index 5e194568f62dd..95411391710b4 100644
--- a/llvm/test/MC/AArch64/seh.s
+++ b/llvm/test/MC/AArch64/seh.s
@@ -1,6 +1,7 @@
 // This test checks that the SEH directives emit the correct unwind data.
 
-// RUN: llvm-mc -triple aarch64-pc-win32 -filetype=obj %s | llvm-readobj -S -r -u - | FileCheck %s
+// RUN: llvm-mc -triple aarch64-pc-win32 -filetype=obj %s -o %t.o
+// RUN: llvm-readobj -S -r -u %t.o | FileCheck %s
 
 // Check that the output assembler directives also can be parsed, and
 // that they produce equivalent output:
@@ -20,7 +21,7 @@
 // CHECK-NEXT:   }
 // CHECK:        Section {
 // CHECK:          Name: .xdata
-// CHECK:          RawDataSize: 100
+// CHECK:          RawDataSize: 108
 // CHECK:          RelocationCount: 1
 // CHECK:          Characteristics [
 // CHECK-NEXT:       ALIGN_4BYTES
@@ -30,7 +31,7 @@
 // CHECK-NEXT:   }
 // CHECK:        Section {
 // CHECK:          Name: .pdata
-// CHECK:          RelocationCount: 2
+// CHECK:          RelocationCount: 4
 // CHECK:          Characteristics [
 // CHECK-NEXT:       ALIGN_4BYTES
 // CHECK-NEXT:       CNT_INITIALIZED_DATA
@@ -41,11 +42,13 @@
 
 // CHECK-NEXT: Relocations [
 // CHECK-NEXT:   Section (4) .xdata {
-// CHECK-NEXT:     0x58 IMAGE_REL_ARM64_ADDR32NB __C_specific_handler
+// CHECK-NEXT:     0x54 IMAGE_REL_ARM64_ADDR32NB __C_specific_handler
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Section (5) .pdata {
 // CHECK-NEXT:     0x0 IMAGE_REL_ARM64_ADDR32NB .text
 // CHECK-NEXT:     0x4 IMAGE_REL_ARM64_ADDR32NB .xdata
+// CHECK-NEXT:     0x8 IMAGE_REL_ARM64_ADDR32NB .text
+// CHECK-NEXT:     0xC IMAGE_REL_ARM64_ADDR32NB .xdata
 // CHECK-NEXT:   }
 // CHECK-NEXT: ]
 
@@ -54,7 +57,7 @@
 // CHECK-NEXT:     Function: func
 // CHECK-NEXT:     ExceptionRecord: .xdata
 // CHECK-NEXT:     ExceptionData {
-// CHECK-NEXT:       FunctionLength: 172
+// CHECK-NEXT:       FunctionLength: 148
 // CHECK:            Prologue [
 // CHECK-NEXT:         0xe716c3            ; str p6, [sp, #3, mul vl]
 // CHECK-NEXT:         0xe703c5            ; str z11, [sp, #5, mul vl]
@@ -72,11 +75,6 @@
 // CHECK-NEXT:         0xe74104            ; stp x1, x2, [sp, #64]
 // CHECK-NEXT:         0xe70008            ; str x0, [sp, #64]
 // CHECK-NEXT:         0xfc                ; pacibsp
-// CHECK-NEXT:         0xec                ; clear unwound to call
-// CHECK-NEXT:         0xeb                ; EC context
-// CHECK-NEXT:         0xea                ; context
-// CHECK-NEXT:         0xe9                ; machine frame
-// CHECK-NEXT:         0xe8                ; trap frame
 // CHECK-NEXT:         0xe3                ; nop
 // CHECK-NEXT:         0xe202              ; add fp, sp, #16
 // CHECK-NEXT:         0xdd41              ; str d13, [sp, #8]
@@ -99,8 +97,8 @@
 // CHECK-NEXT:       ]
 // CHECK-NEXT:       EpilogueScopes [
 // CHECK-NEXT:         EpilogueScope {
-// CHECK-NEXT:           StartOffset: 41
-// CHECK-NEXT:           EpilogueStartIndex: 77
+// CHECK-NEXT:           StartOffset: 35
+// CHECK-NEXT:           EpilogueStartIndex: 72
 // CHECK-NEXT:           Opcodes [
 // CHECK-NEXT:             0x01                ; add sp, #16
 // CHECK-NEXT:             0xe4                ; end
@@ -113,9 +111,28 @@
 // CHECK-NEXT:       ]
 // CHECK-NEXT:     }
 // CHECK-NEXT:   }
+// CHECK-NEXT:   RuntimeFunction {
+// CHECK-NEXT:     Function: customfunc
+// CHECK-NEXT:     ExceptionRecord: .xdata
+// CHECK-NEXT:     ExceptionData {
+// CHECK-NEXT:       FunctionLength: 24
+// CHECK:            Prologue [
+// CHECK-NEXT:         0xec                ; clear unwound to call
+// CHECK-NEXT:         0xeb                ; EC context
+// CHECK-NEXT:         0xea                ; context
+// CHECK-NEXT:         0xe9                ; machine frame
+// CHECK-NEXT:         0xe8                ; trap frame
+// CHECK-NEXT:         0xe4                ; end
+// CHECK-NEXT:       ]
+// CHECK-NEXT:       EpilogueScopes [
+// CHECK-NEXT:       ]
+// CHECK-NEXT:     }
+// CHECK-NEXT:   }
 // CHECK-NEXT: ]
 
 
+    .arch_extension sve
+
     .text
     .globl func
     .def func
@@ -124,8 +141,8 @@
     .endef
     .seh_proc func
 func:
-    sub sp, sp, #24
-    .seh_stackalloc 24
+    sub sp, sp, #16
+    .seh_stackalloc 16
     mov x29, sp
     .seh_set_fp
     stp x29, x30, [sp, #-32]!
@@ -160,54 +177,43 @@ func:
     .seh_add_fp 16
     nop
     .seh_nop
-    nop
-    .seh_trap_frame
-    nop
-    .seh_pushframe
-    nop
-    .seh_context
-    nop
-    .seh_ec_context
-    nop
-    .seh_clear_unwound_to_call
     pacibsp
     .seh_pac_sign_lr
-    nop
+    str x0, [sp, #64]
     .seh_save_any_reg x0, 64
-    nop
+    stp x1, x2, [sp, #64]
     .seh_save_any_reg_p x1, 64
-    nop
+    str d29, [sp, #64]
     .seh_save_any_reg d29, 64
-    nop
+    stp d4, d5, [sp, #64]
     .seh_save_any_reg_p d4, 64
-    nop
+    str q30, [sp, #64]
     .seh_save_any_reg q30, 64
-    nop
+    stp q3, q4, [sp, #64]
     .seh_save_any_reg_p q3, 64
-    nop
+    str x30, [sp, #-64]!
     .seh_save_any_reg_x lr, 64
-    nop
+    stp x29, x30, [sp, #-64]!
     .seh_save_any_reg_px fp, 64
-    nop
+    str d31, [sp, #-64]!
     .seh_save_any_reg_x d31, 64
-    nop
+    stp d2, d3, [sp, #-64]!
     .seh_save_any_reg_px d2, 64
-    nop
+    str q29, [sp, #-64]!
     .seh_save_any_reg_x q29, 64
-    nop
+    stp q9, q10, [sp, #-64]!
     .seh_save_any_reg_px q9, 64
-    nop
+    addvl sp, sp, #-5
     .seh_allocz 5
-    nop
+    str z11, [sp, #5, mul vl]
     .seh_save_zreg z11, 5
-    nop
+    str p6, [sp, #3, mul vl]
     .seh_save_preg p6, 3
-    nop
     .seh_endprologue
     nop
     .seh_startepilogue
-    add sp, sp, #24
-    .seh_stackalloc 24
+    add sp, sp, #16
+    .seh_stackalloc 16
     .seh_endepilogue
     ret
     .seh_handler __C_specific_handler, @except
@@ -216,6 +222,22 @@ func:
     .text
     .seh_endproc
 
+    .seh_proc customfunc
+customfunc:
+    nop
+    .seh_trap_frame
+    nop
+    .seh_pushframe
+    nop
+    .seh_context
+    nop
+    .seh_ec_context
+    nop
+    .seh_clear_unwound_to_call
+    .seh_endprologue
+    ret
+    .seh_endproc
+
     // Function with no .seh directives; no pdata/xdata entries are
     // generated.
     .globl smallFunc

@mstorsjo
Copy link
Member Author

As this is a series of smaller individual changes, I'd prefer to submit them as such (via a manual merge/push), but I'm posting them all in one single PR (see the individual PR descriptions for explanation of each step) to avoid spamming that many individual PRs for essentially the same.

Copy link
Collaborator

@efriedma-quic efriedma-quic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks.

This is what is done in other tests; this makes it easier to
inspect the output of this test manually.
…unction

These custom opcodes disable the checker for having the prologue
length actually match the opcodes (see checkARM64Instructions in
MCWin64EH.cpp) - which led to the prologue mismatching the opcodes
by one instruction, since 312d6b4.

Move the special opcodes to a separate test function.

Remove the mismatched nop instruction at the end of the main
function, as this prologue now is assembled with the strict length
checking enabled.
The actual unwind opcodes only stores stack increments in units
of 16 (which is what it is listed as in the unwind opcode
dumping by llvm-readobj); actually write what we intend to encode.
…pcodes

The MS dumpbin.exe tool can dump the unwind opcodes with the
"-unwindinfo" option; this mode also checks that the instructions
actually match the expected ones here. (This mode doesn't seem
to fully work for all instructions here, but spell out all the
intended instructions here.)
…ctions

This makes them match the expected decoding of the unwind info
opcodes, avoiding mismatch indications from "dumpbin -unwindinfo".
@mstorsjo mstorsjo force-pushed the arm64-seh-testcase-fixup branch from e6c8853 to 4580350 Compare December 2, 2025 11:35
@mstorsjo mstorsjo merged commit 4580350 into llvm:main Dec 2, 2025
5 of 9 checks passed
@mstorsjo mstorsjo deleted the arm64-seh-testcase-fixup branch December 2, 2025 11:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants