[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / sign-return-address-cfi-negate-ra-state.ll
blobda2c2985acf971f74036a2544749b508eee50bde
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:    .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
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
45 entry:
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
52   unreachable
54 return:                                           ; No predecessors!
55   %0 = load i32, ptr %retval, align 4
56   ret i32 %0
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
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
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
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
131 return:                                           ; preds = %if.else, %if.then
132   %retval.0 = phi i32 [ %call1, %if.then ], [ %add, %if.else ]
133   ret i32 %retval.0
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
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
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
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
195 return:                                           ; preds = %if.else, %if.then
196   %retval.0 = phi i32 [ %call1, %if.then ], [ %add, %if.else ]
197   ret i32 %retval.0
200 declare dso_local ptr @__cxa_allocate_exception(i64)
202 declare dso_local void @__cxa_throw(ptr, ptr, ptr)
204 declare dso_local noundef i32 @_Z3bari(i32 noundef) local_unnamed_addr
205 declare dso_local noundef i32 @_Z4quuxi(i32 noundef) local_unnamed_addr
207 attributes #0 = { "sign-return-address"="all" }
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
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:
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