[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / AArch64 / branch-target-enforcment.mir
blob5db503ddcee95c6218e3052410efea96692380c4
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" {
7   entry:
8     ret i32 0
9   }
11   define internal i32 @simple_internal() "branch-target-enforcement" {
12   entry:
13     ret i32 0
14   }
16   define hidden i32 @ptr_auth() "branch-target-enforcement" {
17   entry:
18     tail call void asm sideeffect "", "~{lr}"()
19     ret i32 0
20   }
22   define hidden i32 @ptr_auth_b() "branch-target-enforcement" {
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" {
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" {
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" {
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   }
102 # External function, could be addres-taken elsewhere so needs BTI JC.
103 name:            simple_external
104 body:             |
105   bb.0.entry:
106     ; CHECK-LABEL: name: simple_external
107     ; CHECK: HINT 34
108     ; CHECK: RET
109     $w0 = ORRWrs $wzr, $wzr, 0
110     RET undef $lr, implicit killed $w0
113 # Internal function, not address-taken in this module, so no BTI needed.
114 name:            simple_internal
115 body:             |
116   bb.0.entry:
117     ; CHECK-LABEL: name: simple_internal
118     ; CHECK-NOT: HINT
119     ; CHECK: RET
120     $w0 = ORRWrs $wzr, $wzr, 0
121     RET undef $lr, implicit killed $w0
124 # Function starts with PACIASP, which implicitly acts as BTI JC, so no change
125 # needed.
126 name:            ptr_auth
127 stack:
128   - { id: 0, name: '', type: spill-slot, offset: -16, size: 8, alignment: 16,
129       stack-id: default, callee-saved-register: '$lr', callee-saved-restored: true,
130       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
131 body:             |
132   bb.0.entry:
133     liveins: $lr
135     ; CHECK-LABEL: name: ptr_auth
136     ; CHECK-NOT: HINT
137     ; CHECK: frame-setup PACIASP
138     ; CHECK-NOT: HINT
139     ; CHECK: RETAA
140     frame-setup PACIASP implicit-def $lr, implicit killed $lr, implicit $sp
141     early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store 8 into %stack.0)
142     INLINEASM &"", 1, 12, implicit-def dead early-clobber $lr
143     $w0 = ORRWrs $wzr, $wzr, 0
144     early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load 8 from %stack.0)
145     RETAA implicit killed $w0
148 # Function starts with PACIBSP, which implicitly acts as BTI JC, so no change
149 # needed.
150 name:            ptr_auth_b
151 stack:
152   - { id: 0, name: '', type: spill-slot, offset: -16, size: 8, alignment: 16,
153       stack-id: default, callee-saved-register: '$lr', callee-saved-restored: true,
154       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
155 body:             |
156   bb.0.entry:
157     liveins: $lr
159     ; CHECK-LABEL: name: ptr_auth_b
160     ; CHECK-NOT: HINT
161     ; CHECK: frame-setup PACIBSP
162     ; CHECK-NOT: HINT
163     ; CHECK: RETAB
164     frame-setup PACIBSP implicit-def $lr, implicit killed $lr, implicit $sp
165     early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store 8 into %stack.0)
166     INLINEASM &"", 1, 12, implicit-def dead early-clobber $lr
167     $w0 = ORRWrs $wzr, $wzr, 0
168     early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load 8 from %stack.0)
169     RETAB implicit killed $w0
172 # Function contains a jump table, so every target of the jump table must start
173 # with BTI J.
174 name:            jump_table
175 jumpTable:
176   kind:            block-address
177   entries:
178     - id:              0
179       blocks:          [ '%bb.2', '%bb.3', '%bb.4', '%bb.5', '%bb.6' ]
180 body:             |
181   bb.0.entry:
182     ; CHECK-LABEL: name: jump_table
183     ; CHECK: HINT 34
184     successors: %bb.7(0x15555555), %bb.1(0x6aaaaaab)
185     liveins: $w0
187     renamable $w8 = SUBWri killed renamable $w0, 1, 0, implicit-def $x8
188     dead $wzr = SUBSWri renamable $w8, 4, 0, implicit-def $nzcv
189     Bcc 8, %bb.7, implicit $nzcv
191   bb.1.entry:
192     ; CHECK: bb.1.entry:
193     ; CHECK-NOT: HINT
194     ; CHECK: BR killed renamable $x8
195     successors: %bb.2(0x1999999a), %bb.3(0x1999999a), %bb.4(0x1999999a), %bb.5(0x1999999a), %bb.6(0x1999999a)
196     liveins: $x8
198     $x9 = ADRP target-flags(aarch64-page) %jump-table.0
199     renamable $x9 = ADDXri killed $x9, target-flags(aarch64-pageoff, aarch64-nc) %jump-table.0, 0
200     renamable $x8 = LDRXroX killed renamable $x9, killed renamable $x8, 0, 1 :: (load 8 from jump-table)
201     BR killed renamable $x8
203   bb.2.sw.bb:
204     ; CHECK: bb.2.sw.bb
205     ; CHECK-NEXT: HINT 36
206     $w0 = ORRWrs $wzr, $wzr, 0
207     INLINEASM &"", 1
208     RET undef $lr, implicit killed $w0
210   bb.3.sw.bb1:
211     ; CHECK: bb.3.sw.bb1
212     ; CHECK-NEXT: HINT 36
213     $w0 = ORRWrs $wzr, $wzr, 0
214     INLINEASM &"", 1
215     RET undef $lr, implicit killed $w0
217   bb.4.sw.bb2:
218     ; CHECK: bb.4.sw.bb2
219     ; CHECK-NEXT: HINT 36
220     $w0 = ORRWrs $wzr, $wzr, 0
221     INLINEASM &"", 1
222     RET undef $lr, implicit killed $w0
224   bb.5.sw.bb3:
225     ; CHECK: bb.5.sw.bb3
226     ; CHECK-NEXT: HINT 36
227     $w0 = ORRWrs $wzr, $wzr, 0
228     INLINEASM &"", 1
229     RET undef $lr, implicit killed $w0
231   bb.6.sw.bb4:
232     ; CHECK: bb.6.sw.bb4
233     ; CHECK-NEXT: successors: %bb.7(0x80000000)
234     ; CHECK-NEXT: {{  }}
235     ; CHECK-NEXT: HINT 36
236     successors: %bb.7(0x80000000)
238     INLINEASM &"", 1
240   bb.7.sw.epilog:
241     ; CHECK: bb.7.sw.epilog:
242     ; CHECK-NOT: HINT
243     ; CHECK: RET
244     $w0 = ORRWrs $wzr, $wzr, 0
245     RET undef $lr, implicit killed $w0
248 # Function takes address of basic blocks, so they must start with BTI J.
249 name:            label_address
250 body:             |
251   bb.0.entry:
252     ; CHECK-LABEL: label_address
253     ; CHECK: bb.0.entry:
254     ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
255     ; CHECK-NEXT: {{  }}
256     ; CHECK-NEXT: HINT 34
257     ; CHECK: BR killed renamable $x9
258     successors: %bb.1(0x40000000), %bb.2(0x40000000)
260     renamable $x8 = ADRP target-flags(aarch64-page) @label_address.addr
261     renamable $x9 = LDRXui renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @label_address.addr :: (dereferenceable load 8 from @label_address.addr)
262     BR killed renamable $x9
264   bb.1.return (address-taken):
265     ; CHECK: bb.1.return (address-taken):
266     ; CHECK-NEXT: HINT 36
267     liveins: $x8
269     $x9 = ADRP target-flags(aarch64-page) blockaddress(@label_address, %ir-block.lab2)
270     renamable $w0 = ORRWri $wzr, 0
271     renamable $x9 = ADDXri killed $x9, target-flags(aarch64-pageoff, aarch64-nc) blockaddress(@label_address, %ir-block.lab2), 0
272     STRXui killed renamable $x9, killed renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @label_address.addr :: (store 8 into @label_address.addr)
273     RET undef $lr, implicit killed $w0
275   bb.2.lab2 (address-taken):
276     ; CHECK: bb.2.lab2 (address-taken):
277     ; CHECK-NEXT: HINT 36
278     liveins: $x8
280     $x9 = ADRP target-flags(aarch64-page) blockaddress(@label_address, %ir-block.return)
281     renamable $w0 = ORRWri $wzr, 1984
282     renamable $x9 = ADDXri killed $x9, target-flags(aarch64-pageoff, aarch64-nc) blockaddress(@label_address, %ir-block.return), 0
283     STRXui killed renamable $x9, killed renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @label_address.addr :: (store 8 into @label_address.addr)
284     RET undef $lr, implicit killed $w0
287 # Function takes address of the entry block, so the entry block needs a BTI JC.
288 name:            label_address_entry
289 body:             |
290   bb.0.entry (address-taken):
291     ; CHECK-LABEL: label_address_entry
292     ; CHECK: bb.0.entry (address-taken):
293     ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
294     ; CHECK-NEXT: {{  }}
295     ; CHECK-NEXT: HINT 38
296     ; CHECK: BR killed renamable $x9
297     successors: %bb.1(0x40000000), %bb.2(0x40000000)
299     renamable $x8 = ADRP target-flags(aarch64-page) @label_address.addr
300     renamable $x9 = LDRXui renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @label_address.addr :: (dereferenceable load 8 from @label_address.addr)
301     BR killed renamable $x9
303   bb.1.return (address-taken):
304     ; CHECK: bb.1.return (address-taken):
305     ; CHECK-NEXT: HINT 36
306     liveins: $x8
308     $x9 = ADRP target-flags(aarch64-page) blockaddress(@label_address, %ir-block.entry)
309     renamable $w0 = ORRWri $wzr, 0
310     renamable $x9 = ADDXri killed $x9, target-flags(aarch64-pageoff, aarch64-nc) blockaddress(@label_address, %ir-block.entry), 0
311     STRXui killed renamable $x9, killed renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @label_address.addr :: (store 8 into @label_address.addr)
312     RET undef $lr, implicit killed $w0
314   bb.2.lab2:
315     ; CHECK: bb.2.lab2:
316     ; CHECK-NOT: HINT
317     liveins: $x8
319     $x9 = ADRP target-flags(aarch64-page) blockaddress(@label_address, %ir-block.return)
320     renamable $w0 = ORRWri $wzr, 1984
321     renamable $x9 = ADDXri killed $x9, target-flags(aarch64-pageoff, aarch64-nc) blockaddress(@label_address, %ir-block.return), 0
322     STRXui killed renamable $x9, killed renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @label_address.addr :: (store 8 into @label_address.addr)
323     RET undef $lr, implicit killed $w0