blob: ecc253ba587e93237a3690ecaa11f74e95eee5ba [file] [log] [blame]
Evan Cheng446ff282012-09-25 05:32:34 +00001; RUN: llc -mtriple=x86_64-apple-macosx -mcpu=core2 < %s | FileCheck %s
Chris Lattner22afea72012-06-01 05:03:31 +00002
3declare i64 @testi()
4
5define i64 @test_trivial() {
6 %A = tail call i64 @testi()
7 ret i64 %A
8}
9; CHECK: test_trivial:
10; CHECK: jmp _testi ## TAILCALL
11
12
13define i64 @test_noop_bitcast() {
14 %A = tail call i64 @testi()
15 %B = bitcast i64 %A to i64
16 ret i64 %B
17}
18; CHECK: test_noop_bitcast:
19; CHECK: jmp _testi ## TAILCALL
Chris Lattner182fe3e2012-06-01 05:16:33 +000020
21
22; Tail call shouldn't be blocked by no-op inttoptr.
23define i8* @test_inttoptr() {
24 %A = tail call i64 @testi()
25 %B = inttoptr i64 %A to i8*
26 ret i8* %B
27}
28
29; CHECK: test_inttoptr:
30; CHECK: jmp _testi ## TAILCALL
31
32
33declare <4 x float> @testv()
34
35define <4 x i32> @test_vectorbitcast() {
36 %A = tail call <4 x float> @testv()
37 %B = bitcast <4 x float> %A to <4 x i32>
38 ret <4 x i32> %B
39}
40; CHECK: test_vectorbitcast:
41; CHECK: jmp _testv ## TAILCALL
Chris Lattner466076b2012-06-01 05:29:15 +000042
43
44declare { i64, i64 } @testp()
45
46define {i64, i64} @test_pair_trivial() {
47 %A = tail call { i64, i64} @testp()
48 ret { i64, i64} %A
49}
50; CHECK: test_pair_trivial:
51; CHECK: jmp _testp ## TAILCALL
52
53
54
55define {i64, i64} @test_pair_trivial_extract() {
56 %A = tail call { i64, i64} @testp()
57 %x = extractvalue { i64, i64} %A, 0
58 %y = extractvalue { i64, i64} %A, 1
59
60 %b = insertvalue {i64, i64} undef, i64 %x, 0
61 %c = insertvalue {i64, i64} %b, i64 %y, 1
62
63 ret { i64, i64} %c
64}
65
66; CHECK: test_pair_trivial_extract:
67; CHECK: jmp _testp ## TAILCALL
68
69define {i8*, i64} @test_pair_conv_extract() {
70 %A = tail call { i64, i64} @testp()
71 %x = extractvalue { i64, i64} %A, 0
72 %y = extractvalue { i64, i64} %A, 1
73
74 %x1 = inttoptr i64 %x to i8*
75
76 %b = insertvalue {i8*, i64} undef, i8* %x1, 0
77 %c = insertvalue {i8*, i64} %b, i64 %y, 1
78
79 ret { i8*, i64} %c
80}
81
82; CHECK: test_pair_conv_extract:
83; CHECK: jmp _testp ## TAILCALL
84
85
86
Chris Lattnerb1359892012-06-01 18:19:46 +000087; PR13006
88define { i64, i64 } @crash(i8* %this) {
89 %c = tail call { i64, i64 } @testp()
90 %mrv7 = insertvalue { i64, i64 } %c, i64 undef, 1
91 ret { i64, i64 } %mrv7
92}
93
Jakob Stoklund Olesen3cf3ffc2012-09-13 18:31:27 +000094; Check that we can fold an indexed load into a tail call instruction.
95; CHECK: fold_indexed_load
96; CHECK: leaq (%rsi,%rsi,4), %[[RAX:r..]]
Jakob Stoklund Olesen32a56fa2012-09-13 19:47:45 +000097; CHECK: jmpq *16(%{{r..}},%[[RAX]],8) # TAILCALL
Jakob Stoklund Olesen3cf3ffc2012-09-13 18:31:27 +000098%struct.funcs = type { i32 (i8*, i32*, i32)*, i32 (i8*)*, i32 (i8*)*, i32 (i8*, i32)*, i32 }
99@func_table = external global [0 x %struct.funcs]
100define void @fold_indexed_load(i8* %mbstr, i64 %idxprom) nounwind uwtable ssp {
101entry:
102 %dsplen = getelementptr inbounds [0 x %struct.funcs]* @func_table, i64 0, i64 %idxprom, i32 2
103 %x1 = load i32 (i8*)** %dsplen, align 8
104 %call = tail call i32 %x1(i8* %mbstr) nounwind
105 ret void
106}
Chris Lattner466076b2012-06-01 05:29:15 +0000107
Jakob Stoklund Olesen3cf3ffc2012-09-13 18:31:27 +0000108; <rdar://problem/12282281> Fold an indexed load into the tail call instruction.
109; Calling a varargs function with 6 arguments requires 7 registers (%al is the
110; vector count for varargs functions). This leaves %r11 as the only available
111; scratch register.
112;
113; It is not possible to fold an indexed load into TCRETURNmi64 in that case.
114;
115; typedef int (*funcptr)(void*, ...);
116; extern const funcptr funcs[];
117; int f(int n) {
118; return funcs[n](0, 0, 0, 0, 0, 0);
119; }
120;
121; CHECK: rdar12282281
122; CHECK: jmpq *%r11 # TAILCALL
123@funcs = external constant [0 x i32 (i8*, ...)*]
124
125define i32 @rdar12282281(i32 %n) nounwind uwtable ssp {
126entry:
127 %idxprom = sext i32 %n to i64
128 %arrayidx = getelementptr inbounds [0 x i32 (i8*, ...)*]* @funcs, i64 0, i64 %idxprom
129 %0 = load i32 (i8*, ...)** %arrayidx, align 8
130 %call = tail call i32 (i8*, ...)* %0(i8* null, i32 0, i32 0, i32 0, i32 0, i32 0) nounwind
131 ret i32 %call
132}
Evan Cheng446ff282012-09-25 05:32:34 +0000133
134define x86_fp80 @fp80_call(x86_fp80 %x) nounwind {
135entry:
136; CHECK: fp80_call:
137; CHECK: jmp _fp80_callee
138 %call = tail call x86_fp80 @fp80_callee(x86_fp80 %x) nounwind
139 ret x86_fp80 %call
140}
141
142declare x86_fp80 @fp80_callee(x86_fp80)
143
144; rdar://12229511
145define x86_fp80 @trunc_fp80(x86_fp80 %x) nounwind {
146entry:
147; CHECK: trunc_fp80
148; CHECK: callq _trunc
149; CHECK-NOT: jmp _trunc
150; CHECK: ret
151 %conv = fptrunc x86_fp80 %x to double
152 %call = tail call double @trunc(double %conv) nounwind readnone
153 %conv1 = fpext double %call to x86_fp80
154 ret x86_fp80 %conv1
155}
156
157declare double @trunc(double) nounwind readnone