xref: /llvm-project/llvm/test/CodeGen/AArch64/sign-return-address.ll (revision 0b73b5af60f2c544892b9dd68b4fa43eeff52fc1)
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,COMPAT %s
3; RUN: llc -mtriple=aarch64 -mattr=v8.3a < %s | FileCheck --check-prefixes=CHECK,V83A %s
4
5; v9.5-A is not expected to change codegen without -mbranch-protection=+pc, so reuse V83A.
6; RUN: llc -mtriple=aarch64 -mattr=v9.5a < %s | FileCheck --check-prefixes=CHECK,V83A %s
7
8define i32 @leaf(i32 %x) {
9; CHECK-LABEL: leaf:
10; CHECK:       // %bb.0:
11; CHECK-NEXT:    ret
12  ret i32 %x
13}
14
15define i32 @leaf_sign_none(i32 %x) {
16; CHECK-LABEL: leaf_sign_none:
17; CHECK:       // %bb.0:
18; CHECK-NEXT:    ret
19  ret i32 %x
20}
21
22define i32 @leaf_sign_non_leaf(i32 %x) "sign-return-address"="non-leaf"  {
23; CHECK-LABEL: leaf_sign_non_leaf:
24; CHECK:       // %bb.0:
25; CHECK-NEXT:    ret
26  ret i32 %x
27}
28
29define i32 @leaf_sign_all(i32 %x) "sign-return-address"="all" {
30; COMPAT-LABEL: leaf_sign_all:
31; COMPAT:       // %bb.0:
32; COMPAT-NEXT:    .cfi_negate_ra_state
33; COMPAT-NEXT:    hint #25
34; COMPAT-NEXT:    hint #29
35; COMPAT-NEXT:    ret
36;
37; V83A-LABEL: leaf_sign_all:
38; V83A:       // %bb.0:
39; V83A-NEXT:    .cfi_negate_ra_state
40; V83A-NEXT:    paciasp
41; V83A-NEXT:    retaa
42  ret i32 %x
43}
44
45define i64 @leaf_clobbers_lr(i64 %x) "sign-return-address"="non-leaf"  {
46; COMPAT-LABEL: leaf_clobbers_lr:
47; COMPAT:       // %bb.0:
48; COMPAT-NEXT:    .cfi_negate_ra_state
49; COMPAT-NEXT:    hint #25
50; COMPAT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
51; COMPAT-NEXT:    .cfi_def_cfa_offset 16
52; COMPAT-NEXT:    .cfi_offset w30, -16
53; COMPAT-NEXT:    //APP
54; COMPAT-NEXT:    mov x30, x0
55; COMPAT-NEXT:    //NO_APP
56; COMPAT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
57; COMPAT-NEXT:    hint #29
58; COMPAT-NEXT:    ret
59;
60; V83A-LABEL: leaf_clobbers_lr:
61; V83A:       // %bb.0:
62; V83A-NEXT:    .cfi_negate_ra_state
63; V83A-NEXT:    paciasp
64; V83A-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
65; V83A-NEXT:    .cfi_def_cfa_offset 16
66; V83A-NEXT:    .cfi_offset w30, -16
67; V83A-NEXT:    //APP
68; V83A-NEXT:    mov x30, x0
69; V83A-NEXT:    //NO_APP
70; V83A-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
71; V83A-NEXT:    retaa
72  call void asm sideeffect "mov x30, $0", "r,~{lr}"(i64 %x) #1
73  ret i64 %x
74}
75
76declare i32 @foo(i32)
77
78define i32 @non_leaf_sign_all(i32 %x) "sign-return-address"="all" {
79; COMPAT-LABEL: non_leaf_sign_all:
80; COMPAT:       // %bb.0:
81; COMPAT-NEXT:    .cfi_negate_ra_state
82; COMPAT-NEXT:    hint #25
83; COMPAT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
84; COMPAT-NEXT:    .cfi_def_cfa_offset 16
85; COMPAT-NEXT:    .cfi_offset w30, -16
86; COMPAT-NEXT:    bl foo
87; COMPAT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
88; COMPAT-NEXT:    hint #29
89; COMPAT-NEXT:    ret
90;
91; V83A-LABEL: non_leaf_sign_all:
92; V83A:       // %bb.0:
93; V83A-NEXT:    .cfi_negate_ra_state
94; V83A-NEXT:    paciasp
95; V83A-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
96; V83A-NEXT:    .cfi_def_cfa_offset 16
97; V83A-NEXT:    .cfi_offset w30, -16
98; V83A-NEXT:    bl foo
99; V83A-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
100; V83A-NEXT:    retaa
101  %call = call i32 @foo(i32 %x)
102  ret i32 %call
103}
104
105define i32 @non_leaf_sign_non_leaf(i32 %x) "sign-return-address"="non-leaf"  {
106; COMPAT-LABEL: non_leaf_sign_non_leaf:
107; COMPAT:       // %bb.0:
108; COMPAT-NEXT:    .cfi_negate_ra_state
109; COMPAT-NEXT:    hint #25
110; COMPAT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
111; COMPAT-NEXT:    .cfi_def_cfa_offset 16
112; COMPAT-NEXT:    .cfi_offset w30, -16
113; COMPAT-NEXT:    bl foo
114; COMPAT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
115; COMPAT-NEXT:    hint #29
116; COMPAT-NEXT:    ret
117;
118; V83A-LABEL: non_leaf_sign_non_leaf:
119; V83A:       // %bb.0:
120; V83A-NEXT:    .cfi_negate_ra_state
121; V83A-NEXT:    paciasp
122; V83A-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
123; V83A-NEXT:    .cfi_def_cfa_offset 16
124; V83A-NEXT:    .cfi_offset w30, -16
125; V83A-NEXT:    bl foo
126; V83A-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
127; V83A-NEXT:    retaa
128  %call = call i32 @foo(i32 %x)
129  ret i32 %call
130}
131
132; Should not use the RETAA instruction.
133define i32 @non_leaf_scs(i32 %x) "sign-return-address"="non-leaf" shadowcallstack "target-features"="+v8.3a,+reserve-x18"  {
134; CHECK-LABEL: non_leaf_scs:
135; CHECK:       // %bb.0:
136; CHECK-NEXT:    str x30, [x18], #8
137; CHECK-NEXT:    .cfi_escape 0x16, 0x12, 0x02, 0x82, 0x78 //
138; CHECK-NEXT:    .cfi_negate_ra_state
139; CHECK-NEXT:    paciasp
140; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
141; CHECK-NEXT:    .cfi_def_cfa_offset 16
142; CHECK-NEXT:    .cfi_offset w30, -16
143; CHECK-NEXT:    bl foo
144; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
145; CHECK-NEXT:    autiasp
146; CHECK-NEXT:    ldr x30, [x18, #-8]!
147; CHECK-NEXT:    ret
148  %call = call i32 @foo(i32 %x)
149  ret i32 %call
150}
151
152define i32 @leaf_sign_all_v83(i32 %x) "sign-return-address"="all" "target-features"="+v8.3a" {
153; CHECK-LABEL: leaf_sign_all_v83:
154; CHECK:       // %bb.0:
155; CHECK-NEXT:    .cfi_negate_ra_state
156; CHECK-NEXT:    paciasp
157; CHECK-NEXT:    retaa
158  ret i32 %x
159}
160
161declare fastcc i64 @bar(i64)
162
163define fastcc void @spill_lr_and_tail_call(i64 %x) "sign-return-address"="all" {
164; COMPAT-LABEL: spill_lr_and_tail_call:
165; COMPAT:       // %bb.0:
166; COMPAT-NEXT:    .cfi_negate_ra_state
167; COMPAT-NEXT:    hint #25
168; COMPAT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
169; COMPAT-NEXT:    .cfi_def_cfa_offset 16
170; COMPAT-NEXT:    .cfi_offset w30, -16
171; COMPAT-NEXT:    //APP
172; COMPAT-NEXT:    mov x30, x0
173; COMPAT-NEXT:    //NO_APP
174; COMPAT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
175; COMPAT-NEXT:    hint #29
176; COMPAT-NEXT:    b bar
177;
178; V83A-LABEL: spill_lr_and_tail_call:
179; V83A:       // %bb.0:
180; V83A-NEXT:    .cfi_negate_ra_state
181; V83A-NEXT:    paciasp
182; V83A-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
183; V83A-NEXT:    .cfi_def_cfa_offset 16
184; V83A-NEXT:    .cfi_offset w30, -16
185; V83A-NEXT:    //APP
186; V83A-NEXT:    mov x30, x0
187; V83A-NEXT:    //NO_APP
188; V83A-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
189; V83A-NEXT:    autiasp
190; V83A-NEXT:    b bar
191  call void asm sideeffect "mov x30, $0", "r,~{lr}"(i64 %x) #1
192  tail call fastcc i64 @bar(i64 %x)
193  ret void
194}
195
196define i32 @leaf_sign_all_a_key(i32 %x) "sign-return-address"="all" "sign-return-address-key"="a_key" {
197; COMPAT-LABEL: leaf_sign_all_a_key:
198; COMPAT:       // %bb.0:
199; COMPAT-NEXT:    .cfi_negate_ra_state
200; COMPAT-NEXT:    hint #25
201; COMPAT-NEXT:    hint #29
202; COMPAT-NEXT:    ret
203;
204; V83A-LABEL: leaf_sign_all_a_key:
205; V83A:       // %bb.0:
206; V83A-NEXT:    .cfi_negate_ra_state
207; V83A-NEXT:    paciasp
208; V83A-NEXT:    retaa
209  ret i32 %x
210}
211
212define i32 @leaf_sign_all_b_key(i32 %x) "sign-return-address"="all" "sign-return-address-key"="b_key" {
213; COMPAT-LABEL: leaf_sign_all_b_key:
214; COMPAT:       // %bb.0:
215; COMPAT-NEXT:    .cfi_b_key_frame
216; COMPAT-NEXT:    .cfi_negate_ra_state
217; COMPAT-NEXT:    hint #27
218; COMPAT-NEXT:    hint #31
219; COMPAT-NEXT:    ret
220;
221; V83A-LABEL: leaf_sign_all_b_key:
222; V83A:       // %bb.0:
223; V83A-NEXT:    .cfi_b_key_frame
224; V83A-NEXT:    .cfi_negate_ra_state
225; V83A-NEXT:    pacibsp
226; V83A-NEXT:    retab
227  ret i32 %x
228}
229
230define i32 @leaf_sign_all_v83_b_key(i32 %x) "sign-return-address"="all" "target-features"="+v8.3a" "sign-return-address-key"="b_key" {
231; CHECK-LABEL: leaf_sign_all_v83_b_key:
232; CHECK:       // %bb.0:
233; CHECK-NEXT:    .cfi_b_key_frame
234; CHECK-NEXT:    .cfi_negate_ra_state
235; CHECK-NEXT:    pacibsp
236; CHECK-NEXT:    retab
237  ret i32 %x
238}
239
240; Note that BTI instruction is not needed before PACIASP.
241define i32 @leaf_sign_all_a_key_bti(i32 %x) "sign-return-address"="all" "sign-return-address-key"="a_key" "branch-target-enforcement"{
242; COMPAT-LABEL: leaf_sign_all_a_key_bti:
243; COMPAT:       // %bb.0:
244; COMPAT-NEXT:    .cfi_negate_ra_state
245; COMPAT-NEXT:    hint #25
246; COMPAT-NEXT:    hint #29
247; COMPAT-NEXT:    ret
248;
249; V83A-LABEL: leaf_sign_all_a_key_bti:
250; V83A:       // %bb.0:
251; V83A-NEXT:    .cfi_negate_ra_state
252; V83A-NEXT:    paciasp
253; V83A-NEXT:    retaa
254  ret i32 %x
255}
256
257; Note that BTI instruction is not needed before PACIBSP.
258define i32 @leaf_sign_all_b_key_bti(i32 %x) "sign-return-address"="all" "sign-return-address-key"="b_key" "branch-target-enforcement"{
259; COMPAT-LABEL: leaf_sign_all_b_key_bti:
260; COMPAT:       // %bb.0:
261; COMPAT-NEXT:    .cfi_b_key_frame
262; COMPAT-NEXT:    .cfi_negate_ra_state
263; COMPAT-NEXT:    hint #27
264; COMPAT-NEXT:    hint #31
265; COMPAT-NEXT:    ret
266;
267; V83A-LABEL: leaf_sign_all_b_key_bti:
268; V83A:       // %bb.0:
269; V83A-NEXT:    .cfi_b_key_frame
270; V83A-NEXT:    .cfi_negate_ra_state
271; V83A-NEXT:    pacibsp
272; V83A-NEXT:    retab
273  ret i32 %x
274}
275
276; Note that BTI instruction is not needed before PACIBSP.
277define i32 @leaf_sign_all_v83_b_key_bti(i32 %x) "sign-return-address"="all" "target-features"="+v8.3a" "sign-return-address-key"="b_key" "branch-target-enforcement" {
278; CHECK-LABEL: leaf_sign_all_v83_b_key_bti:
279; CHECK:       // %bb.0:
280; CHECK-NEXT:    .cfi_b_key_frame
281; CHECK-NEXT:    .cfi_negate_ra_state
282; CHECK-NEXT:    pacibsp
283; CHECK-NEXT:    retab
284  ret i32 %x
285}
286