[AArch64,ELF] Restrict MOVZ/MOVK to non-PIC large code model (#70178)
[llvm-project.git] / llvm / test / CodeGen / X86 / indirect-branch-tracking.ll
blobd4b0ed3aae69b326be4af5bfd2e2e0c2ea076ccf
1 ; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck %s --check-prefix=ALL --check-prefix=X86_64
2 ; RUN: llc -mtriple=x86_64-unknown-unknown-gnux32 < %s | FileCheck %s --check-prefix=ALL --check-prefix=X86_64
3 ; RUN: llc -mtriple=i386-unknown-unknown < %s | FileCheck %s --check-prefix=ALL --check-prefix=X86
4 ; FIXME: Fix machine verifier issues and remove -verify-machineinstrs=0. PR39439.
5 ; RUN: llc -mtriple i386-windows-gnu -exception-model sjlj -verify-machineinstrs=0 < %s | FileCheck %s --check-prefix=SJLJ
7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 ;; Test1
9 ;; -----
10 ;; Checks ENDBR insertion in case of switch case statement.
11 ;; Also since the function is not internal, make sure that endbr32/64 was 
12 ;; added at the beginning of the function.
13 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15 define i8 @test1(){
16 ; ALL-LABEL:   test1
17 ; X86_64:      endbr64
18 ; X86:         endbr32
19 ; ALL:         jmp{{q|l}} *
20 ; ALL:         .LBB0_1:
21 ; X86_64-NEXT: endbr64
22 ; X86-NEXT:    endbr32
23 ; ALL:         .LBB0_2:
24 ; X86_64-NEXT: endbr64
25 ; X86-NEXT:    endbr32
26 entry:
27   %0 = select i1 undef, ptr blockaddress(@test1, %bb), ptr blockaddress(@test1, %bb6) ; <ptr> [#uses=1]
28   indirectbr ptr %0, [label %bb, label %bb6]
30 bb:                                               ; preds = %entry
31   ret i8 1
33 bb6:                                              ; preds = %entry
34   ret i8 2
37 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
38 ;; Test2
39 ;; -----
40 ;; Checks NOTRACK insertion in case of switch case statement.
41 ;; Check that there is no ENDBR insertion in the following case statements.
42 ;; Also since the function is not internal, ENDBR instruction should be
43 ;; added to its first basic block.
44 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
46 define i32 @test2(i32 %a) {
47 ; ALL-LABEL:   test2
48 ; X86_64:      endbr64
49 ; X86:         endbr32
50 ; ALL:         notrack jmp{{q|l}} *
51 ; X86_64-NOT:      endbr64
52 ; X86-NOT:         endbr32
53 entry:
54   %retval = alloca i32, align 4
55   %a.addr = alloca i32, align 4
56   store i32 %a, ptr %a.addr, align 4
57   %0 = load i32, ptr %a.addr, align 4
58   switch i32 %0, label %sw.default [
59     i32 0, label %sw.bb
60     i32 1, label %sw.bb1
61     i32 2, label %sw.bb2
62     i32 3, label %sw.bb3
63     i32 4, label %sw.bb4
64   ]
66 sw.bb:                                            ; preds = %entry
67   store i32 5, ptr %retval, align 4
68   br label %return
70 sw.bb1:                                           ; preds = %entry
71   store i32 7, ptr %retval, align 4
72   br label %return
74 sw.bb2:                                           ; preds = %entry
75   store i32 2, ptr %retval, align 4
76   br label %return
78 sw.bb3:                                           ; preds = %entry
79   store i32 32, ptr %retval, align 4
80   br label %return
82 sw.bb4:                                           ; preds = %entry
83   store i32 73, ptr %retval, align 4
84   br label %return
86 sw.default:                                       ; preds = %entry
87   store i32 0, ptr %retval, align 4
88   br label %return
90 return:                                           ; preds = %sw.default, %sw.bb4, %sw.bb3, %sw.bb2, %sw.bb1, %sw.bb
91   %1 = load i32, ptr %retval, align 4
92   ret i32 %1
95 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
96 ;; Test3
97 ;; -----
98 ;; Checks ENDBR insertion in case of indirect call instruction.
99 ;; The new instruction should be added to the called function (test6)
100 ;; although it is internal.
101 ;; Also since the function is not internal, ENDBR instruction should be
102 ;; added to its first basic block.
103 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
105 define void @test3() {
106 ; ALL-LABEL:   test3
107 ; X86_64:      endbr64
108 ; X86:         endbr32
109 ; ALL:         call{{q|l}} *
110 entry:
111   %f = alloca ptr, align 8
112   store ptr @test6, ptr %f, align 8
113   %0 = load ptr, ptr %f, align 8
114   %call = call i32 (...) %0()
115   ret void
118 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
119 ;; Test4
120 ;; -----
121 ;; Checks ENDBR insertion in case of setjmp-like function calls.
122 ;; Also since the function is not internal, ENDBR instruction should be
123 ;; added to its first basic block.
124 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
126 @buf = internal global [5 x ptr] zeroinitializer
127 declare ptr @llvm.frameaddress(i32)
128 declare ptr @llvm.stacksave()
129 declare i32 @llvm.eh.sjlj.setjmp(ptr)
131 define i32 @test4() {
132 ; ALL-LABEL:   test4
133 ; X86_64:      endbr64
134 ; X86:         endbr32
135 ; ALL:         .LBB3_3:
136 ; X86_64-NEXT: endbr64
137 ; X86-NEXT:    endbr32
138   %fp = tail call ptr @llvm.frameaddress(i32 0)
139   store ptr %fp, ptr @buf, align 16
140   %sp = tail call ptr @llvm.stacksave()
141   store ptr %sp, ptr getelementptr inbounds ([5 x ptr], ptr @buf, i64 0, i64 2), align 16
142   %r = tail call i32 @llvm.eh.sjlj.setjmp(ptr @buf)
143   ret i32 %r
146 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
147 ;; Test5
148 ;; -----
149 ;; Checks ENDBR insertion in case of internal function.
150 ;; Since the function is internal and its address was not taken,
151 ;; make sure that endbr32/64 was not added at the beginning of the 
152 ;; function.
153 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
155 define internal i8 @test5(){
156 ; ALL-LABEL:   test5
157 ; X86_64-NOT:      endbr64
158 ; X86-NOT:         endbr32
159   ret i8 1
162 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
163 ;; Test6
164 ;; -----
165 ;; Checks ENDBR insertion in case of function that its was address taken.
166 ;; Since the function's address was taken by test3() and despite being
167 ;; internal, check for added endbr32/64 at the beginning of the function.
168 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
170 define internal i32 @test6(i32 %a) {
171 ; ALL-LABEL:   test6
172 ; X86_64:      endbr64
173 ; X86:         endbr32
174   ret i32 1
177 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
178 ;; Test7
179 ;; -----
180 ;; Checks ENDBR insertion in case of non-intrenal function.
181 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
183 define i32 @test7() {
184 ; ALL-LABEL:   test7
185 ; X86_64:      endbr64
186 ; X86:         endbr32
187   ret i32 1
190 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
191 ;; Test8
192 ;; -----
193 ;; Checks that NO TRACK prefix is not added for indirect jumps to a jump-
194 ;; table that was created for SJLJ dispatch.
195 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
197 declare void @_Z20function_that_throwsv()
198 declare i32 @__gxx_personality_sj0(...)
199 declare ptr @__cxa_begin_catch(ptr)
200 declare void @__cxa_end_catch()
202 define void @test8() personality ptr @__gxx_personality_sj0 {
203 ;SJLJ-LABEL:    test8
204 ;SJLJ-NOT:      ds
205 entry:
206   invoke void @_Z20function_that_throwsv()
207           to label %try.cont unwind label %lpad
209 lpad:
210   %0 = landingpad { ptr, i32 }
211           catch ptr null
212   %1 = extractvalue { ptr, i32 } %0, 0
213   %2 = tail call ptr @__cxa_begin_catch(ptr %1)
214   tail call void @__cxa_end_catch()
215   br label %try.cont
217 try.cont:
218   ret void
221 !llvm.module.flags = !{!0}
223 !0 = !{i32 8, !"cf-protection-branch", i32 1}