[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / AArch64 / branch-target-enforcement.mir
blob946005a90e74a626407d709e9ad6573e9a98c8dd
1 # RUN: llc -run-pass=aarch64-branch-targets %s -o - | FileCheck %s
2 --- |
3   target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
4   target triple = "aarch64-arm-none-eabi"
6   define hidden i32 @simple_external() "branch-target-enforcement"="true" {
7   entry:
8     ret i32 0
9   }
11   define internal i32 @simple_internal() "branch-target-enforcement"="true" {
12   entry:
13     ret i32 0
14   }
16   define hidden i32 @ptr_auth() "branch-target-enforcement"="true" {
17   entry:
18     tail call void asm sideeffect "", "~{lr}"()
19     ret i32 0
20   }
22   define hidden i32 @ptr_auth_b() "branch-target-enforcement"="true" {
23   entry:
24     tail call void asm sideeffect "", "~{lr}"()
25     ret i32 0
26   }
28   define hidden i32 @jump_table(i32 %a) "branch-target-enforcement"="true" {
29   entry:
30     switch i32 %a, label %sw.epilog [
31       i32 1, label %sw.bb
32       i32 2, label %sw.bb1
33       i32 3, label %sw.bb2
34       i32 4, label %sw.bb3
35       i32 5, label %sw.bb4
36     ]
38   sw.bb:                                            ; preds = %entry
39     tail call void asm sideeffect "", ""()
40     br label %sw.epilog
42   sw.bb1:                                           ; preds = %entry
43     tail call void asm sideeffect "", ""()
44     br label %sw.epilog
46   sw.bb2:                                           ; preds = %entry
47     tail call void asm sideeffect "", ""()
48     br label %sw.epilog
50   sw.bb3:                                           ; preds = %entry
51     tail call void asm sideeffect "", ""()
52     br label %sw.epilog
54   sw.bb4:                                           ; preds = %entry
55     tail call void asm sideeffect "", ""()
56     br label %sw.epilog
58   sw.epilog:                                        ; preds = %entry, %sw.bb4, %sw.bb3, %sw.bb2, %sw.bb1, %sw.bb
59     ret i32 0
60   }
62   @label_address.addr = internal unnamed_addr global i8* blockaddress(@label_address, %return), align 8
64   define hidden i32 @label_address() "branch-target-enforcement"="true" {
65   entry:
66     %0 = load i8*, i8** @label_address.addr, align 8
67     indirectbr i8* %0, [label %return, label %lab2]
69   lab2:                                             ; preds = %entry
70     br label %.split
72   return:                                           ; preds = %entry
73     br label %.split
75   .split:                                           ; preds = %lab2, %return
76     %merge = phi i8* [ blockaddress(@label_address, %lab2), %return ], [ blockaddress(@label_address, %return), %lab2 ]
77     %merge2 = phi i32 [ 1, %return ], [ 2, %lab2 ]
78     store i8* %merge, i8** @label_address.addr, align 8
79     ret i32 %merge2
80   }
82   define hidden i32 @label_address_entry() "branch-target-enforcement"="true" {
83   entry:
84     %0 = load i8*, i8** @label_address.addr, align 8
85     indirectbr i8* %0, [label %return, label %lab2]
87   lab2:                                             ; preds = %entry
88     br label %.split
90   return:                                           ; preds = %entry
91     br label %.split
93   .split:                                           ; preds = %lab2, %return
94     %merge = phi i8* [ blockaddress(@label_address, %lab2), %return ], [ blockaddress(@label_address, %return), %lab2 ]
95     %merge2 = phi i32 [ 1, %return ], [ 2, %lab2 ]
96     store i8* %merge, i8** @label_address.addr, align 8
97     ret i32 %merge2
98   }
100   define hidden i32 @debug_ptr_auth() "branch-target-enforcement"="true" {
101   entry:
102     tail call void asm sideeffect "", "~{lr}"()
103     ret i32 0
104   }
108 # External function, could be addres-taken elsewhere so needs BTI JC.
109 name:            simple_external
110 body:             |
111   bb.0.entry:
112     ; CHECK-LABEL: name: simple_external
113     ; CHECK: HINT 34
114     ; CHECK: RET
115     $w0 = ORRWrs $wzr, $wzr, 0
116     RET undef $lr, implicit killed $w0
119 # Internal function, not address-taken in this module, however the compiler
120 # cannot 100% ensure that later parts of the toolchain won't add indirect
121 # jumps. E.g. a linker adding a thunk to extend the range of a direct jump.
122 # Therefore, even this case needs a BTI.
123 name:            simple_internal
124 body:             |
125   bb.0.entry:
126     ; CHECK-LABEL: name: simple_internal
127     ; CHECK: HINT 34
128     ; CHECK: RET
129     $w0 = ORRWrs $wzr, $wzr, 0
130     RET undef $lr, implicit killed $w0
133 # Function starts with PACIASP, which implicitly acts as BTI JC, so no change
134 # needed.
135 name:            ptr_auth
136 stack:
137   - { id: 0, name: '', type: spill-slot, offset: -16, size: 8, alignment: 16,
138       stack-id: default, callee-saved-register: '$lr', callee-saved-restored: true,
139       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
140 body:             |
141   bb.0.entry:
142     liveins: $lr
144     ; CHECK-LABEL: name: ptr_auth
145     ; CHECK-NOT: HINT
146     ; CHECK: frame-setup PACIASP
147     ; CHECK-NOT: HINT
148     ; CHECK: RETAA
149     frame-setup PACIASP implicit-def $lr, implicit killed $lr, implicit $sp
150     early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.0)
151     INLINEASM &"", 1, 12, implicit-def dead early-clobber $lr
152     $w0 = ORRWrs $wzr, $wzr, 0
153     early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.0)
154     RETAA implicit $sp, implicit $lr, implicit killed $w0
157 # Function starts with PACIBSP, which implicitly acts as BTI JC, so no change
158 # needed.
159 name:            ptr_auth_b
160 stack:
161   - { id: 0, name: '', type: spill-slot, offset: -16, size: 8, alignment: 16,
162       stack-id: default, callee-saved-register: '$lr', callee-saved-restored: true,
163       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
164 body:             |
165   bb.0.entry:
166     liveins: $lr
168     ; CHECK-LABEL: name: ptr_auth_b
169     ; CHECK-NOT: HINT
170     ; CHECK: frame-setup PACIBSP
171     ; CHECK-NOT: HINT
172     ; CHECK: RETAB
173     frame-setup PACIBSP implicit-def $lr, implicit killed $lr, implicit $sp
174     early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.0)
175     INLINEASM &"", 1, 12, implicit-def dead early-clobber $lr
176     $w0 = ORRWrs $wzr, $wzr, 0
177     early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.0)
178     RETAB implicit $sp, implicit $lr, implicit killed $w0
181 # Function contains a jump table, so every target of the jump table must start
182 # with BTI J.
183 name:            jump_table
184 jumpTable:
185   kind:            block-address
186   entries:
187     - id:              0
188       blocks:          [ '%bb.2', '%bb.3', '%bb.4', '%bb.5', '%bb.6' ]
189 body:             |
190   bb.0.entry:
191     ; CHECK-LABEL: name: jump_table
192     ; CHECK: HINT 34
193     successors: %bb.7(0x15555555), %bb.1(0x6aaaaaab)
194     liveins: $w0
196     renamable $w8 = SUBWri killed renamable $w0, 1, 0, implicit-def $x8
197     dead $wzr = SUBSWri renamable $w8, 4, 0, implicit-def $nzcv
198     Bcc 8, %bb.7, implicit $nzcv
200   bb.1.entry:
201     ; CHECK: bb.1.entry:
202     ; CHECK-NOT: HINT
203     ; CHECK: BR killed renamable $x8
204     successors: %bb.2(0x1999999a), %bb.3(0x1999999a), %bb.4(0x1999999a), %bb.5(0x1999999a), %bb.6(0x1999999a)
205     liveins: $x8
207     $x9 = ADRP target-flags(aarch64-page) %jump-table.0
208     renamable $x9 = ADDXri killed $x9, target-flags(aarch64-pageoff, aarch64-nc) %jump-table.0, 0
209     renamable $x8 = LDRXroX killed renamable $x9, killed renamable $x8, 0, 1 :: (load (s64) from jump-table)
210     BR killed renamable $x8
212   bb.2.sw.bb:
213     ; CHECK: bb.2.sw.bb
214     ; CHECK-NEXT: HINT 36
215     $w0 = ORRWrs $wzr, $wzr, 0
216     INLINEASM &"", 1
217     RET undef $lr, implicit killed $w0
219   bb.3.sw.bb1:
220     ; CHECK: bb.3.sw.bb1
221     ; CHECK-NEXT: HINT 36
222     $w0 = ORRWrs $wzr, $wzr, 0
223     INLINEASM &"", 1
224     RET undef $lr, implicit killed $w0
226   bb.4.sw.bb2:
227     ; CHECK: bb.4.sw.bb2
228     ; CHECK-NEXT: HINT 36
229     $w0 = ORRWrs $wzr, $wzr, 0
230     INLINEASM &"", 1
231     RET undef $lr, implicit killed $w0
233   bb.5.sw.bb3:
234     ; CHECK: bb.5.sw.bb3
235     ; CHECK-NEXT: HINT 36
236     $w0 = ORRWrs $wzr, $wzr, 0
237     INLINEASM &"", 1
238     RET undef $lr, implicit killed $w0
240   bb.6.sw.bb4:
241     ; CHECK: bb.6.sw.bb4
242     ; CHECK-NEXT: successors: %bb.7(0x80000000)
243     ; CHECK-NEXT: {{  }}
244     ; CHECK-NEXT: HINT 36
245     successors: %bb.7(0x80000000)
247     INLINEASM &"", 1
249   bb.7.sw.epilog:
250     ; CHECK: bb.7.sw.epilog:
251     ; CHECK-NOT: HINT
252     ; CHECK: RET
253     $w0 = ORRWrs $wzr, $wzr, 0
254     RET undef $lr, implicit killed $w0
257 # Function takes address of basic blocks, so they must start with BTI J.
258 name:            label_address
259 body:             |
260   bb.0.entry:
261     ; CHECK-LABEL: label_address
262     ; CHECK: bb.0.entry:
263     ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
264     ; CHECK-NEXT: {{  }}
265     ; CHECK-NEXT: HINT 34
266     ; CHECK: BR killed renamable $x9
267     successors: %bb.1(0x40000000), %bb.2(0x40000000)
269     renamable $x8 = ADRP target-flags(aarch64-page) @label_address.addr
270     renamable $x9 = LDRXui renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @label_address.addr :: (dereferenceable load (s64) from @label_address.addr)
271     BR killed renamable $x9
273   bb.1.return (address-taken):
274     ; CHECK: bb.1.return (address-taken):
275     ; CHECK-NEXT: HINT 36
276     liveins: $x8
278     $x9 = ADRP target-flags(aarch64-page) blockaddress(@label_address, %ir-block.lab2)
279     renamable $w0 = ORRWri $wzr, 0
280     renamable $x9 = ADDXri killed $x9, target-flags(aarch64-pageoff, aarch64-nc) blockaddress(@label_address, %ir-block.lab2), 0
281     STRXui killed renamable $x9, killed renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @label_address.addr :: (store (s64) into @label_address.addr)
282     RET undef $lr, implicit killed $w0
284   bb.2.lab2 (address-taken):
285     ; CHECK: bb.2.lab2 (address-taken):
286     ; CHECK-NEXT: HINT 36
287     liveins: $x8
289     $x9 = ADRP target-flags(aarch64-page) blockaddress(@label_address, %ir-block.return)
290     renamable $w0 = ORRWri $wzr, 1984
291     renamable $x9 = ADDXri killed $x9, target-flags(aarch64-pageoff, aarch64-nc) blockaddress(@label_address, %ir-block.return), 0
292     STRXui killed renamable $x9, killed renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @label_address.addr :: (store (s64) into @label_address.addr)
293     RET undef $lr, implicit killed $w0
296 # Function takes address of the entry block, so the entry block needs a BTI JC.
297 name:            label_address_entry
298 stack:
299   - { id: 0, name: '', type: spill-slot, offset: -16, size: 8, alignment: 16,
300       stack-id: default, callee-saved-register: '$lr', callee-saved-restored: true,
301       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
302 body:             |
303   bb.0.entry (address-taken):
304     ; CHECK-LABEL: label_address_entry
305     ; CHECK: bb.0.entry (address-taken):
306     ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
307     ; CHECK-NEXT: {{  }}
308     ; CHECK-NEXT: HINT 38
309     ; CHECK: BR killed renamable $x9
310     successors: %bb.1(0x40000000), %bb.2(0x40000000)
312     renamable $x8 = ADRP target-flags(aarch64-page) @label_address.addr
313     renamable $x9 = LDRXui renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @label_address.addr :: (dereferenceable load (s64) from @label_address.addr)
314     BR killed renamable $x9
316   bb.1.return (address-taken):
317     ; CHECK: bb.1.return (address-taken):
318     ; CHECK-NEXT: HINT 36
319     liveins: $x8
320     frame-setup PACIASP implicit-def $lr, implicit killed $lr, implicit $sp
321     frame-setup CFI_INSTRUCTION negate_ra_sign_state
322     early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.0)
323     INLINEASM &"", 1, 12, implicit-def dead early-clobber $lr
324     $x9 = ADRP target-flags(aarch64-page) blockaddress(@label_address, %ir-block.entry)
325     renamable $w0 = ORRWri $wzr, 0
326     renamable $x9 = ADDXri killed $x9, target-flags(aarch64-pageoff, aarch64-nc) blockaddress(@label_address, %ir-block.entry), 0
327     STRXui killed renamable $x9, killed renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @label_address.addr :: (store (s64) into @label_address.addr)
328     early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.0)
329     RETAA implicit $sp, implicit $lr, implicit killed $w0
331   bb.2.lab2:
332     ; CHECK: bb.2.lab2:
333     ; CHECK-NOT: HINT
334     liveins: $x8
336     $x9 = ADRP target-flags(aarch64-page) blockaddress(@label_address, %ir-block.return)
337     renamable $w0 = ORRWri $wzr, 1984
338     renamable $x9 = ADDXri killed $x9, target-flags(aarch64-pageoff, aarch64-nc) blockaddress(@label_address, %ir-block.return), 0
339     STRXui killed renamable $x9, killed renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @label_address.addr :: (store (s64) into @label_address.addr)
340     RET undef $lr, implicit killed $w0
342 # When PACIASP is the first real instruction in the functions then BTI should not be inserted.
343 name:            debug_ptr_auth
344 stack:
345   - { id: 0, name: '', type: spill-slot, offset: -16, size: 8, alignment: 16,
346       stack-id: default, callee-saved-register: '$lr', callee-saved-restored: true,
347       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
348 body:             |
349   bb.0.entry:
350     liveins: $lr
352     ; CHECK-LABEL: name: debug_ptr_auth
353     ; CHECK-NOT: HINT
354     ; CHECK: frame-setup PACIASP
355     ; CHECK-NOT: HINT
356     ; CHECK: RETAA
357     frame-setup PACIASP implicit-def $lr, implicit killed $lr, implicit $sp
358     frame-setup CFI_INSTRUCTION negate_ra_sign_state
359     early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.0)
360     INLINEASM &"", 1, 12, implicit-def dead early-clobber $lr
361     $w0 = ORRWrs $wzr, $wzr, 0
362     early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.0)
363     RETAA implicit $sp, implicit $lr, implicit killed $w0