[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / AArch64 / speculation-hardening-sls.ll
blob89f2fba022b7c23cf6c3c2dc52d278276cb95200
1 ; RUN: llc -mattr=harden-sls-retbr,harden-sls-blr -verify-machineinstrs -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,HARDEN,HARDEN-COMDAT,ISBDSB,ISBDSBDAGISEL
2 ; RUN: llc -mattr=harden-sls-retbr,harden-sls-blr,harden-sls-nocomdat -verify-machineinstrs -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,HARDEN,HARDEN-COMDAT-OFF,ISBDSB,ISBDSBDAGISEL
3 ; RUN: llc -mattr=harden-sls-retbr,harden-sls-blr -mattr=+sb -verify-machineinstrs -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,HARDEN,SB,SBDAGISEL
4 ; RUN: llc -global-isel -global-isel-abort=0 -mattr=harden-sls-retbr,harden-sls-blr -verify-machineinstrs -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,HARDEN,HARDEN-COMDAT,ISBDSB
5 ; RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,NOHARDEN
6 ; RUN: llc -global-isel -global-isel-abort=0 -mattr=harden-sls-retbr,harden-sls-blr,harden-sls-nocomdat -verify-machineinstrs -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,HARDEN,HARDEN-COMDAT-OFF,ISBDSB
7 ; RUN: llc -global-isel -global-isel-abort=0 -mattr=harden-sls-retbr,harden-sls-blr -mattr=+sb -verify-machineinstrs -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,HARDEN,SB
9 ; Function Attrs: norecurse nounwind readnone
10 define dso_local i32 @double_return(i32 %a, i32 %b) local_unnamed_addr {
11 entry:
12   %cmp = icmp sgt i32 %a, 0
13   br i1 %cmp, label %if.then, label %if.else
15 if.then:                                          ; preds = %entry
16   %div = sdiv i32 %a, %b
17   ret i32 %div
19 if.else:                                          ; preds = %entry
20   %div1 = sdiv i32 %b, %a
21   ret i32 %div1
22 ; CHECK-LABEL: double_return:
23 ; CHECK:       {{ret$}}
24 ; ISBDSB-NEXT: dsb sy
25 ; ISBDSB-NEXT: isb
26 ; SB-NEXT:     {{ sb$}}
27 ; CHECK:       {{ret$}}
28 ; ISBDSB-NEXT: dsb sy
29 ; ISBDSB-NEXT: isb
30 ; SB-NEXT:     {{ sb$}}
31 ; CHECK-NEXT: .Lfunc_end
34 @__const.indirect_branch.ptr = private unnamed_addr constant [2 x i8*] [i8* blockaddress(@indirect_branch, %return), i8* blockaddress(@indirect_branch, %l2)], align 8
36 ; Function Attrs: norecurse nounwind readnone
37 define dso_local i32 @indirect_branch(i32 %a, i32 %b, i32 %i) {
38 ; CHECK-LABEL: indirect_branch:
39 entry:
40   %idxprom = sext i32 %i to i64
41   %arrayidx = getelementptr inbounds [2 x i8*], [2 x i8*]* @__const.indirect_branch.ptr, i64 0, i64 %idxprom
42   %0 = load i8*, i8** %arrayidx, align 8
43   indirectbr i8* %0, [label %return, label %l2]
44 ; CHECK:       br x
45 ; ISBDSB-NEXT: dsb sy
46 ; ISBDSB-NEXT: isb
47 ; SB-NEXT:     {{ sb$}}
49 l2:                                               ; preds = %entry
50   br label %return
51 ; CHECK:       {{ret$}}
52 ; ISBDSB-NEXT: dsb sy
53 ; ISBDSB-NEXT: isb
54 ; SB-NEXT:     {{ sb$}}
56 return:                                           ; preds = %entry, %l2
57   %retval.0 = phi i32 [ 1, %l2 ], [ 0, %entry ]
58   ret i32 %retval.0
59 ; CHECK:       {{ret$}}
60 ; ISBDSB-NEXT: dsb sy
61 ; ISBDSB-NEXT: isb
62 ; SB-NEXT:     {{ sb$}}
63 ; CHECK-NEXT: .Lfunc_end
66 ; Check that RETAA and RETAB instructions are also protected as expected.
67 define dso_local i32 @ret_aa(i32 returned %a) local_unnamed_addr "target-features"="+neon,+v8.3a" "sign-return-address"="all" "sign-return-address-key"="a_key" {
68 entry:
69 ; CHECK-LABEL: ret_aa:
70 ; CHECK:       {{ retaa$}}
71 ; ISBDSB-NEXT: dsb sy
72 ; ISBDSB-NEXT: isb
73 ; SB-NEXT:     {{ sb$}}
74 ; CHECK-NEXT: .Lfunc_end
75           ret i32 %a
78 define dso_local i32 @ret_ab(i32 returned %a) local_unnamed_addr "target-features"="+neon,+v8.3a" "sign-return-address"="all" "sign-return-address-key"="b_key" {
79 entry:
80 ; CHECK-LABEL: ret_ab:
81 ; CHECK:       {{ retab$}}
82 ; ISBDSB-NEXT: dsb sy
83 ; ISBDSB-NEXT: isb
84 ; SB-NEXT:     {{ sb$}}
85 ; CHECK-NEXT: .Lfunc_end
86           ret i32 %a
89 define i32 @asmgoto() {
90 entry:
91 ; CHECK-LABEL: asmgoto:
92   callbr void asm sideeffect "B $0", "X"(i8* blockaddress(@asmgoto, %d))
93             to label %asm.fallthrough [label %d]
94      ; The asm goto above produces a direct branch:
95 ; CHECK:           //APP
96 ; CHECK-NEXT:      {{^[ \t]+b }}
97 ; CHECK-NEXT:      //NO_APP
98      ; For direct branches, no mitigation is needed.
99 ; ISDDSB-NOT: dsb sy
100 ; SB-NOT:     {{ sb$}}
102 asm.fallthrough:               ; preds = %entry
103   ret i32 0
104 ; CHECK:       {{ret$}}
105 ; ISBDSB-NEXT: dsb sy
106 ; ISBDSB-NEXT: isb
107 ; SB-NEXT:     {{ sb$}}
109 d:                             ; preds = %asm.fallthrough, %entry
110   ret i32 1
111 ; CHECK:       {{ret$}}
112 ; ISBDSB-NEXT: dsb sy
113 ; ISBDSB-NEXT: isb
114 ; SB-NEXT:     {{ sb$}}
115 ; CHECK-NEXT: .Lfunc_end
118 define dso_local i32 @indirect_call(
119 i32 (...)* nocapture %f1, i32 (...)* nocapture %f2) {
120 entry:
121 ; CHECK-LABEL: indirect_call:
122   %callee.knr.cast = bitcast i32 (...)* %f1 to i32 ()*
123   %call = tail call i32 %callee.knr.cast()
124 ; HARDEN: bl {{__llvm_slsblr_thunk_x[0-9]+$}}
125   %callee.knr.cast1 = bitcast i32 (...)* %f2 to i32 ()*
126   %call2 = tail call i32 %callee.knr.cast1()
127 ; HARDEN: bl {{__llvm_slsblr_thunk_x[0-9]+$}}
128   %add = add nsw i32 %call2, %call
129   ret i32 %add
130 ; CHECK: .Lfunc_end
133 ; verify calling through a function pointer.
134 @a = dso_local local_unnamed_addr global i32 (...)* null, align 8
135 @b = dso_local local_unnamed_addr global i32 0, align 4
136 define dso_local void @indirect_call_global() local_unnamed_addr {
137 ; CHECK-LABEL: indirect_call_global:
138 entry:
139   %0 = load i32 ()*, i32 ()** bitcast (i32 (...)** @a to i32 ()**), align 8
140   %call = tail call i32 %0()  nounwind
141 ; HARDEN: bl {{__llvm_slsblr_thunk_x[0-9]+$}}
142   store i32 %call, i32* @b, align 4
143   ret void
144 ; CHECK: .Lfunc_end
147 ; Verify that neither x16 nor x17 are used when the BLR mitigation is enabled,
148 ; as a linker is allowed to clobber x16 or x17 on calls, which would break the
149 ; correct execution of the code sequence produced by the mitigation.
150 ; The below test carefully increases register pressure to persuade code
151 ; generation to produce a BLR x16. Yes, that is a bit fragile.
152 define i64 @check_x16(i64 (i8*, i64, i64, i64, i64, i64, i64, i64)** nocapture readonly %fp, i64 (i8*, i64, i64, i64, i64, i64, i64, i64)** nocapture readonly %fp2) "target-features"="+neon,+reserve-x10,+reserve-x11,+reserve-x12,+reserve-x13,+reserve-x14,+reserve-x15,+reserve-x18,+reserve-x20,+reserve-x21,+reserve-x22,+reserve-x23,+reserve-x24,+reserve-x25,+reserve-x26,+reserve-x27,+reserve-x28,+reserve-x30,+reserve-x9" {
153 entry:
154 ; CHECK-LABEL: check_x16:
155   %0 = load i64 (i8*, i64, i64, i64, i64, i64, i64, i64)*, i64 (i8*, i64, i64, i64, i64, i64, i64, i64)** %fp, align 8
156   %1 = bitcast i64 (i8*, i64, i64, i64, i64, i64, i64, i64)** %fp2 to i8**
157   %2 = load i8*, i8** %1, align 8
158   %call = call i64 %0(i8* %2, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0)
159   %3 = load i64 (i8*, i64, i64, i64, i64, i64, i64, i64)*, i64 (i8*, i64, i64, i64, i64, i64, i64, i64)** %fp2, align 8
160   %4 = bitcast i64 (i8*, i64, i64, i64, i64, i64, i64, i64)** %fp to i8**
161   %5 = load i8*, i8** %4, align 8;, !tbaa !2
162   %call1 = call i64 %3(i8* %5, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0)
163 ; NOHARDEN:   blr x16
164 ; ISBDSB-NOT: bl __llvm_slsblr_thunk_x16
165 ; SB-NOT:     bl __llvm_slsblr_thunk_x16
166 ; CHECK
167   %add = add nsw i64 %call1, %call
168   ret i64 %add
169 ; CHECK: .Lfunc_end
172 ; Verify that the transformation works correctly for x29 when it is not
173 ; reserved to be used as a frame pointer.
174 ; Since this is sensitive to register allocation choices, only check this with
175 ; DAGIsel to avoid too much accidental breaking of this test that is a bit
176 ; brittle.
177 define i64 @check_x29(i64 (i8*, i8*, i64, i64, i64, i64, i64, i64)** nocapture readonly %fp,
178                       i64 (i8*, i8*, i64, i64, i64, i64, i64, i64)** nocapture readonly %fp2,
179                       i64 (i8*, i8*, i64, i64, i64, i64, i64, i64)** nocapture readonly %fp3)
180 "target-features"="+neon,+reserve-x10,+reserve-x11,+reserve-x12,+reserve-x13,+reserve-x14,+reserve-x15,+reserve-x18,+reserve-x20,+reserve-x21,+reserve-x22,+reserve-x23,+reserve-x24,+reserve-x25,+reserve-x26,+reserve-x27,+reserve-x28,+reserve-x9"
181 "frame-pointer"="none"
183 entry:
184 ; CHECK-LABEL: check_x29:
185   %0 = load i64 (i8*, i8*, i64, i64, i64, i64, i64, i64)*, i64 (i8*, i8*, i64, i64, i64, i64, i64, i64)** %fp, align 8
186   %1 = bitcast i64 (i8*, i8*, i64, i64, i64, i64, i64, i64)** %fp2 to i8**
187   %2 = load i8*, i8** %1, align 8
188   %3 = load i64 (i8*, i8*, i64, i64, i64, i64, i64, i64)*, i64 (i8*, i8*, i64, i64, i64, i64, i64, i64)** %fp2, align 8
189   %4 = bitcast i64 (i8*, i8*, i64, i64, i64, i64, i64, i64)** %fp3 to i8**
190   %5 = load i8*, i8** %4, align 8
191   %6 = load i64 (i8*, i8*, i64, i64, i64, i64, i64, i64)*, i64 (i8*, i8*, i64, i64, i64, i64, i64, i64)** %fp3, align 8
192   %7 = bitcast i64 (i8*, i8*, i64, i64, i64, i64, i64, i64)** %fp to i8**
193   %8 = load i8*, i8** %7, align 8
194   %call = call i64 %0(i8* %2, i8* %5, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0)
195   %call1 = call i64 %3(i8* %2, i8* %5, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0)
196 ; NOHARDEN:      blr x29
197 ; ISBDSBDAGISEL: bl __llvm_slsblr_thunk_x29
198 ; SBDAGISEL:     bl __llvm_slsblr_thunk_x29
199 ; CHECK
200   %call2 = call i64 %6(i8* %2, i8* %8, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0)
201   %add = add nsw i64 %call1, %call
202   %add1 = add nsw i64 %call2, %add
203   ret i64 %add1
204 ; CHECK: .Lfunc_end
207 ; HARDEN-label: __llvm_slsblr_thunk_x0:
208 ; HARDEN:    mov x16, x0
209 ; HARDEN:    br x16
210 ; ISBDSB-NEXT: dsb sy
211 ; ISBDSB-NEXT: isb
212 ; SB-NEXT:     dsb sy
213 ; SB-NEXT:     isb
214 ; HARDEN-NEXT: .Lfunc_end
215 ; HARDEN-COMDAT:  .section .text.__llvm_slsblr_thunk_x19
216 ; HARDEN-COMDAT:  .hidden __llvm_slsblr_thunk_x19
217 ; HARDEN-COMDAT:  .weak __llvm_slsblr_thunk_x19
218 ; HARDEN-COMDAT: .type  __llvm_slsblr_thunk_x19,@function
219 ; HARDEN-COMDAT-OFF-NOT:  .section .text.__llvm_slsblr_thunk_x19
220 ; HARDEN-COMDAT-OFF-NOT:  .hidden __llvm_slsblr_thunk_x19
221 ; HARDEN-COMDAT-OFF-NOT:  .weak __llvm_slsblr_thunk_x19
222 ; HARDEN-COMDAT-OFF:      .type __llvm_slsblr_thunk_x19,@function
223 ; HARDEN-label: __llvm_slsblr_thunk_x19:
224 ; HARDEN:    mov x16, x19
225 ; HARDEN:    br x16
226 ; ISBDSB-NEXT: dsb sy
227 ; ISBDSB-NEXT: isb
228 ; SB-NEXT:     dsb sy
229 ; SB-NEXT:     isb
230 ; HARDEN-NEXT: .Lfunc_end