[ARM] More MVE compare vector splat combines for ANDs
[llvm-complete.git] / test / CodeGen / AArch64 / speculation-hardening.mir
blob5991c4df0407f7ec701d89cc0608962cbcf45f9f
1 # RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu \
2 # RUN:     -start-before aarch64-speculation-hardening -o - %s \
3 # RUN:   | FileCheck %s --dump-input-on-failure
5 # Check that the speculation hardening pass generates code as expected for
6 # basic blocks ending with a variety of branch patterns:
7 # - (1) no branches (fallthrough)
8 # - (2) one unconditional branch
9 # - (3) one conditional branch + fall-through
10 # - (4) one conditional branch + one unconditional branch
11 # - other direct branches don't seem to be generated by the AArch64 codegen
12 --- |
13   define void @nobranch_fallthrough(i32 %a, i32 %b) speculative_load_hardening {
14    ret void
15   }
16   define void @uncondbranch(i32 %a, i32 %b) speculative_load_hardening {
17    ret void
18   }
19   define void @condbranch_fallthrough(i32 %a, i32 %b) speculative_load_hardening {
20    ret void
21   }
22   define void @condbranch_uncondbranch(i32 %a, i32 %b) speculative_load_hardening {
23    ret void
24   }
25   define void @indirectbranch(i32 %a, i32 %b) speculative_load_hardening {
26    ret void
27   }
28   ; Also check that a non-default temporary register gets picked correctly to
29   ; transfer the SP to to and it with the taint register when the default
30   ; temporary isn't available.
31   define void @indirect_call_x17(i32 %a, i32 %b) speculative_load_hardening {
32    ret void
33   }
34   @g = common dso_local local_unnamed_addr global i64 (...)* null, align 8
35   define void @indirect_tailcall_x17(i32 %a, i32 %b) speculative_load_hardening {
36    ret void
37   }
38   define void @indirect_call_lr(i32 %a, i32 %b) speculative_load_hardening {
39    ret void
40   }
41   define void @RS_cannot_find_available_regs() speculative_load_hardening {
42    ret void
43   }
44 ...
45 ---
46 name:            nobranch_fallthrough
47 tracksRegLiveness: true
48 body:             |
49   ; CHECK-LABEL: nobranch_fallthrough
50   bb.0:
51     successors: %bb.1
52     liveins: $w0, $w1
53   ; CHECK-NOT: csel
54   bb.1:
55     liveins: $w0
56    RET undef $lr, implicit $w0
57 ...
58 ---
59 name:            uncondbranch
60 tracksRegLiveness: true
61 body:             |
62   ; CHECK-LABEL: uncondbranch
63   bb.0:
64     successors: %bb.1
65     liveins: $w0, $w1
66     B %bb.1
67   ; CHECK-NOT: csel
68   bb.1:
69    liveins: $w0
70    RET undef $lr, implicit $w0
71 ...
72 ---
73 name:            condbranch_fallthrough
74 tracksRegLiveness: true
75 body:             |
76   ; CHECK-LABEL: condbranch_fallthrough
77   bb.0:
78     successors: %bb.1, %bb.2
79     liveins: $w0, $w1
80     $wzr = SUBSWrs renamable $w0, renamable $w1, 0, implicit-def $nzcv, implicit-def $nzcv
81     Bcc 11, %bb.2, implicit $nzcv
82   ; CHECK: b.lt [[BB_LT_T:\.LBB[0-9_]+]]
84   bb.1:
85     liveins: $nzcv, $w0
86   ; CHECK: csel x16, x16, xzr, ge
87     RET undef $lr, implicit $w0
88   bb.2:
89     liveins: $nzcv, $w0
90   ; CHECK: csel x16, x16, xzr, lt
91     RET undef $lr, implicit $w0
92 ...
93 ---
94 name:            condbranch_uncondbranch
95 tracksRegLiveness: true
96 body:             |
97   ; CHECK-LABEL: condbranch_uncondbranch
98   bb.0:
99     successors: %bb.1, %bb.2
100     liveins: $w0, $w1
101     $wzr = SUBSWrs renamable $w0, renamable $w1, 0, implicit-def $nzcv, implicit-def $nzcv
102     Bcc 11, %bb.2, implicit $nzcv
103     B %bb.1, implicit $nzcv
104   ; CHECK: b.lt [[BB_LT_T:\.LBB[0-9_]+]]
106   bb.1:
107     liveins: $nzcv, $w0
108   ; CHECK: csel x16, x16, xzr, ge
109     RET undef $lr, implicit $w0
110   bb.2:
111     liveins: $nzcv, $w0
112   ; CHECK: csel x16, x16, xzr, lt
113     RET undef $lr, implicit $w0
116 name:            indirectbranch
117 tracksRegLiveness: true
118 body:             |
119   ; Check that no instrumentation is done on indirect branches (for now).
120   ; CHECK-LABEL: indirectbranch
121   bb.0:
122     successors: %bb.1, %bb.2
123     liveins: $x0
124     BR $x0
125   bb.1:
126    liveins: $x0
127   ; CHECK-NOT: csel
128    RET undef $lr, implicit $x0
129   bb.2:
130    liveins: $x0
131   ; CHECK-NOT: csel
132    RET undef $lr, implicit $x0
135 name:            indirect_call_x17
136 tracksRegLiveness: true
137 body:             |
138   bb.0:
139     liveins: $x17
140     ; CHECK-LABEL: indirect_call_x17
141     ; CHECK:       mov x0, sp
142     ; CHECK:       and x0, x0, x16
143     ; CHECK:       mov sp, x0
144     ; CHECK:       blr x17
145     BLR killed renamable $x17, implicit-def dead $lr, implicit $sp
146     RET undef $lr, implicit undef $w0
149 name:           indirect_tailcall_x17
150 tracksRegLiveness: true
151 body:             |
152   bb.0:
153     liveins: $x0
154     ; CHECK-LABEL: indirect_tailcall_x17
155     ; CHECK:       mov x1, sp
156     ; CHECK:       and x1, x1, x16
157     ; CHECK:       mov sp, x1
158     ; CHECK:       br x17
159     $x8 = ADRP target-flags(aarch64-page) @g
160     $x17 = LDRXui killed $x8, target-flags(aarch64-pageoff, aarch64-nc) @g
161     TCRETURNri killed $x17, 0, implicit $sp, implicit $x0
164 name:           indirect_call_lr
165 tracksRegLiveness: true
166 body:             |
167   bb.0:
168     ; CHECK-LABEL: indirect_call_lr
169     ; CHECK:            mov x1, sp
170     ; CHECK-NEXT:       and x1, x1, x16
171     ; CHECK-NEXT:       mov sp, x1
172     ; CHECK-NEXT:       blr x30
173     liveins: $x0, $lr
174     BLR killed renamable $lr, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def $w0
175     $w0 = nsw ADDWri killed $w0, 1, 0
176     RET undef $lr, implicit $w0
179 name:           RS_cannot_find_available_regs
180 tracksRegLiveness: true
181 body:             |
182   bb.0:
183     ; In the rare case when no free temporary register is available for the
184     ; propagate taint-to-sp operation, just put in a full speculation barrier
185     ; (isb+dsb sy) at the start of the basic block. And don't put masks on
186     ; instructions for the rest of the basic block, since speculation in that
187     ; basic block was already done, so no need to do masking.
188     ; CHECK-LABEL: RS_cannot_find_available_regs
189     ; CHECK:       dsb sy
190     ; CHECK-NEXT:  isb
191     ; CHECK-NEXT:  ldr x0, [x0]
192     ; The following 2 instructions come from propagating the taint encoded in
193     ; sp at function entry to x16. It turns out the taint info in x16 is not
194     ; used in this function, so those instructions could be optimized away. An
195     ; optimization for later if it turns out this situation occurs often enough.
196     ; CHECK-NEXT:  cmp sp, #0
197     ; CHECK-NEXT:  csetm x16, ne
198     ; CHECK-NEXT:  ret
199     liveins: $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15, $x17, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27, $x28, $fp, $lr
200      $x0 = LDRXui killed $x0, 0
201      RET undef $lr, implicit $x0