xref: /llvm-project/llvm/test/CodeGen/AArch64/wineh1.mir (revision cabefea2ec99f80ecdf9d3d5fe955831532ff4b0)
1# RUN: llc -o - %s -mtriple=aarch64-windows -start-after=prologepilog -filetype=obj  \
2# RUN:   | llvm-readobj --unwind - | FileCheck %s
3# RUN: llc -o - %s -mtriple=aarch64-windows -run-pass=aarch64-ldst-opt \
4# RUN:   | FileCheck %s --check-prefix=CHECK-LDSTOPT
5# This test case checks the basic validity of the .xdata section.  It's
6# documented at:
7# https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling
8
9# Also test the generated assembler SEH directives.
10# RUN: llc -o - %s -mtriple=aarch64-windows -start-after=prologepilog -filetype=asm  \
11# RUN:   | FileCheck %s --check-prefix=ASM
12
13# We expect to see the following in the .xdata section:
14
15# CHECK: 	 ExceptionData {
16# CHECK-NEXT:      FunctionLength: 96
17# CHECK-NEXT:      Version: 0
18# CHECK-NEXT:      ExceptionData: No
19# CHECK-NEXT:      EpiloguePacked: Yes
20# CHECK-NEXT:      EpilogueOffset: 13
21# CHECK-NEXT:      ByteCodeLength: 28
22# CHECK-NEXT:      Prologue [
23# CHECK-NEXT:        0xc808              ; stp x19, x20, [sp, #64]
24# CHECK-NEXT:        0xd0c7              ; str x22, [sp, #56]
25# CHECK-NEXT:        0xd086              ; str x21, [sp, #48]
26# CHECK-NEXT:        0xc904              ; stp x23, x24, [sp, #32]
27# CHECK-NEXT:        0xc982              ; stp x25, x26, [sp, #16]
28# CHECK-NEXT:        0xce09              ; stp x27, x28, [sp, #-80]!
29# CHECK-NEXT:        0xe4                ; end
30# CHECK-NEXT:      ]
31# CHECK-NEXT:      Epilogue [
32# CHECK-NEXT:        0xc808              ; ldp x19, x20, [sp, #64]
33# CHECK-NEXT:        0xd086              ; ldr x21, [sp, #48]
34# CHECK-NEXT:        0xe3                ; nop
35# CHECK-NEXT:        0xd0c7              ; ldr x22, [sp, #56]
36# CHECK-NEXT:        0xc904              ; ldp x23, x24, [sp, #32]
37# CHECK-NEXT:        0xc982              ; ldp x25, x26, [sp, #16]
38# CHECK-NEXT:        0xce09              ; ldp x27, x28, [sp], #80
39# CHECK-NEXT:        0xe4                ; end
40# CHECK-NEXT:      ]
41# CHECK-NEXT:    }
42
43# Check that the load-store optimizer does not merge the two
44# callee-saved stores in the prologue.
45# CHECK-LDSTOPT: name: test
46# CHECK-LDSTOPT: frame-setup STRXui killed $x21, $sp, 6
47# CHECK-LDSTOPT: frame-setup STRXui killed $x22, $sp, 7
48
49# ASM-LABEL: test:
50# ASM: .seh_proc test
51# ASM: .seh_save_regp_x x27, 80
52# ASM: .seh_save_regp x25, 16
53# ASM: .seh_save_regp x23, 32
54# ASM: .seh_save_reg x21, 48
55# ASM: .seh_save_reg x22, 56
56# ASM: .seh_save_regp x19, 64
57# ASM: .seh_endprologue
58
59# ASM: .seh_startepilogue
60# ASM: .seh_save_regp x19, 64
61# ASM: .seh_save_reg x21, 48
62# ASM: .seh_nop
63# ASM: .seh_save_reg x22, 56
64# ASM: .seh_save_regp x23, 32
65# ASM: .seh_save_regp x25, 16
66# ASM: .seh_save_regp_x x27, 80
67# ASM: .seh_endepilogue
68
69# ASM: .seh_endfunclet
70# ASM: .seh_endproc
71
72...
73---
74name:            test
75alignment:       4
76tracksRegLiveness: true
77hasWinCFI: true
78liveins:
79  - { reg: '$w0' }
80frameInfo:
81  stackSize:       80
82  maxAlignment:    8
83  maxCallFrameSize: 0
84  hasOpaqueSPAdjustment: true
85stack:
86  - { id: 0, type: spill-slot, offset: -8, size: 8, alignment: 8, stack-id: default,
87      callee-saved-register: '$x19' }
88  - { id: 1, type: spill-slot, offset: -16, size: 8, alignment: 8, stack-id: default,
89      callee-saved-register: '$x20' }
90  - { id: 2, type: spill-slot, offset: -24, size: 8, alignment: 8, stack-id: default,
91      callee-saved-register: '$x21' }
92  - { id: 3, type: spill-slot, offset: -32, size: 8, alignment: 8, stack-id: default,
93      callee-saved-register: '$x22' }
94  - { id: 4, type: spill-slot, offset: -40, size: 8, alignment: 8, stack-id: default,
95      callee-saved-register: '$x23' }
96  - { id: 5, type: spill-slot, offset: -48, size: 8, alignment: 8, stack-id: default,
97      callee-saved-register: '$x24' }
98  - { id: 6, type: spill-slot, offset: -56, size: 8, alignment: 8, stack-id: default,
99      callee-saved-register: '$x25' }
100  - { id: 7, type: spill-slot, offset: -64, size: 8, alignment: 8, stack-id: default,
101      callee-saved-register: '$x26' }
102  - { id: 8, type: spill-slot, offset: -72, size: 8, alignment: 8, stack-id: default,
103      callee-saved-register: '$x27' }
104  - { id: 9, type: spill-slot, offset: -80, size: 8, alignment: 8, stack-id: default,
105      callee-saved-register: '$x28' }
106body:             |
107  bb.0.entry:
108    liveins: $x0, $x1, $x27, $x28, $x25, $x26, $x23, $x24, $x21, $x22, $x19, $x20
109    early-clobber $sp = frame-setup STPXpre killed $x27, killed $x28, $sp, -10 :: (store (s64) into %stack.8), (store (s64) into %stack.9)
110    frame-setup SEH_SaveRegP_X 27, 28, -80
111    frame-setup STPXi killed $x25, killed $x26, $sp, 2 :: (store (s64) into %stack.6), (store (s64) into %stack.7)
112    frame-setup SEH_SaveRegP 25, 26, 16
113    frame-setup STPXi killed $x23, killed $x24, $sp, 4 :: (store (s64) into %stack.4), (store (s64) into %stack.5)
114    frame-setup SEH_SaveRegP 23, 24, 32
115    frame-setup STRXui killed $x21, $sp, 6 :: (store (s64) into %stack.2)
116    frame-setup SEH_SaveReg 21, 48
117    frame-setup STRXui killed $x22, $sp, 7 :: (store (s64) into %stack.3)
118    frame-setup SEH_SaveReg 22, 56
119    frame-setup STPXi killed $x19, killed $x20, $sp, 8 :: (store (s64) into %stack.0), (store (s64) into %stack.1)
120    frame-setup SEH_SaveRegP 19, 20, 64
121    frame-setup SEH_PrologEnd
122    $x19 = ADDXrr $x0, killed $x1
123    $x20 = ADDXrr $x19, killed $x0
124    $x21 = ADDXrr $x20, killed $x19
125    $x22 = ADDXrr $x21, killed $x20
126    $x23 = ADDXrr $x22, killed $x21
127    $x24 = ADDXrr $x23, killed $x22
128    $x25 = ADDXrr $x24, killed $x23
129    $x26 = ADDXrr $x25, killed $x24
130    $x27 = ADDXrr $x26, killed $x25
131    $x28 = ADDXrr $x27, killed $x26
132    frame-destroy SEH_EpilogStart
133    $x19, $x20 = frame-destroy LDPXi $sp, 8 :: (load (s64) from %stack.0), (load (s64) from %stack.1)
134    frame-destroy SEH_SaveRegP 19, 20, 64
135    $x21 = frame-destroy LDRXui $sp, 6 :: (load (s64) from %stack.2)
136    frame-destroy SEH_SaveReg 21, 48
137    $x0 = COPY $x28
138    frame-destroy SEH_Nop
139    $x21 = frame-destroy LDRXui $sp, 6 :: (load (s64) from %stack.2)
140    frame-destroy SEH_SaveReg 22, 56
141    $x23, $x24 = frame-destroy LDPXi $sp, 4 :: (load (s64) from %stack.4), (load (s64) from %stack.5)
142    frame-destroy SEH_SaveRegP 23, 24, 32
143    $x25, $x26 = frame-destroy LDPXi $sp, 2 :: (load (s64) from %stack.6), (load (s64) from %stack.7)
144    frame-destroy SEH_SaveRegP 25, 26, 16
145    early-clobber $sp, $x27, $x28 = frame-destroy LDPXpost $sp, 10 :: (load (s64) from %stack.8), (load (s64) from %stack.9)
146    frame-destroy SEH_SaveRegP_X 27, 28, -80
147    frame-destroy SEH_EpilogEnd
148    RET_ReallyLR implicit $x0
149
150...
151