xref: /aosp_15_r20/external/llvm/test/CodeGen/ARM/call-tc.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=armv6-apple-ios5.0 -mattr=+vfp2 -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=CHECKV6
2*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=thumbv7-apple-ios5.0 -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=CHECKT2D
3*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=armv6-linux-gnueabi -relocation-model=pic -mattr=+vfp2 -arm-atomic-cfg-tidy=0 \
4*9880d681SAndroid Build Coastguard Worker; RUN:    | FileCheck %s -check-prefix=CHECKELF
5*9880d681SAndroid Build Coastguard Worker
6*9880d681SAndroid Build Coastguard Worker; Enable tailcall optimization for iOS 5.0
7*9880d681SAndroid Build Coastguard Worker; rdar://9120031
8*9880d681SAndroid Build Coastguard Worker
9*9880d681SAndroid Build Coastguard Worker@t = weak global i32 ()* null           ; <i32 ()**> [#uses=1]
10*9880d681SAndroid Build Coastguard Worker
11*9880d681SAndroid Build Coastguard Workerdeclare void @g(i32, i32, i32, i32)
12*9880d681SAndroid Build Coastguard Worker
13*9880d681SAndroid Build Coastguard Workerdefine void @t1() {
14*9880d681SAndroid Build Coastguard Worker; CHECKELF-LABEL: t1:
15*9880d681SAndroid Build Coastguard Worker; CHECKELF: bl g
16*9880d681SAndroid Build Coastguard Worker        call void @g( i32 1, i32 2, i32 3, i32 4 )
17*9880d681SAndroid Build Coastguard Worker        ret void
18*9880d681SAndroid Build Coastguard Worker}
19*9880d681SAndroid Build Coastguard Worker
20*9880d681SAndroid Build Coastguard Workerdefine void @t2() {
21*9880d681SAndroid Build Coastguard Worker; CHECKV6-LABEL: t2:
22*9880d681SAndroid Build Coastguard Worker; CHECKV6: bx r0
23*9880d681SAndroid Build Coastguard Worker; CHECKT2D-LABEL: t2:
24*9880d681SAndroid Build Coastguard Worker; CHECKT2D: ldr
25*9880d681SAndroid Build Coastguard Worker; CHECKT2D-NEXT: ldr
26*9880d681SAndroid Build Coastguard Worker; CHECKT2D-NEXT: bx r0
27*9880d681SAndroid Build Coastguard Worker        %tmp = load i32 ()*, i32 ()** @t         ; <i32 ()*> [#uses=1]
28*9880d681SAndroid Build Coastguard Worker        %tmp.upgrd.2 = tail call i32 %tmp( )            ; <i32> [#uses=0]
29*9880d681SAndroid Build Coastguard Worker        ret void
30*9880d681SAndroid Build Coastguard Worker}
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard Workerdefine void @t3() {
33*9880d681SAndroid Build Coastguard Worker; CHECKV6-LABEL: t3:
34*9880d681SAndroid Build Coastguard Worker; CHECKV6: b _t2
35*9880d681SAndroid Build Coastguard Worker; CHECKELF-LABEL: t3:
36*9880d681SAndroid Build Coastguard Worker; CHECKELF: b t2
37*9880d681SAndroid Build Coastguard Worker; CHECKT2D-LABEL: t3:
38*9880d681SAndroid Build Coastguard Worker; CHECKT2D: b.w _t2
39*9880d681SAndroid Build Coastguard Worker
40*9880d681SAndroid Build Coastguard Worker        tail call void @t2( )            ; <i32> [#uses=0]
41*9880d681SAndroid Build Coastguard Worker        ret void
42*9880d681SAndroid Build Coastguard Worker}
43*9880d681SAndroid Build Coastguard Worker
44*9880d681SAndroid Build Coastguard Worker; Sibcall optimization of expanded libcalls. rdar://8707777
45*9880d681SAndroid Build Coastguard Workerdefine double @t4(double %a) nounwind readonly ssp {
46*9880d681SAndroid Build Coastguard Workerentry:
47*9880d681SAndroid Build Coastguard Worker; CHECKV6-LABEL: t4:
48*9880d681SAndroid Build Coastguard Worker; CHECKV6: b _sin
49*9880d681SAndroid Build Coastguard Worker; CHECKELF-LABEL: t4:
50*9880d681SAndroid Build Coastguard Worker; CHECKELF: b sin
51*9880d681SAndroid Build Coastguard Worker  %0 = tail call double @sin(double %a) nounwind readonly ; <double> [#uses=1]
52*9880d681SAndroid Build Coastguard Worker  ret double %0
53*9880d681SAndroid Build Coastguard Worker}
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Workerdefine float @t5(float %a) nounwind readonly ssp {
56*9880d681SAndroid Build Coastguard Workerentry:
57*9880d681SAndroid Build Coastguard Worker; CHECKV6-LABEL: t5:
58*9880d681SAndroid Build Coastguard Worker; CHECKV6: b _sinf
59*9880d681SAndroid Build Coastguard Worker; CHECKELF-LABEL: t5:
60*9880d681SAndroid Build Coastguard Worker; CHECKELF: b sinf
61*9880d681SAndroid Build Coastguard Worker  %0 = tail call float @sinf(float %a) nounwind readonly ; <float> [#uses=1]
62*9880d681SAndroid Build Coastguard Worker  ret float %0
63*9880d681SAndroid Build Coastguard Worker}
64*9880d681SAndroid Build Coastguard Worker
65*9880d681SAndroid Build Coastguard Workerdeclare float @sinf(float) nounwind readonly
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Workerdeclare double @sin(double) nounwind readonly
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard Workerdefine i32 @t6(i32 %a, i32 %b) nounwind readnone {
70*9880d681SAndroid Build Coastguard Workerentry:
71*9880d681SAndroid Build Coastguard Worker; CHECKV6-LABEL: t6:
72*9880d681SAndroid Build Coastguard Worker; CHECKV6: b ___divsi3
73*9880d681SAndroid Build Coastguard Worker; CHECKELF-LABEL: t6:
74*9880d681SAndroid Build Coastguard Worker; CHECKELF: b __aeabi_idiv
75*9880d681SAndroid Build Coastguard Worker  %0 = sdiv i32 %a, %b
76*9880d681SAndroid Build Coastguard Worker  ret i32 %0
77*9880d681SAndroid Build Coastguard Worker}
78*9880d681SAndroid Build Coastguard Worker
79*9880d681SAndroid Build Coastguard Worker; Make sure the tail call instruction isn't deleted
80*9880d681SAndroid Build Coastguard Worker; rdar://8309338
81*9880d681SAndroid Build Coastguard Workerdeclare void @foo() nounwind
82*9880d681SAndroid Build Coastguard Worker
83*9880d681SAndroid Build Coastguard Workerdefine void @t7() nounwind {
84*9880d681SAndroid Build Coastguard Workerentry:
85*9880d681SAndroid Build Coastguard Worker; CHECKT2D-LABEL: t7:
86*9880d681SAndroid Build Coastguard Worker; CHECKT2D: it ne
87*9880d681SAndroid Build Coastguard Worker; CHECKT2D-NEXT: bne.w _foo
88*9880d681SAndroid Build Coastguard Worker; CHECKT2D-NEXT: push
89*9880d681SAndroid Build Coastguard Worker; CHECKT2D-NEXT: mov r7, sp
90*9880d681SAndroid Build Coastguard Worker; CHECKT2D-NEXT: bl _foo
91*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %bb, label %bb1.lr.ph
92*9880d681SAndroid Build Coastguard Worker
93*9880d681SAndroid Build Coastguard Workerbb1.lr.ph:
94*9880d681SAndroid Build Coastguard Worker  tail call void @foo() nounwind
95*9880d681SAndroid Build Coastguard Worker  unreachable
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Workerbb:
98*9880d681SAndroid Build Coastguard Worker  tail call void @foo() nounwind
99*9880d681SAndroid Build Coastguard Worker  ret void
100*9880d681SAndroid Build Coastguard Worker}
101*9880d681SAndroid Build Coastguard Worker
102*9880d681SAndroid Build Coastguard Worker; Make sure codegenprep is duplicating ret instructions to enable tail calls.
103*9880d681SAndroid Build Coastguard Worker; rdar://11140249
104*9880d681SAndroid Build Coastguard Workerdefine i32 @t8(i32 %x) nounwind ssp {
105*9880d681SAndroid Build Coastguard Workerentry:
106*9880d681SAndroid Build Coastguard Worker; CHECKT2D-LABEL: t8:
107*9880d681SAndroid Build Coastguard Worker; CHECKT2D-NOT: push
108*9880d681SAndroid Build Coastguard Worker  %and = and i32 %x, 1
109*9880d681SAndroid Build Coastguard Worker  %tobool = icmp eq i32 %and, 0
110*9880d681SAndroid Build Coastguard Worker  br i1 %tobool, label %if.end, label %if.then
111*9880d681SAndroid Build Coastguard Worker
112*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %entry
113*9880d681SAndroid Build Coastguard Worker; CHECKT2D: bne.w _a
114*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 @a(i32 %x) nounwind
115*9880d681SAndroid Build Coastguard Worker  br label %return
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Workerif.end:                                           ; preds = %entry
118*9880d681SAndroid Build Coastguard Worker  %and1 = and i32 %x, 2
119*9880d681SAndroid Build Coastguard Worker  %tobool2 = icmp eq i32 %and1, 0
120*9880d681SAndroid Build Coastguard Worker  br i1 %tobool2, label %if.end5, label %if.then3
121*9880d681SAndroid Build Coastguard Worker
122*9880d681SAndroid Build Coastguard Workerif.then3:                                         ; preds = %if.end
123*9880d681SAndroid Build Coastguard Worker; CHECKT2D: bne.w _b
124*9880d681SAndroid Build Coastguard Worker  %call4 = tail call i32 @b(i32 %x) nounwind
125*9880d681SAndroid Build Coastguard Worker  br label %return
126*9880d681SAndroid Build Coastguard Worker
127*9880d681SAndroid Build Coastguard Workerif.end5:                                          ; preds = %if.end
128*9880d681SAndroid Build Coastguard Worker; CHECKT2D: b.w _c
129*9880d681SAndroid Build Coastguard Worker  %call6 = tail call i32 @c(i32 %x) nounwind
130*9880d681SAndroid Build Coastguard Worker  br label %return
131*9880d681SAndroid Build Coastguard Worker
132*9880d681SAndroid Build Coastguard Workerreturn:                                           ; preds = %if.end5, %if.then3, %if.then
133*9880d681SAndroid Build Coastguard Worker  %retval.0 = phi i32 [ %call, %if.then ], [ %call4, %if.then3 ], [ %call6, %if.end5 ]
134*9880d681SAndroid Build Coastguard Worker  ret i32 %retval.0
135*9880d681SAndroid Build Coastguard Worker}
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard Workerdeclare i32 @a(i32)
138*9880d681SAndroid Build Coastguard Worker
139*9880d681SAndroid Build Coastguard Workerdeclare i32 @b(i32)
140*9880d681SAndroid Build Coastguard Worker
141*9880d681SAndroid Build Coastguard Workerdeclare i32 @c(i32)
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Worker; PR12419
144*9880d681SAndroid Build Coastguard Worker; rdar://11195178
145*9880d681SAndroid Build Coastguard Worker; Use the correct input chain for the tailcall node or else the call to
146*9880d681SAndroid Build Coastguard Worker; _ZN9MutexLockD1Ev would be lost.
147*9880d681SAndroid Build Coastguard Worker%class.MutexLock = type { i8 }
148*9880d681SAndroid Build Coastguard Worker
149*9880d681SAndroid Build Coastguard Worker@x = external global i32, align 4
150*9880d681SAndroid Build Coastguard Worker
151*9880d681SAndroid Build Coastguard Workerdefine i32 @t9() nounwind {
152*9880d681SAndroid Build Coastguard Worker; CHECKT2D-LABEL: t9:
153*9880d681SAndroid Build Coastguard Worker; CHECKT2D: bl __ZN9MutexLockC1Ev
154*9880d681SAndroid Build Coastguard Worker; CHECKT2D: bl __ZN9MutexLockD1Ev
155*9880d681SAndroid Build Coastguard Worker; CHECKT2D: b.w ___divsi3
156*9880d681SAndroid Build Coastguard Worker  %lock = alloca %class.MutexLock, align 1
157*9880d681SAndroid Build Coastguard Worker  %1 = call %class.MutexLock* @_ZN9MutexLockC1Ev(%class.MutexLock* %lock)
158*9880d681SAndroid Build Coastguard Worker  %2 = load i32, i32* @x, align 4
159*9880d681SAndroid Build Coastguard Worker  %3 = sdiv i32 1000, %2
160*9880d681SAndroid Build Coastguard Worker  %4 = call %class.MutexLock* @_ZN9MutexLockD1Ev(%class.MutexLock* %lock)
161*9880d681SAndroid Build Coastguard Worker  ret i32 %3
162*9880d681SAndroid Build Coastguard Worker}
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Workerdeclare %class.MutexLock* @_ZN9MutexLockC1Ev(%class.MutexLock*) unnamed_addr nounwind align 2
165*9880d681SAndroid Build Coastguard Worker
166*9880d681SAndroid Build Coastguard Workerdeclare %class.MutexLock* @_ZN9MutexLockD1Ev(%class.MutexLock*) unnamed_addr nounwind align 2
167*9880d681SAndroid Build Coastguard Worker
168*9880d681SAndroid Build Coastguard Worker; rdar://13827621
169*9880d681SAndroid Build Coastguard Worker; Correctly preserve the input chain for the tailcall node in the bitcast case,
170*9880d681SAndroid Build Coastguard Worker; otherwise the call to floorf is lost.
171*9880d681SAndroid Build Coastguard Workerdefine float @libcall_tc_test2(float* nocapture %a, float %b) {
172*9880d681SAndroid Build Coastguard Worker; CHECKT2D-LABEL: libcall_tc_test2:
173*9880d681SAndroid Build Coastguard Worker; CHECKT2D: bl _floorf
174*9880d681SAndroid Build Coastguard Worker; CHECKT2D: b.w _truncf
175*9880d681SAndroid Build Coastguard Worker  %1 = load float, float* %a, align 4
176*9880d681SAndroid Build Coastguard Worker  %call = tail call float @floorf(float %1)
177*9880d681SAndroid Build Coastguard Worker  store float %call, float* %a, align 4
178*9880d681SAndroid Build Coastguard Worker  %call1 = tail call float @truncf(float %b)
179*9880d681SAndroid Build Coastguard Worker  ret float %call1
180*9880d681SAndroid Build Coastguard Worker}
181*9880d681SAndroid Build Coastguard Worker
182*9880d681SAndroid Build Coastguard Workerdeclare float @floorf(float) readnone
183*9880d681SAndroid Build Coastguard Workerdeclare float @truncf(float) readnone
184