1 # RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu \
2 # RUN: -start-before aarch64-sls-hardening -o - %s \
3 # RUN: -asm-verbose=0 \
4 # RUN: | FileCheck %s \
5 # RUN: --implicit-check-not=__llvm_slsblr_thunk_aa_x5_x8 \
6 # RUN: --implicit-check-not=__llvm_slsblr_thunk_ab_x5_x8 \
7 # RUN: --implicit-check-not=__llvm_slsblr_thunk_aaz_x5 \
8 # RUN: --implicit-check-not=__llvm_slsblr_thunk_abz_x5
10 # Pointer Authentication extension introduces more branch-with-link-to-register
11 # instructions for the BLR SLS hardening to handle, namely BLRAA, BLRAB, BLRAAZ
12 # and BLRABZ. Unlike the non-authenticating BLR instruction, BLRAA and BLRAB
13 # accept two register operands (almost 900 combinations for each instruction).
14 # For that reason, it is not practical to create all possible thunks.
16 # Check that the BLR SLS hardening transforms BLRA* instructions into
17 # unconditional BL calls to the correct thunk functions.
18 # Check that only relevant thunk functions are generated.
20 define void @test_instructions() #0 {
25 define void @test_no_redef() #0 {
30 define void @test_regs() #0 {
35 attributes #0 = { "target-features"="+pauth,+harden-sls-blr" }
38 # Test that all BLRA* instructions are handled.
40 name: test_instructions
41 tracksRegLiveness: true
44 liveins: $lr, $x0, $x1, $x2, $x3
46 BLRAA $x0, $x1, implicit-def $lr, implicit $sp, implicit-def $sp, implicit-def $w0
47 BLRAB $x1, $x2, implicit-def $lr, implicit $sp, implicit-def $sp, implicit-def $w0
48 BLRAAZ $x2, implicit-def $lr, implicit $sp, implicit-def $sp, implicit-def $w0
49 BLRABZ $x3, implicit-def $lr, implicit $sp, implicit-def $sp, implicit-def $w0
53 # Test that the same thunk function is not created twice.
56 tracksRegLiveness: true
59 liveins: $lr, $x0, $x1, $x2, $x3, $x4
61 ; thunk used by @test_instructions
62 BLRAB $x1, $x2, implicit-def $lr, implicit $sp, implicit-def $sp, implicit-def $w0
64 ; thunk used by this function twice
65 BLRAB $x3, $x4, implicit-def $lr, implicit $sp, implicit-def $sp, implicit-def $w0
66 BLRAB $x3, $x4, implicit-def $lr, implicit $sp, implicit-def $sp, implicit-def $w0
71 # Test that all xN registers (except x16, x17, x30 and xzr) are handled.
74 tracksRegLiveness: true
77 liveins: $lr, $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27, $x28, $fp
79 BLRAA $x0, $x1, implicit-def $lr, implicit $sp, implicit-def $sp, implicit-def $w0
80 BLRAA $x2, $x3, implicit-def $lr, implicit $sp, implicit-def $sp, implicit-def $w0
81 BLRAA $x4, $x5, implicit-def $lr, implicit $sp, implicit-def $sp, implicit-def $w0
82 BLRAA $x6, $x7, implicit-def $lr, implicit $sp, implicit-def $sp, implicit-def $w0
83 BLRAA $x8, $x9, implicit-def $lr, implicit $sp, implicit-def $sp, implicit-def $w0
84 BLRAA $x10, $x11, implicit-def $lr, implicit $sp, implicit-def $sp, implicit-def $w0
85 BLRAA $x12, $x13, implicit-def $lr, implicit $sp, implicit-def $sp, implicit-def $w0
86 BLRAA $x14, $x15, implicit-def $lr, implicit $sp, implicit-def $sp, implicit-def $w0
87 ; skipping x16 and x17
88 BLRAA $x18, $x19, implicit-def $lr, implicit $sp, implicit-def $sp, implicit-def $w0
89 BLRAA $x20, $x21, implicit-def $lr, implicit $sp, implicit-def $sp, implicit-def $w0
90 BLRAA $x22, $x23, implicit-def $lr, implicit $sp, implicit-def $sp, implicit-def $w0
91 BLRAA $x24, $x25, implicit-def $lr, implicit $sp, implicit-def $sp, implicit-def $w0
92 BLRAA $x26, $x27, implicit-def $lr, implicit $sp, implicit-def $sp, implicit-def $w0
93 BLRAA $x28, $fp, implicit-def $lr, implicit $sp, implicit-def $sp, implicit-def $w0
97 # CHECK-LABEL: test_instructions:
98 # CHECK-NEXT: .cfi_startproc
99 # CHECK-NEXT: bl __llvm_slsblr_thunk_aa_x0_x1
100 # CHECK-NEXT: bl __llvm_slsblr_thunk_ab_x1_x2
101 # CHECK-NEXT: bl __llvm_slsblr_thunk_aaz_x2
102 # CHECK-NEXT: bl __llvm_slsblr_thunk_abz_x3
105 # CHECK-LABEL: test_no_redef:
106 # CHECK-NEXT: .cfi_startproc
107 # CHECK-NEXT: bl __llvm_slsblr_thunk_ab_x1_x2
108 # CHECK-NEXT: bl __llvm_slsblr_thunk_ab_x3_x4
109 # CHECK-NEXT: bl __llvm_slsblr_thunk_ab_x3_x4
112 # CHECK-LABEL: test_regs:
113 # CHECK-NEXT: .cfi_startproc
114 # CHECK-NEXT: bl __llvm_slsblr_thunk_aa_x0_x1
115 # CHECK-NEXT: bl __llvm_slsblr_thunk_aa_x2_x3
116 # CHECK-NEXT: bl __llvm_slsblr_thunk_aa_x4_x5
117 # CHECK-NEXT: bl __llvm_slsblr_thunk_aa_x6_x7
118 # CHECK-NEXT: bl __llvm_slsblr_thunk_aa_x8_x9
119 # CHECK-NEXT: bl __llvm_slsblr_thunk_aa_x10_x11
120 # CHECK-NEXT: bl __llvm_slsblr_thunk_aa_x12_x13
121 # CHECK-NEXT: bl __llvm_slsblr_thunk_aa_x14_x15
122 # skipping x16 and x17
123 # CHECK-NEXT: bl __llvm_slsblr_thunk_aa_x18_x19
124 # CHECK-NEXT: bl __llvm_slsblr_thunk_aa_x20_x21
125 # CHECK-NEXT: bl __llvm_slsblr_thunk_aa_x22_x23
126 # CHECK-NEXT: bl __llvm_slsblr_thunk_aa_x24_x25
127 # CHECK-NEXT: bl __llvm_slsblr_thunk_aa_x26_x27
128 # CHECK-NEXT: bl __llvm_slsblr_thunk_aa_x28_x29
131 # CHECK-LABEL: __llvm_slsblr_thunk_aa_x0_x1:
132 # CHECK-NEXT: mov x16, x0
133 # CHECK-NEXT: braa x16, x1
137 # CHECK-LABEL: __llvm_slsblr_thunk_ab_x1_x2:
138 # CHECK-NEXT: mov x16, x1
139 # CHECK-NEXT: brab x16, x2
143 # CHECK-LABEL: __llvm_slsblr_thunk_aaz_x2:
144 # CHECK-NEXT: mov x16, x2
145 # CHECK-NEXT: braaz x16
149 # CHECK-LABEL: __llvm_slsblr_thunk_abz_x3:
150 # CHECK-NEXT: mov x16, x3
151 # CHECK-NEXT: brabz x16
155 # The instruction *operands* should correspond to the thunk function *name*
156 # (check that the name is parsed correctly when populating the thunk).
158 # CHECK-LABEL: __llvm_slsblr_thunk_aa_x2_x3:
159 # CHECK-NEXT: mov x16, x2
160 # CHECK: braa x16, x3
162 # CHECK-LABEL: __llvm_slsblr_thunk_aa_x4_x5:
163 # CHECK-NEXT: mov x16, x4
164 # CHECK: braa x16, x5
166 # CHECK-LABEL: __llvm_slsblr_thunk_aa_x6_x7:
167 # CHECK-NEXT: mov x16, x6
168 # CHECK: braa x16, x7
170 # CHECK-LABEL: __llvm_slsblr_thunk_aa_x8_x9:
171 # CHECK-NEXT: mov x16, x8
172 # CHECK: braa x16, x9
174 # CHECK-LABEL: __llvm_slsblr_thunk_aa_x10_x11:
175 # CHECK-NEXT: mov x16, x10
176 # CHECK: braa x16, x11
178 # CHECK-LABEL: __llvm_slsblr_thunk_aa_x12_x13:
179 # CHECK-NEXT: mov x16, x12
180 # CHECK: braa x16, x13
182 # CHECK-LABEL: __llvm_slsblr_thunk_aa_x14_x15:
183 # CHECK-NEXT: mov x16, x14
184 # CHECK: braa x16, x15
186 # skipping x16 and x17
188 # CHECK-LABEL: __llvm_slsblr_thunk_aa_x18_x19:
189 # CHECK-NEXT: mov x16, x18
190 # CHECK: braa x16, x19
192 # CHECK-LABEL: __llvm_slsblr_thunk_aa_x20_x21:
193 # CHECK-NEXT: mov x16, x20
194 # CHECK: braa x16, x21
196 # CHECK-LABEL: __llvm_slsblr_thunk_aa_x22_x23:
197 # CHECK-NEXT: mov x16, x22
198 # CHECK: braa x16, x23
200 # CHECK-LABEL: __llvm_slsblr_thunk_aa_x24_x25:
201 # CHECK-NEXT: mov x16, x24
202 # CHECK: braa x16, x25
204 # CHECK-LABEL: __llvm_slsblr_thunk_aa_x26_x27:
205 # CHECK-NEXT: mov x16, x26
206 # CHECK: braa x16, x27
208 # CHECK-LABEL: __llvm_slsblr_thunk_aa_x28_x29:
209 # CHECK-NEXT: mov x16, x28
210 # CHECK: braa x16, x29