1
- ; RUN: llc -mtriple=aarch64 < %s | FileCheck --check-prefixes CHECK,CHECK-V8A %s
2
- ; RUN: llc -mtriple=aarch64 -mattr=v8.3a < %s | FileCheck --check-prefixes CHECK,CHECK-V83A %s
1
+ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
2
+ ; RUN: llc -mtriple=aarch64 < %s | FileCheck --check-prefixes CHECK-V8A %s
3
+ ; RUN: llc -mtriple=aarch64 -mattr=v8.3a < %s | FileCheck --check-prefixes CHECK-V83A %s
3
4
; RUN: llc -mtriple=aarch64 -filetype=obj -o - <%s | llvm-dwarfdump -v - | FileCheck --check-prefix=CHECK-DUMP %s
4
5
5
6
@.str = private unnamed_addr constant [15 x i8 ] c "some exception\00 " , align 1
6
7
@_ZTIPKc = external dso_local constant ptr
7
8
8
- ; CHECK: @_Z3fooi
9
- ; CHECK-V8A: hint #25
10
- ; CHECK-V83A: paciasp
11
- ; CHECK-NEXT: .cfi_negate_ra_state
12
- ; CHECK-NOT: .cfi_negate_ra_state
13
9
define dso_local i32 @_Z3fooi (i32 %x ) #0 {
10
+ ; CHECK-V8A-LABEL: _Z3fooi:
11
+ ; CHECK-V8A: // %bb.0: // %entry
12
+ ; CHECK-V8A-NEXT: hint #25
13
+ ; CHECK-V8A-NEXT: .cfi_negate_ra_state
14
+ ; CHECK-V8A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
15
+ ; CHECK-V8A-NEXT: .cfi_def_cfa_offset 16
16
+ ; CHECK-V8A-NEXT: .cfi_offset w30, -16
17
+ ; CHECK-V8A-NEXT: str w0, [sp, #8]
18
+ ; CHECK-V8A-NEXT: mov w0, #8 // =0x8
19
+ ; CHECK-V8A-NEXT: bl __cxa_allocate_exception
20
+ ; CHECK-V8A-NEXT: adrp x8, .L.str
21
+ ; CHECK-V8A-NEXT: add x8, x8, :lo12:.L.str
22
+ ; CHECK-V8A-NEXT: adrp x1, _ZTIPKc
23
+ ; CHECK-V8A-NEXT: add x1, x1, :lo12:_ZTIPKc
24
+ ; CHECK-V8A-NEXT: mov x2, xzr
25
+ ; CHECK-V8A-NEXT: str x8, [x0]
26
+ ; CHECK-V8A-NEXT: bl __cxa_throw
27
+ ;
28
+ ; CHECK-V83A-LABEL: _Z3fooi:
29
+ ; CHECK-V83A: // %bb.0: // %entry
30
+ ; CHECK-V83A-NEXT: paciasp
31
+ ; CHECK-V83A-NEXT: .cfi_negate_ra_state
32
+ ; CHECK-V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
33
+ ; CHECK-V83A-NEXT: .cfi_def_cfa_offset 16
34
+ ; CHECK-V83A-NEXT: .cfi_offset w30, -16
35
+ ; CHECK-V83A-NEXT: str w0, [sp, #8]
36
+ ; CHECK-V83A-NEXT: mov w0, #8 // =0x8
37
+ ; CHECK-V83A-NEXT: bl __cxa_allocate_exception
38
+ ; CHECK-V83A-NEXT: adrp x8, .L.str
39
+ ; CHECK-V83A-NEXT: add x8, x8, :lo12:.L.str
40
+ ; CHECK-V83A-NEXT: adrp x1, _ZTIPKc
41
+ ; CHECK-V83A-NEXT: add x1, x1, :lo12:_ZTIPKc
42
+ ; CHECK-V83A-NEXT: mov x2, xzr
43
+ ; CHECK-V83A-NEXT: str x8, [x0]
44
+ ; CHECK-V83A-NEXT: bl __cxa_throw
14
45
entry:
15
46
%retval = alloca i32 , align 4
16
47
%x.addr = alloca i32 , align 4
@@ -25,10 +56,175 @@ return: ; No predecessors!
25
56
ret i32 %0
26
57
}
27
58
59
+ ; For asynchronous unwind tables, we need to flip the value of RA_SIGN_STATE
60
+ ; before and after the tail call.
61
+ define hidden noundef i32 @baz_async (i32 noundef %a ) #0 uwtable (async) {
62
+ ; CHECK-V8A-LABEL: baz_async:
63
+ ; CHECK-V8A: // %bb.0: // %entry
64
+ ; CHECK-V8A-NEXT: hint #25
65
+ ; CHECK-V8A-NEXT: .cfi_negate_ra_state
66
+ ; CHECK-V8A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
67
+ ; CHECK-V8A-NEXT: .cfi_def_cfa_offset 16
68
+ ; CHECK-V8A-NEXT: .cfi_offset w30, -16
69
+ ; CHECK-V8A-NEXT: .cfi_remember_state
70
+ ; CHECK-V8A-NEXT: cbz w0, .LBB1_2
71
+ ; CHECK-V8A-NEXT: // %bb.1: // %if.then
72
+ ; CHECK-V8A-NEXT: mov w0, wzr
73
+ ; CHECK-V8A-NEXT: bl _Z3bari
74
+ ; CHECK-V8A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
75
+ ; CHECK-V8A-NEXT: .cfi_def_cfa_offset 0
76
+ ; CHECK-V8A-NEXT: hint #29
77
+ ; CHECK-V8A-NEXT: .cfi_negate_ra_state
78
+ ; CHECK-V8A-NEXT: .cfi_restore w30
79
+ ; CHECK-V8A-NEXT: b _Z3bari
80
+ ; CHECK-V8A-NEXT: .LBB1_2: // %if.else
81
+ ; CHECK-V8A-NEXT: .cfi_restore_state
82
+ ; CHECK-V8A-NEXT: bl _Z4quuxi
83
+ ; CHECK-V8A-NEXT: add w0, w0, #1
84
+ ; CHECK-V8A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
85
+ ; CHECK-V8A-NEXT: .cfi_def_cfa_offset 0
86
+ ; CHECK-V8A-NEXT: hint #29
87
+ ; CHECK-V8A-NEXT: .cfi_negate_ra_state
88
+ ; CHECK-V8A-NEXT: .cfi_restore w30
89
+ ; CHECK-V8A-NEXT: ret
90
+ ;
91
+ ; CHECK-V83A-LABEL: baz_async:
92
+ ; CHECK-V83A: // %bb.0: // %entry
93
+ ; CHECK-V83A-NEXT: paciasp
94
+ ; CHECK-V83A-NEXT: .cfi_negate_ra_state
95
+ ; CHECK-V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
96
+ ; CHECK-V83A-NEXT: .cfi_def_cfa_offset 16
97
+ ; CHECK-V83A-NEXT: .cfi_offset w30, -16
98
+ ; CHECK-V83A-NEXT: .cfi_remember_state
99
+ ; CHECK-V83A-NEXT: cbz w0, .LBB1_2
100
+ ; CHECK-V83A-NEXT: // %bb.1: // %if.then
101
+ ; CHECK-V83A-NEXT: mov w0, wzr
102
+ ; CHECK-V83A-NEXT: bl _Z3bari
103
+ ; CHECK-V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
104
+ ; CHECK-V83A-NEXT: .cfi_def_cfa_offset 0
105
+ ; CHECK-V83A-NEXT: autiasp
106
+ ; CHECK-V83A-NEXT: .cfi_negate_ra_state
107
+ ; CHECK-V83A-NEXT: .cfi_restore w30
108
+ ; CHECK-V83A-NEXT: b _Z3bari
109
+ ; CHECK-V83A-NEXT: .LBB1_2: // %if.else
110
+ ; CHECK-V83A-NEXT: .cfi_restore_state
111
+ ; CHECK-V83A-NEXT: bl _Z4quuxi
112
+ ; CHECK-V83A-NEXT: add w0, w0, #1
113
+ ; CHECK-V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
114
+ ; CHECK-V83A-NEXT: .cfi_def_cfa_offset 0
115
+ ; CHECK-V83A-NEXT: .cfi_restore w30
116
+ ; CHECK-V83A-NEXT: retaa
117
+ entry:
118
+ %tobool.not = icmp eq i32 %a , 0
119
+ br i1 %tobool.not , label %if.else , label %if.then
120
+
121
+ if.then: ; preds = %entry
122
+ %call = tail call noundef i32 @_Z3bari (i32 noundef 0 )
123
+ %call1 = tail call noundef i32 @_Z3bari (i32 noundef %call )
124
+ br label %return
125
+
126
+ if.else: ; preds = %entry
127
+ %call2 = tail call noundef i32 @_Z4quuxi (i32 noundef 0 )
128
+ %add = add nsw i32 %call2 , 1
129
+ br label %return
130
+
131
+ return: ; preds = %if.else, %if.then
132
+ %retval.0 = phi i32 [ %call1 , %if.then ], [ %add , %if.else ]
133
+ ret i32 %retval.0
134
+ }
135
+
136
+ ; For synchronous unwind tables, we don't need to update the unwind tables
137
+ ; around the tail call. The tail-called function might throw an exception, but
138
+ ; at this point we are set up to return into baz's caller, so the unwinder will
139
+ ; never see baz's unwind table for that exception.
140
+ define hidden noundef i32 @baz_sync (i32 noundef %a ) #0 uwtable (sync) {
141
+ ; CHECK-V8A-LABEL: baz_sync:
142
+ ; CHECK-V8A: // %bb.0: // %entry
143
+ ; CHECK-V8A-NEXT: hint #25
144
+ ; CHECK-V8A-NEXT: .cfi_negate_ra_state
145
+ ; CHECK-V8A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
146
+ ; CHECK-V8A-NEXT: .cfi_def_cfa_offset 16
147
+ ; CHECK-V8A-NEXT: .cfi_offset w30, -16
148
+ ; CHECK-V8A-NEXT: cbz w0, .LBB2_2
149
+ ; CHECK-V8A-NEXT: // %bb.1: // %if.then
150
+ ; CHECK-V8A-NEXT: mov w0, wzr
151
+ ; CHECK-V8A-NEXT: bl _Z3bari
152
+ ; CHECK-V8A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
153
+ ; CHECK-V8A-NEXT: hint #29
154
+ ; CHECK-V8A-NEXT: b _Z3bari
155
+ ; CHECK-V8A-NEXT: .LBB2_2: // %if.else
156
+ ; CHECK-V8A-NEXT: bl _Z4quuxi
157
+ ; CHECK-V8A-NEXT: add w0, w0, #1
158
+ ; CHECK-V8A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
159
+ ; CHECK-V8A-NEXT: hint #29
160
+ ; CHECK-V8A-NEXT: ret
161
+ ;
162
+ ; CHECK-V83A-LABEL: baz_sync:
163
+ ; CHECK-V83A: // %bb.0: // %entry
164
+ ; CHECK-V83A-NEXT: paciasp
165
+ ; CHECK-V83A-NEXT: .cfi_negate_ra_state
166
+ ; CHECK-V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
167
+ ; CHECK-V83A-NEXT: .cfi_def_cfa_offset 16
168
+ ; CHECK-V83A-NEXT: .cfi_offset w30, -16
169
+ ; CHECK-V83A-NEXT: cbz w0, .LBB2_2
170
+ ; CHECK-V83A-NEXT: // %bb.1: // %if.then
171
+ ; CHECK-V83A-NEXT: mov w0, wzr
172
+ ; CHECK-V83A-NEXT: bl _Z3bari
173
+ ; CHECK-V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
174
+ ; CHECK-V83A-NEXT: autiasp
175
+ ; CHECK-V83A-NEXT: b _Z3bari
176
+ ; CHECK-V83A-NEXT: .LBB2_2: // %if.else
177
+ ; CHECK-V83A-NEXT: bl _Z4quuxi
178
+ ; CHECK-V83A-NEXT: add w0, w0, #1
179
+ ; CHECK-V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
180
+ ; CHECK-V83A-NEXT: retaa
181
+ entry:
182
+ %tobool.not = icmp eq i32 %a , 0
183
+ br i1 %tobool.not , label %if.else , label %if.then
184
+
185
+ if.then: ; preds = %entry
186
+ %call = tail call noundef i32 @_Z3bari (i32 noundef 0 )
187
+ %call1 = tail call noundef i32 @_Z3bari (i32 noundef %call )
188
+ br label %return
189
+
190
+ if.else: ; preds = %entry
191
+ %call2 = tail call noundef i32 @_Z4quuxi (i32 noundef 0 )
192
+ %add = add nsw i32 %call2 , 1
193
+ br label %return
194
+
195
+ return: ; preds = %if.else, %if.then
196
+ %retval.0 = phi i32 [ %call1 , %if.then ], [ %add , %if.else ]
197
+ ret i32 %retval.0
198
+ }
199
+
28
200
declare dso_local ptr @__cxa_allocate_exception (i64 )
29
201
30
202
declare dso_local void @__cxa_throw (ptr , ptr , ptr )
31
203
204
+ declare dso_local noundef i32 @_Z3bari (i32 noundef) local_unnamed_addr
205
+ declare dso_local noundef i32 @_Z4quuxi (i32 noundef) local_unnamed_addr
206
+
32
207
attributes #0 = { "sign-return-address" ="all" }
33
208
34
- ;CHECK-DUMP: DW_CFA_AARCH64_negate_ra_state
209
+ ; foo
210
+ ; CHECK-DUMP-LABEL: FDE
211
+ ; CHECK-DUMP: DW_CFA_AARCH64_negate_ra_state:
212
+ ; CHECK-DUMP-NOT: DW_CFA_AARCH64_negate_ra_state
213
+ ; CHECK-DUMP-NOT: DW_CFA_remember_state
214
+ ; CHECK-DUMP-NOT: DW_CFA_restore_state
215
+
216
+ ; baz_async
217
+ ; CHECK-DUMP-LABEL: FDE
218
+ ; CHECK-DUMP: Format: DWARF32
219
+ ; CHECK-DUMP: DW_CFA_AARCH64_negate_ra_state:
220
+ ; CHECK-DUMP: DW_CFA_remember_state:
221
+ ; CHECK-DUMP: DW_CFA_AARCH64_negate_ra_state:
222
+ ; CHECK-DUMP: DW_CFA_restore_state:
223
+ ; CHECK-DUMP: DW_CFA_AARCH64_negate_ra_state:
224
+
225
+ ; baz_sync
226
+ ; CHECK-DUMP-LABEL: FDE
227
+ ; CHECK-DUMP: DW_CFA_AARCH64_negate_ra_state:
228
+ ; CHECK-DUMP-NOT: DW_CFA_AARCH64_negate_ra_state
229
+ ; CHECK-DUMP-NOT: DW_CFA_remember_state
230
+ ; CHECK-DUMP-NOT: DW_CFA_restore_state
0 commit comments