1 # RUN: llc -mtriple=x86_64-unknown-linux-gnu -run-pass shadow-call-stack -verify-machineinstrs -o - %s | FileCheck %s 2 --- | 3 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 } 12 13 attributes #0 = { shadowcallstack } 14 15 ... 16 --- 17 # CHECK-LABEL: name: no_return 18 name: no_return 19 tracksRegLiveness: true 20 frameInfo: 21 adjustsStack: true # not a leaf function 22 body: | 23 ; CHECK: bb.0: 24 bb.0: 25 ; CHECK-NEXT: $eax = MOV32ri 13 26 $eax = MOV32ri 13 27 ... 28 --- 29 # CHECK-LABEL: name: normal_return 30 name: normal_return 31 tracksRegLiveness: true 32 frameInfo: 33 adjustsStack: true # not a leaf function 34 body: | 35 ; CHECK: bb.0: 36 bb.0: 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 43 $eax = MOV32ri 13 44 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 52 RETQ $eax 53 54 ; CHECK: bb.1: 55 ; CHECK-NEXT; TRAP 56 ... 57 --- 58 # CHECK-LABEL: name: normal_return_leaf_func 59 name: normal_return_leaf_func 60 tracksRegLiveness: true 61 frameInfo: 62 adjustsStack: false # leaf function 63 body: | 64 ; CHECK: bb.0: 65 ; CHECK: liveins: $rcx 66 bb.0: 67 liveins: $rcx 68 69 ; CHECK: $rdx = MOV64rm $rsp, 1, $noreg, 0, $noreg 70 ; CHECK-NEXT: $eax = MOV32ri 0 71 $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 77 JMP_1 %bb.2 78 79 ; CHECK: bb.1 80 ; CHECK: liveins: $eax, $rdx 81 bb.1: 82 liveins: $eax 83 84 ; CHECKT: $eax = MOV32ri 1 85 $eax = MOV32ri 1 86 87 ; CHECK: bb.2 88 ; CHECK: liveins: $eax, $rdx 89 bb.2: 90 liveins: $eax 91 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 95 RETQ $eax 96 97 ; CHECK: bb.3: 98 ; CHECK-NEXT; TRAP 99 ... 100 --- 101 # CHECK-LABEL: name: short_leaf_func 102 name: short_leaf_func 103 tracksRegLiveness: true 104 frameInfo: 105 adjustsStack: false # leaf function 106 body: | 107 ; CHECK: bb.0: 108 bb.0: 109 ; Ensure these are not counted as machine instructions 110 CFI_INSTRUCTION 0 111 CFI_INSTRUCTION 0 112 CFI_INSTRUCTION 0 113 DBG_VALUE 0 114 DBG_VALUE 0 115 DBG_VALUE 0 116 117 ; CHECK: $eax = MOV32ri 13 118 $eax = MOV32ri 13 119 120 ; CHECK-NEXT: RETQ $eax 121 RETQ $eax 122 ... 123 --- 124 # CHECK-LABEL: name: normal_tail_call 125 name: normal_tail_call 126 tracksRegLiveness: true 127 frameInfo: 128 adjustsStack: true # not a leaf function 129 body: | 130 ; CHECK: bb.0: 131 bb.0: 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 138 $eax = MOV32ri 13 139 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 147 TAILJMPr64 $rax 148 149 ; CHECK: bb.1: 150 ; CHECK-NEXT; TRAP 151 ... 152 --- 153 # CHECK-LABEL: name: r11_tail_call 154 name: r11_tail_call 155 tracksRegLiveness: true 156 frameInfo: 157 adjustsStack: true # not a leaf function 158 body: | 159 ; CHECK: bb.0: 160 bb.0: 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 167 $eax = MOV32ri 13 168 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 177 178 ; CHECK: bb.1: 179 ; CHECK-NEXT; TRAP 180 ... 181 --- 182 # CHECK-LABEL: name: conditional_tail_call 183 name: conditional_tail_call 184 tracksRegLiveness: true 185 frameInfo: 186 adjustsStack: true # not a leaf function 187 body: | 188 ; CHECK: bb.0: 189 bb.0: 190 ; CHECK: $eax = MOV32ri 13 191 $eax = MOV32ri 13 192 193 ; CHECK-NEXT: TAILJMPd64_CC @conditional_tail_call, undef $eflags 194 TAILJMPd64_CC @conditional_tail_call, undef $eflags 195 ... 196 --- 197 # CHECK-LABEL: name: r10_live_in 198 name: r10_live_in 199 tracksRegLiveness: true 200 frameInfo: 201 adjustsStack: true # not a leaf function 202 body: | 203 ; CHECK: bb.0: 204 ; CHECK: liveins: $r10 205 bb.0: 206 liveins: $r10 207 208 ; CHECK: $eax = MOV32ri 13 209 $eax = MOV32ri 13 210 ; CHECK-NEXT: RETQ $eax 211 RETQ $eax 212 ... 213