1 # RUN: llc -mtriple=x86_64-unknown-linux-gnu -run-pass shadow-call-stack -verify-machineinstrs -o - %s | FileCheck %s
4 define void @no_return() #0 { ret void }
5 define void @normal_return() #0 { ret void }
6 define void @normal_return_leaf_func() #0 { ret void }
7 define void @short_leaf_func() #0 { ret void }
8 define void @normal_tail_call() #0 { ret void }
9 define void @r11_tail_call() #0 { ret void }
10 define void @conditional_tail_call() #0 { ret void }
11 define void @r10_live_in() #0 { ret void }
13 attributes #0 = { shadowcallstack }
17 # CHECK-LABEL: name: no_return
19 tracksRegLiveness: true
21 adjustsStack: true # not a leaf function
25 ; CHECK-NEXT: $eax = MOV32ri 13
29 # CHECK-LABEL: name: normal_return
31 tracksRegLiveness: true
33 adjustsStack: true # not a leaf function
37 ; CHECK: $r10 = MOV64rm $rsp, 1, $noreg, 0, $noreg
38 ; CHECK-NEXT: $r11 = XOR64rr undef $r11, undef $r11, implicit-def $eflags
39 ; CHECK-NEXT: ADD64mi8 $r11, 1, $noreg, 0, $gs, 8, implicit-def $eflags
40 ; CHECK-NEXT: $r11 = MOV64rm $r11, 1, $noreg, 0, $gs
41 ; CHECK-NEXT: MOV64mr $r11, 1, $noreg, 0, $gs, $r10
42 ; CHECK-NEXT: $eax = MOV32ri 13
45 ; CHECK-NEXT: $r11 = XOR64rr undef $r11, undef $r11, implicit-def $eflags
46 ; CHECK-NEXT: $r10 = MOV64rm $r11, 1, $noreg, 0, $gs
47 ; CHECK-NEXT: $r10 = MOV64rm $r10, 1, $noreg, 0, $gs
48 ; CHECK-NEXT: SUB64mi8 $r11, 1, $noreg, 0, $gs, 8, implicit-def $eflags
49 ; CHECK-NEXT: CMP64mr $rsp, 1, $noreg, 0, $noreg, $r10, implicit-def $eflags
50 ; CHECK-NEXT: JNE_1 %bb.1, implicit $eflags
51 ; CHECK-NEXT: RETQ $eax
58 # CHECK-LABEL: name: normal_return_leaf_func
59 name: normal_return_leaf_func
60 tracksRegLiveness: true
62 adjustsStack: false # leaf function
65 ; CHECK: liveins: $rcx
69 ; CHECK: $rdx = MOV64rm $rsp, 1, $noreg, 0, $noreg
70 ; CHECK-NEXT: $eax = MOV32ri 0
72 ; CHECK-NEXT: CMP64ri8 $rcx, 5, implicit-def $eflags
73 CMP64ri8 $rcx, 5, implicit-def $eflags
74 ; CHECK-NEXT: JA_1 %bb.1, implicit $eflags
75 JA_1 %bb.1, implicit $eflags
76 ; CHECK-NEXT: JMP_1 %bb.2
80 ; CHECK: liveins: $eax, $rdx
84 ; CHECKT: $eax = MOV32ri 1
88 ; CHECK: liveins: $eax, $rdx
92 ; CHECK: CMP64mr $rsp, 1, $noreg, 0, $noreg, $rdx, implicit-def $eflags
93 ; CHECK-NEXT: JNE_1 %bb.3, implicit $eflags
94 ; CHECK-NEXT: RETQ $eax
101 # CHECK-LABEL: name: short_leaf_func
102 name: short_leaf_func
103 tracksRegLiveness: true
105 adjustsStack: false # leaf function
109 ; Ensure these are not counted as machine instructions
117 ; CHECK: $eax = MOV32ri 13
120 ; CHECK-NEXT: RETQ $eax
124 # CHECK-LABEL: name: normal_tail_call
125 name: normal_tail_call
126 tracksRegLiveness: true
128 adjustsStack: true # not a leaf function
132 ; CHECK: $r10 = MOV64rm $rsp, 1, $noreg, 0, $noreg
133 ; CHECK-NEXT: $r11 = XOR64rr undef $r11, undef $r11, implicit-def $eflags
134 ; CHECK-NEXT: ADD64mi8 $r11, 1, $noreg, 0, $gs, 8, implicit-def $eflags
135 ; CHECK-NEXT: $r11 = MOV64rm $r11, 1, $noreg, 0, $gs
136 ; CHECK-NEXT: MOV64mr $r11, 1, $noreg, 0, $gs, $r10
137 ; CHECK-NEXT: $eax = MOV32ri 13
140 ; CHECK-NEXT: $r11 = XOR64rr undef $r11, undef $r11, implicit-def $eflags
141 ; CHECK-NEXT: $r10 = MOV64rm $r11, 1, $noreg, 0, $gs
142 ; CHECK-NEXT: $r10 = MOV64rm $r10, 1, $noreg, 0, $gs
143 ; CHECK-NEXT: SUB64mi8 $r11, 1, $noreg, 0, $gs, 8, implicit-def $eflags
144 ; CHECK-NEXT: CMP64mr $rsp, 1, $noreg, 0, $noreg, $r10, implicit-def $eflags
145 ; CHECK-NEXT: JNE_1 %bb.1, implicit $eflags
146 ; CHECK-NEXT: TAILJMPr64 $rax
153 # CHECK-LABEL: name: r11_tail_call
155 tracksRegLiveness: true
157 adjustsStack: true # not a leaf function
161 ; CHECK: $r10 = MOV64rm $rsp, 1, $noreg, 0, $noreg
162 ; CHECK-NEXT: $r11 = XOR64rr undef $r11, undef $r11, implicit-def $eflags
163 ; CHECK-NEXT: ADD64mi8 $r11, 1, $noreg, 0, $gs, 8, implicit-def $eflags
164 ; CHECK-NEXT: $r11 = MOV64rm $r11, 1, $noreg, 0, $gs
165 ; CHECK-NEXT: MOV64mr $r11, 1, $noreg, 0, $gs, $r10
166 ; CHECK-NEXT: $eax = MOV32ri 13
169 ; CHECK-NEXT: $r10 = XOR64rr undef $r10, undef $r10, implicit-def $eflags
170 ; CHECK-NEXT: $r10 = MOV64rm $r10, 1, $noreg, 0, $gs
171 ; CHECK-NEXT: $r10 = MOV64rm $r10, 1, $noreg, 0, $gs
172 ; CHECK-NEXT: SUB64mi8 $noreg, 1, $noreg, 0, $gs, 8, implicit-def $eflags
173 ; CHECK-NEXT: CMP64mr $rsp, 1, $noreg, 0, $noreg, $r10, implicit-def $eflags
174 ; CHECK-NEXT: JNE_1 %bb.1, implicit $eflags
175 ; CHECK-NEXT: TAILJMPr64 undef $r11
176 TAILJMPr64 undef $r11
182 # CHECK-LABEL: name: conditional_tail_call
183 name: conditional_tail_call
184 tracksRegLiveness: true
186 adjustsStack: true # not a leaf function
190 ; CHECK: $eax = MOV32ri 13
193 ; CHECK-NEXT: TAILJMPd64_CC @conditional_tail_call, undef $eflags
194 TAILJMPd64_CC @conditional_tail_call, undef $eflags
197 # CHECK-LABEL: name: r10_live_in
199 tracksRegLiveness: true
201 adjustsStack: true # not a leaf function
204 ; CHECK: liveins: $r10
208 ; CHECK: $eax = MOV32ri 13
210 ; CHECK-NEXT: RETQ $eax