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
4 ; RUN: llc -mtriple=aarch64 -filetype=obj -o - <%s | llvm-dwarfdump -v - | FileCheck --check-prefix=CHECK-DUMP %s
6 @.str = private unnamed_addr constant [15 x i8] c"some exception\00", align 1
7 @_ZTIPKc = external dso_local constant ptr
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: str x30, [sp, #-16]! // 8-byte Folded Spill
14 ; CHECK-V8A-NEXT: .cfi_negate_ra_state
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
28 ; CHECK-V83A-LABEL: _Z3fooi:
29 ; CHECK-V83A: // %bb.0: // %entry
30 ; CHECK-V83A-NEXT: paciasp
31 ; CHECK-V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
32 ; CHECK-V83A-NEXT: .cfi_negate_ra_state
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
46 %retval = alloca i32, align 4
47 %x.addr = alloca i32, align 4
48 store i32 %x, ptr %x.addr, align 4
49 %exception = call ptr @__cxa_allocate_exception(i64 8) #1
50 store ptr @.str, ptr %exception, align 16
51 call void @__cxa_throw(ptr %exception, ptr @_ZTIPKc, ptr null) #2
54 return: ; No predecessors!
55 %0 = load i32, ptr %retval, align 4
59 ; For asynchronous unwind tables, we need to flip the value of RA_SIGN_STATE
60 ; before and after the tail call. In the prolog, RA_SIGN_STATE is updated right
61 ; after the corresponding 'PACIASP' instruction.
62 define hidden noundef i32 @baz_async(i32 noundef %a) #0 uwtable(async) {
63 ; CHECK-V8A-LABEL: baz_async:
64 ; CHECK-V8A: // %bb.0: // %entry
65 ; CHECK-V8A-NEXT: hint #25
66 ; CHECK-V8A-NEXT: .cfi_negate_ra_state
67 ; CHECK-V8A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
68 ; CHECK-V8A-NEXT: .cfi_def_cfa_offset 16
69 ; CHECK-V8A-NEXT: .cfi_offset w30, -16
70 ; CHECK-V8A-NEXT: .cfi_remember_state
71 ; CHECK-V8A-NEXT: cbz w0, .LBB1_2
72 ; CHECK-V8A-NEXT: // %bb.1: // %if.then
73 ; CHECK-V8A-NEXT: mov w0, wzr
74 ; CHECK-V8A-NEXT: bl _Z3bari
75 ; CHECK-V8A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
76 ; CHECK-V8A-NEXT: .cfi_def_cfa_offset 0
77 ; CHECK-V8A-NEXT: hint #29
78 ; CHECK-V8A-NEXT: .cfi_negate_ra_state
79 ; CHECK-V8A-NEXT: .cfi_restore w30
80 ; CHECK-V8A-NEXT: b _Z3bari
81 ; CHECK-V8A-NEXT: .LBB1_2: // %if.else
82 ; CHECK-V8A-NEXT: .cfi_restore_state
83 ; CHECK-V8A-NEXT: bl _Z4quuxi
84 ; CHECK-V8A-NEXT: add w0, w0, #1
85 ; CHECK-V8A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
86 ; CHECK-V8A-NEXT: .cfi_def_cfa_offset 0
87 ; CHECK-V8A-NEXT: hint #29
88 ; CHECK-V8A-NEXT: .cfi_negate_ra_state
89 ; CHECK-V8A-NEXT: .cfi_restore w30
92 ; CHECK-V83A-LABEL: baz_async:
93 ; CHECK-V83A: // %bb.0: // %entry
94 ; CHECK-V83A-NEXT: paciasp
95 ; CHECK-V83A-NEXT: .cfi_negate_ra_state
96 ; CHECK-V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
97 ; CHECK-V83A-NEXT: .cfi_def_cfa_offset 16
98 ; CHECK-V83A-NEXT: .cfi_offset w30, -16
99 ; CHECK-V83A-NEXT: .cfi_remember_state
100 ; CHECK-V83A-NEXT: cbz w0, .LBB1_2
101 ; CHECK-V83A-NEXT: // %bb.1: // %if.then
102 ; CHECK-V83A-NEXT: mov w0, wzr
103 ; CHECK-V83A-NEXT: bl _Z3bari
104 ; CHECK-V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
105 ; CHECK-V83A-NEXT: .cfi_def_cfa_offset 0
106 ; CHECK-V83A-NEXT: autiasp
107 ; CHECK-V83A-NEXT: .cfi_negate_ra_state
108 ; CHECK-V83A-NEXT: .cfi_restore w30
109 ; CHECK-V83A-NEXT: b _Z3bari
110 ; CHECK-V83A-NEXT: .LBB1_2: // %if.else
111 ; CHECK-V83A-NEXT: .cfi_restore_state
112 ; CHECK-V83A-NEXT: bl _Z4quuxi
113 ; CHECK-V83A-NEXT: add w0, w0, #1
114 ; CHECK-V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
115 ; CHECK-V83A-NEXT: .cfi_def_cfa_offset 0
116 ; CHECK-V83A-NEXT: .cfi_restore w30
117 ; CHECK-V83A-NEXT: retaa
119 %tobool.not = icmp eq i32 %a, 0
120 br i1 %tobool.not, label %if.else, label %if.then
122 if.then: ; preds = %entry
123 %call = tail call noundef i32 @_Z3bari(i32 noundef 0)
124 %call1 = tail call noundef i32 @_Z3bari(i32 noundef %call)
127 if.else: ; preds = %entry
128 %call2 = tail call noundef i32 @_Z4quuxi(i32 noundef 0)
129 %add = add nsw i32 %call2, 1
132 return: ; preds = %if.else, %if.then
133 %retval.0 = phi i32 [ %call1, %if.then ], [ %add, %if.else ]
137 ; For synchronous unwind tables, we don't need to update the unwind tables
138 ; around the tail call. The tail-called function might throw an exception, but
139 ; at this point we are set up to return into baz's caller, so the unwinder will
140 ; never see baz's unwind table for that exception.
141 ; The '.cfi_negate_ra_state' instruction in the prolog can be bundled with other
142 ; CFI instructions to avoid emitting superfluous DW_CFA_advance_loc.
143 define hidden noundef i32 @baz_sync(i32 noundef %a) #0 uwtable(sync) {
144 ; CHECK-V8A-LABEL: baz_sync:
145 ; CHECK-V8A: // %bb.0: // %entry
146 ; CHECK-V8A-NEXT: hint #25
147 ; CHECK-V8A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
148 ; CHECK-V8A-NEXT: .cfi_negate_ra_state
149 ; CHECK-V8A-NEXT: .cfi_def_cfa_offset 16
150 ; CHECK-V8A-NEXT: .cfi_offset w30, -16
151 ; CHECK-V8A-NEXT: cbz w0, .LBB2_2
152 ; CHECK-V8A-NEXT: // %bb.1: // %if.then
153 ; CHECK-V8A-NEXT: mov w0, wzr
154 ; CHECK-V8A-NEXT: bl _Z3bari
155 ; CHECK-V8A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
156 ; CHECK-V8A-NEXT: hint #29
157 ; CHECK-V8A-NEXT: b _Z3bari
158 ; CHECK-V8A-NEXT: .LBB2_2: // %if.else
159 ; CHECK-V8A-NEXT: bl _Z4quuxi
160 ; CHECK-V8A-NEXT: add w0, w0, #1
161 ; CHECK-V8A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
162 ; CHECK-V8A-NEXT: hint #29
163 ; CHECK-V8A-NEXT: ret
165 ; CHECK-V83A-LABEL: baz_sync:
166 ; CHECK-V83A: // %bb.0: // %entry
167 ; CHECK-V83A-NEXT: paciasp
168 ; CHECK-V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
169 ; CHECK-V83A-NEXT: .cfi_negate_ra_state
170 ; CHECK-V83A-NEXT: .cfi_def_cfa_offset 16
171 ; CHECK-V83A-NEXT: .cfi_offset w30, -16
172 ; CHECK-V83A-NEXT: cbz w0, .LBB2_2
173 ; CHECK-V83A-NEXT: // %bb.1: // %if.then
174 ; CHECK-V83A-NEXT: mov w0, wzr
175 ; CHECK-V83A-NEXT: bl _Z3bari
176 ; CHECK-V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
177 ; CHECK-V83A-NEXT: autiasp
178 ; CHECK-V83A-NEXT: b _Z3bari
179 ; CHECK-V83A-NEXT: .LBB2_2: // %if.else
180 ; CHECK-V83A-NEXT: bl _Z4quuxi
181 ; CHECK-V83A-NEXT: add w0, w0, #1
182 ; CHECK-V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
183 ; CHECK-V83A-NEXT: retaa
185 %tobool.not = icmp eq i32 %a, 0
186 br i1 %tobool.not, label %if.else, label %if.then
188 if.then: ; preds = %entry
189 %call = tail call noundef i32 @_Z3bari(i32 noundef 0)
190 %call1 = tail call noundef i32 @_Z3bari(i32 noundef %call)
193 if.else: ; preds = %entry
194 %call2 = tail call noundef i32 @_Z4quuxi(i32 noundef 0)
195 %add = add nsw i32 %call2, 1
198 return: ; preds = %if.else, %if.then
199 %retval.0 = phi i32 [ %call1, %if.then ], [ %add, %if.else ]
203 declare dso_local ptr @__cxa_allocate_exception(i64)
205 declare dso_local void @__cxa_throw(ptr, ptr, ptr)
207 declare dso_local noundef i32 @_Z3bari(i32 noundef) local_unnamed_addr
208 declare dso_local noundef i32 @_Z4quuxi(i32 noundef) local_unnamed_addr
210 attributes #0 = { "sign-return-address"="all" }
213 ; CHECK-DUMP-LABEL: FDE
214 ; CHECK-DUMP: DW_CFA_AARCH64_negate_ra_state:
215 ; CHECK-DUMP-NOT: DW_CFA_AARCH64_negate_ra_state
216 ; CHECK-DUMP-NOT: DW_CFA_remember_state
217 ; CHECK-DUMP-NOT: DW_CFA_restore_state
219 ; CHECK-DUMP: CFA=WSP{{$}}
220 ; CHECK-DUMP: reg34=1
221 ; CHECK-DUMP-NOT: reg34=0
224 ; CHECK-DUMP-LABEL: FDE
225 ; CHECK-DUMP: Format: DWARF32
226 ; CHECK-DUMP: DW_CFA_AARCH64_negate_ra_state:
227 ; CHECK-DUMP: DW_CFA_remember_state:
228 ; CHECK-DUMP: DW_CFA_AARCH64_negate_ra_state:
229 ; CHECK-DUMP: DW_CFA_restore_state:
230 ; CHECK-DUMP: DW_CFA_AARCH64_negate_ra_state:
232 ; CHECK-DUMP: CFA=WSP{{$}}
233 ;; First DW_CFA_AARCH64_negate_ra_state:
234 ; CHECK-DUMP: reg34=1
235 ;; Second DW_CFA_AARCH64_negate_ra_state:
236 ; CHECK-DUMP: reg34=0
237 ;; DW_CFA_restore_state:
238 ; CHECK-DUMP: reg34=1
239 ;; Third DW_CFA_AARCH64_negate_ra_state:
240 ; CHECK-DUMP: reg34=0
241 ; CHECK-DUMP-NOT: reg34=
244 ; CHECK-DUMP-LABEL: FDE
245 ; CHECK-DUMP: DW_CFA_AARCH64_negate_ra_state:
246 ; CHECK-DUMP-NOT: DW_CFA_AARCH64_negate_ra_state
247 ; CHECK-DUMP-NOT: DW_CFA_remember_state
248 ; CHECK-DUMP-NOT: DW_CFA_restore_state
250 ; CHECK-DUMP: CFA=WSP{{$}}
251 ; CHECK-DUMP: reg34=1
252 ; CHECK-DUMP-NOT: reg34=0