1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2 ; RUN: llc -mtriple=x86_64-apple-macosx -mcpu=core2 < %s | FileCheck %s 3 4 declare i64 @testi() 5 6 define i64 @test_trivial() { 7 ; CHECK-LABEL: test_trivial: 8 ; CHECK: ## %bb.0: ## %entry 9 ; CHECK-NEXT: jmp _testi ## TAILCALL 10 entry: 11 %A = tail call i64 @testi() 12 ret i64 %A 13 } 14 15 define i64 @test_noop_bitcast() { 16 ; CHECK-LABEL: test_noop_bitcast: 17 ; CHECK: ## %bb.0: ## %entry 18 ; CHECK-NEXT: jmp _testi ## TAILCALL 19 entry: 20 %A = tail call i64 @testi() 21 %B = bitcast i64 %A to i64 22 ret i64 %B 23 } 24 25 ; Tail call shouldn't be blocked by no-op inttoptr. 26 define i8* @test_inttoptr() { 27 ; CHECK-LABEL: test_inttoptr: 28 ; CHECK: ## %bb.0: ## %entry 29 ; CHECK-NEXT: jmp _testi ## TAILCALL 30 entry: 31 %A = tail call i64 @testi() 32 %B = inttoptr i64 %A to i8* 33 ret i8* %B 34 } 35 36 declare <4 x float> @testv() 37 38 define <4 x i32> @test_vectorbitcast() { 39 ; CHECK-LABEL: test_vectorbitcast: 40 ; CHECK: ## %bb.0: ## %entry 41 ; CHECK-NEXT: jmp _testv ## TAILCALL 42 entry: 43 %A = tail call <4 x float> @testv() 44 %B = bitcast <4 x float> %A to <4 x i32> 45 ret <4 x i32> %B 46 } 47 48 declare { i64, i64 } @testp() 49 50 define {i64, i64} @test_pair_trivial() { 51 ; CHECK-LABEL: test_pair_trivial: 52 ; CHECK: ## %bb.0: ## %entry 53 ; CHECK-NEXT: jmp _testp ## TAILCALL 54 entry: 55 %A = tail call { i64, i64} @testp() 56 ret { i64, i64} %A 57 } 58 59 define {i64, i64} @test_pair_notail() { 60 ; CHECK-LABEL: test_pair_notail: 61 ; CHECK: ## %bb.0: ## %entry 62 ; CHECK-NEXT: pushq %rax 63 ; CHECK-NEXT: .cfi_def_cfa_offset 16 64 ; CHECK-NEXT: callq _testi 65 ; CHECK-NEXT: movq %rax, %rdx 66 ; CHECK-NEXT: popq %rcx 67 ; CHECK-NEXT: retq 68 entry: 69 %A = tail call i64 @testi() 70 71 %b = insertvalue {i64, i64} undef, i64 %A, 0 72 %c = insertvalue {i64, i64} %b, i64 %A, 1 73 74 ret { i64, i64} %c 75 } 76 77 define {i64, i64} @test_pair_extract_trivial() { 78 ; CHECK-LABEL: test_pair_extract_trivial: 79 ; CHECK: ## %bb.0: ## %entry 80 ; CHECK-NEXT: jmp _testp ## TAILCALL 81 entry: 82 %A = tail call { i64, i64} @testp() 83 %x = extractvalue { i64, i64} %A, 0 84 %y = extractvalue { i64, i64} %A, 1 85 86 %b = insertvalue {i64, i64} undef, i64 %x, 0 87 %c = insertvalue {i64, i64} %b, i64 %y, 1 88 89 ret { i64, i64} %c 90 } 91 92 define {i64, i64} @test_pair_extract_notail() { 93 ; CHECK-LABEL: test_pair_extract_notail: 94 ; CHECK: ## %bb.0: ## %entry 95 ; CHECK-NEXT: pushq %rax 96 ; CHECK-NEXT: .cfi_def_cfa_offset 16 97 ; CHECK-NEXT: callq _testp 98 ; CHECK-NEXT: movq %rax, %rcx 99 ; CHECK-NEXT: movq %rdx, %rax 100 ; CHECK-NEXT: movq %rcx, %rdx 101 ; CHECK-NEXT: popq %rcx 102 ; CHECK-NEXT: retq 103 entry: 104 %A = tail call { i64, i64} @testp() 105 %x = extractvalue { i64, i64} %A, 0 106 %y = extractvalue { i64, i64} %A, 1 107 108 %b = insertvalue {i64, i64} undef, i64 %y, 0 109 %c = insertvalue {i64, i64} %b, i64 %x, 1 110 111 ret { i64, i64} %c 112 } 113 114 define {i8*, i64} @test_pair_extract_conv() { 115 ; CHECK-LABEL: test_pair_extract_conv: 116 ; CHECK: ## %bb.0: ## %entry 117 ; CHECK-NEXT: jmp _testp ## TAILCALL 118 entry: 119 %A = tail call { i64, i64} @testp() 120 %x = extractvalue { i64, i64} %A, 0 121 %y = extractvalue { i64, i64} %A, 1 122 123 %x1 = inttoptr i64 %x to i8* 124 125 %b = insertvalue {i8*, i64} undef, i8* %x1, 0 126 %c = insertvalue {i8*, i64} %b, i64 %y, 1 127 128 ret { i8*, i64} %c 129 } 130 131 define {i64, i64} @test_pair_extract_multiple() { 132 ; CHECK-LABEL: test_pair_extract_multiple: 133 ; CHECK: ## %bb.0: ## %entry 134 ; CHECK-NEXT: jmp _testp ## TAILCALL 135 entry: 136 %A = tail call { i64, i64} @testp() 137 %x = extractvalue { i64, i64} %A, 0 138 %y = extractvalue { i64, i64} %A, 1 139 140 %b = insertvalue {i64, i64} undef, i64 %x, 0 141 %c = insertvalue {i64, i64} %b, i64 %y, 1 142 143 %x1 = extractvalue { i64, i64} %b, 0 144 %y1 = extractvalue { i64, i64} %c, 1 145 146 %d = insertvalue {i64, i64} undef, i64 %x1, 0 147 %e = insertvalue {i64, i64} %b, i64 %y1, 1 148 149 ret { i64, i64} %e 150 } 151 152 define {i64, i64} @test_pair_extract_undef() { 153 ; CHECK-LABEL: test_pair_extract_undef: 154 ; CHECK: ## %bb.0: ## %entry 155 ; CHECK-NEXT: jmp _testp ## TAILCALL 156 entry: 157 %A = tail call { i64, i64} @testp() 158 %x = extractvalue { i64, i64} %A, 0 159 160 %b = insertvalue {i64, i64} undef, i64 %x, 0 161 162 ret { i64, i64} %b 163 } 164 165 declare { i64, { i32, i32 } } @testn() 166 167 define {i64, {i32, i32}} @test_nest() { 168 ; CHECK-LABEL: test_nest: 169 ; CHECK: ## %bb.0: ## %entry 170 ; CHECK-NEXT: jmp _testn ## TAILCALL 171 entry: 172 %A = tail call { i64, { i32, i32 } } @testn() 173 %x = extractvalue { i64, { i32, i32}} %A, 0 174 %y = extractvalue { i64, { i32, i32}} %A, 1 175 %y1 = extractvalue { i32, i32} %y, 0 176 %y2 = extractvalue { i32, i32} %y, 1 177 178 %b = insertvalue {i64, {i32, i32}} undef, i64 %x, 0 179 %c1 = insertvalue {i32, i32} undef, i32 %y1, 0 180 %c2 = insertvalue {i32, i32} %c1, i32 %y2, 1 181 %c = insertvalue {i64, {i32, i32}} %b, {i32, i32} %c2, 1 182 183 ret { i64, { i32, i32}} %c 184 } 185 186 %struct.A = type { i32 } 187 %struct.B = type { %struct.A, i32 } 188 189 declare %struct.B* @testu() 190 191 define %struct.A* @test_upcast() { 192 ; CHECK-LABEL: test_upcast: 193 ; CHECK: ## %bb.0: ## %entry 194 ; CHECK-NEXT: jmp _testu ## TAILCALL 195 entry: 196 %A = tail call %struct.B* @testu() 197 %x = getelementptr inbounds %struct.B, %struct.B* %A, i32 0, i32 0 198 ret %struct.A* %x 199 } 200 201 ; PR13006 202 define { i64, i64 } @crash(i8* %this) { 203 ; CHECK-LABEL: crash: 204 ; CHECK: ## %bb.0: ## %entry 205 ; CHECK-NEXT: jmp _testp ## TAILCALL 206 entry: 207 %c = tail call { i64, i64 } @testp() 208 %mrv7 = insertvalue { i64, i64 } %c, i64 undef, 1 209 ret { i64, i64 } %mrv7 210 } 211 212 %struct.funcs = type { i32 (i8*, i32*, i32)*, i32 (i8*)*, i32 (i8*)*, i32 (i8*, i32)*, i32 } 213 214 @func_table = external global [0 x %struct.funcs] 215 216 ; Check that we can fold an indexed load into a tail call instruction. 217 define void @fold_indexed_load(i8* %mbstr, i64 %idxprom) nounwind uwtable ssp { 218 ; CHECK-LABEL: fold_indexed_load: 219 ; CHECK: ## %bb.0: ## %entry 220 ; CHECK-NEXT: leaq (%rsi,%rsi,4), %rax 221 ; CHECK-NEXT: movq _func_table@{{.*}}(%rip), %rcx 222 ; CHECK-NEXT: jmpq *16(%rcx,%rax,8) ## TAILCALL 223 entry: 224 %dsplen = getelementptr inbounds [0 x %struct.funcs], [0 x %struct.funcs]* @func_table, i64 0, i64 %idxprom, i32 2 225 %x1 = load i32 (i8*)*, i32 (i8*)** %dsplen, align 8 226 %call = tail call i32 %x1(i8* %mbstr) nounwind 227 ret void 228 } 229 230 @funcs = external constant [0 x i32 (i8*, ...)*] 231 232 ; <rdar://problem/12282281> Fold an indexed load into the tail call instruction. 233 ; Calling a varargs function with 6 arguments requires 7 registers (%al is the 234 ; vector count for varargs functions). This leaves %r11 as the only available 235 ; scratch register. 236 ; 237 ; It is not possible to fold an indexed load into TCRETURNmi64 in that case. 238 ; 239 ; typedef int (*funcptr)(void*, ...); 240 ; extern const funcptr funcs[]; 241 ; int f(int n) { 242 ; return funcs[n](0, 0, 0, 0, 0, 0); 243 ; } 244 define i32 @rdar12282281(i32 %n) nounwind uwtable ssp { 245 ; CHECK-LABEL: rdar12282281: 246 ; CHECK: ## %bb.0: ## %entry 247 ; CHECK-NEXT: movslq %edi, %rax 248 ; CHECK-NEXT: movq _funcs@{{.*}}(%rip), %rcx 249 ; CHECK-NEXT: movq (%rcx,%rax,8), %r11 250 ; CHECK-NEXT: xorl %edi, %edi 251 ; CHECK-NEXT: xorl %esi, %esi 252 ; CHECK-NEXT: xorl %edx, %edx 253 ; CHECK-NEXT: xorl %ecx, %ecx 254 ; CHECK-NEXT: xorl %r8d, %r8d 255 ; CHECK-NEXT: xorl %r9d, %r9d 256 ; CHECK-NEXT: xorl %eax, %eax 257 ; CHECK-NEXT: jmpq *%r11 ## TAILCALL 258 entry: 259 %idxprom = sext i32 %n to i64 260 %arrayidx = getelementptr inbounds [0 x i32 (i8*, ...)*], [0 x i32 (i8*, ...)*]* @funcs, i64 0, i64 %idxprom 261 %0 = load i32 (i8*, ...)*, i32 (i8*, ...)** %arrayidx, align 8 262 %call = tail call i32 (i8*, ...) %0(i8* null, i32 0, i32 0, i32 0, i32 0, i32 0) nounwind 263 ret i32 %call 264 } 265 266 declare x86_fp80 @fp80_callee(x86_fp80) 267 268 define x86_fp80 @fp80_call(x86_fp80 %x) nounwind { 269 ; CHECK-LABEL: fp80_call: 270 ; CHECK: ## %bb.0: ## %entry 271 ; CHECK-NEXT: jmp _fp80_callee ## TAILCALL 272 entry: 273 %call = tail call x86_fp80 @fp80_callee(x86_fp80 %x) nounwind 274 ret x86_fp80 %call 275 } 276 277 declare double @trunc(double) nounwind readnone 278 279 ; rdar://12229511 - Don't tail call trunc here. 280 define x86_fp80 @trunc_fp80(x86_fp80 %x) nounwind { 281 ; CHECK-LABEL: trunc_fp80: 282 ; CHECK: ## %bb.0: ## %entry 283 ; CHECK-NEXT: subq $24, %rsp 284 ; CHECK-NEXT: fldt {{[0-9]+}}(%rsp) 285 ; CHECK-NEXT: fstpl {{[0-9]+}}(%rsp) 286 ; CHECK-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero 287 ; CHECK-NEXT: callq _trunc 288 ; CHECK-NEXT: movsd %xmm0, {{[0-9]+}}(%rsp) 289 ; CHECK-NEXT: fldl {{[0-9]+}}(%rsp) 290 ; CHECK-NEXT: addq $24, %rsp 291 ; CHECK-NEXT: retq 292 entry: 293 %conv = fptrunc x86_fp80 %x to double 294 %call = tail call double @trunc(double %conv) nounwind readnone 295 %conv1 = fpext double %call to x86_fp80 296 ret x86_fp80 %conv1 297 } 298