Skip to content

Commit 376312a

Browse files
authored
[Hexagon] Implement isUsedByReturnOnly (#167637)
Prior to this patch, libcalls inserted by the `SelectionDAG` legalizer could never be tailcalled. The eligibility of libcalls for tail calling is is partly determined by checking `TargetLowering::isInTailCallPosition` and comparing the return type of the libcall and the caller. `isInTailCallPosition` in turn calls `TargetLowering::isUsedByReturnOnly` (which always returns false if not implemented by the target).
1 parent 182c415 commit 376312a

File tree

10 files changed

+153
-110
lines changed

10 files changed

+153
-110
lines changed

llvm/lib/Target/Hexagon/HexagonISelLowering.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3958,3 +3958,41 @@ bool HexagonTargetLowering::isMaskAndCmp0FoldingBeneficial(
39583958
return false;
39593959
return Mask->getValue().isPowerOf2();
39603960
}
3961+
3962+
// Check if the result of the node is only used as a return value, as
3963+
// otherwise we can't perform a tail-call.
3964+
bool HexagonTargetLowering::isUsedByReturnOnly(SDNode *N,
3965+
SDValue &Chain) const {
3966+
if (N->getNumValues() != 1)
3967+
return false;
3968+
if (!N->hasNUsesOfValue(1, 0))
3969+
return false;
3970+
3971+
SDNode *Copy = *N->user_begin();
3972+
3973+
if (Copy->getOpcode() == ISD::BITCAST) {
3974+
return isUsedByReturnOnly(Copy, Chain);
3975+
}
3976+
3977+
if (Copy->getOpcode() != ISD::CopyToReg) {
3978+
return false;
3979+
}
3980+
3981+
// If the ISD::CopyToReg has a glue operand, we conservatively assume it
3982+
// isn't safe to perform a tail call.
3983+
if (Copy->getOperand(Copy->getNumOperands() - 1).getValueType() == MVT::Glue)
3984+
return false;
3985+
3986+
// The copy must be used by a HexagonISD::RET_GLUE, and nothing else.
3987+
bool HasRet = false;
3988+
for (SDNode *Node : Copy->users()) {
3989+
if (Node->getOpcode() != HexagonISD::RET_GLUE)
3990+
return false;
3991+
HasRet = true;
3992+
}
3993+
if (!HasRet)
3994+
return false;
3995+
3996+
Chain = Copy->getOperand(0);
3997+
return true;
3998+
}

llvm/lib/Target/Hexagon/HexagonISelLowering.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ class HexagonTargetLowering : public TargetLowering {
162162

163163
bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const override;
164164

165+
bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override;
166+
165167
/// Return true if an FMA operation is faster than a pair of mul and add
166168
/// instructions. fmuladd intrinsics will be expanded to FMAs when this
167169
/// method returns true (and FMAs are legal), otherwise fmuladd is

llvm/test/CodeGen/Hexagon/fast-math-libcalls.ll

Lines changed: 11 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,8 @@ define float @fast_sqrt_f32(float %x) {
99
; CHECK-LABEL: fast_sqrt_f32:
1010
; CHECK: .cfi_startproc
1111
; CHECK-NEXT: // %bb.0:
12-
; CHECK-NEXT: .cfi_def_cfa r30, 8
13-
; CHECK-NEXT: .cfi_offset r31, -4
14-
; CHECK-NEXT: .cfi_offset r30, -8
1512
; CHECK-NEXT: {
16-
; CHECK-NEXT: call __hexagon_fast2_sqrtf
17-
; CHECK-NEXT: allocframe(r29,#0):raw
18-
; CHECK-NEXT: }
19-
; CHECK-NEXT: {
20-
; CHECK-NEXT: r31:30 = dealloc_return(r30):raw
13+
; CHECK-NEXT: jump __hexagon_fast2_sqrtf
2114
; CHECK-NEXT: }
2215
%result = call nnan ninf nsz afn float @llvm.sqrt.f32(float %x)
2316
ret float %result
@@ -27,15 +20,8 @@ define double @fast_sqrt_f64(double %x) {
2720
; CHECK-LABEL: fast_sqrt_f64:
2821
; CHECK: .cfi_startproc
2922
; CHECK-NEXT: // %bb.0:
30-
; CHECK-NEXT: .cfi_def_cfa r30, 8
31-
; CHECK-NEXT: .cfi_offset r31, -4
32-
; CHECK-NEXT: .cfi_offset r30, -8
33-
; CHECK-NEXT: {
34-
; CHECK-NEXT: call __hexagon_fast2_sqrtdf2
35-
; CHECK-NEXT: allocframe(r29,#0):raw
36-
; CHECK-NEXT: }
3723
; CHECK-NEXT: {
38-
; CHECK-NEXT: r31:30 = dealloc_return(r30):raw
24+
; CHECK-NEXT: jump __hexagon_fast2_sqrtdf2
3925
; CHECK-NEXT: }
4026
%result = call nnan ninf nsz afn double @llvm.sqrt.f64(double %x)
4127
ret double %result
@@ -61,15 +47,8 @@ define double @fast_add_f64(double %x, double %y) {
6147
; CHECK-LABEL: fast_add_f64:
6248
; CHECK: .cfi_startproc
6349
; CHECK-NEXT: // %bb.0:
64-
; CHECK-NEXT: .cfi_def_cfa r30, 8
65-
; CHECK-NEXT: .cfi_offset r31, -4
66-
; CHECK-NEXT: .cfi_offset r30, -8
67-
; CHECK-NEXT: {
68-
; CHECK-NEXT: call __hexagon_fast_adddf3
69-
; CHECK-NEXT: allocframe(r29,#0):raw
70-
; CHECK-NEXT: }
7150
; CHECK-NEXT: {
72-
; CHECK-NEXT: r31:30 = dealloc_return(r30):raw
51+
; CHECK-NEXT: jump __hexagon_fast_adddf3
7352
; CHECK-NEXT: }
7453
%result = fadd nnan ninf nsz afn double %x, %y
7554
ret double %result
@@ -95,15 +74,8 @@ define double @fast_sub_f64(double %x, double %y) {
9574
; CHECK-LABEL: fast_sub_f64:
9675
; CHECK: .cfi_startproc
9776
; CHECK-NEXT: // %bb.0:
98-
; CHECK-NEXT: .cfi_def_cfa r30, 8
99-
; CHECK-NEXT: .cfi_offset r31, -4
100-
; CHECK-NEXT: .cfi_offset r30, -8
10177
; CHECK-NEXT: {
102-
; CHECK-NEXT: call __hexagon_fast_subdf3
103-
; CHECK-NEXT: allocframe(r29,#0):raw
104-
; CHECK-NEXT: }
105-
; CHECK-NEXT: {
106-
; CHECK-NEXT: r31:30 = dealloc_return(r30):raw
78+
; CHECK-NEXT: jump __hexagon_fast_subdf3
10779
; CHECK-NEXT: }
10880
%result = fsub nnan ninf nsz afn double %x, %y
10981
ret double %result
@@ -129,15 +101,8 @@ define double @fast_mul_f64(double %x, double %y) {
129101
; CHECK-LABEL: fast_mul_f64:
130102
; CHECK: .cfi_startproc
131103
; CHECK-NEXT: // %bb.0:
132-
; CHECK-NEXT: .cfi_def_cfa r30, 8
133-
; CHECK-NEXT: .cfi_offset r31, -4
134-
; CHECK-NEXT: .cfi_offset r30, -8
135104
; CHECK-NEXT: {
136-
; CHECK-NEXT: call __hexagon_fast_muldf3
137-
; CHECK-NEXT: allocframe(r29,#0):raw
138-
; CHECK-NEXT: }
139-
; CHECK-NEXT: {
140-
; CHECK-NEXT: r31:30 = dealloc_return(r30):raw
105+
; CHECK-NEXT: jump __hexagon_fast_muldf3
141106
; CHECK-NEXT: }
142107
%result = fmul nnan ninf nsz afn double %x, %y
143108
ret double %result
@@ -194,15 +159,8 @@ define double @fast_div_f64(double %x, double %y) {
194159
; CHECK-LABEL: fast_div_f64:
195160
; CHECK: .cfi_startproc
196161
; CHECK-NEXT: // %bb.0:
197-
; CHECK-NEXT: .cfi_def_cfa r30, 8
198-
; CHECK-NEXT: .cfi_offset r31, -4
199-
; CHECK-NEXT: .cfi_offset r30, -8
200-
; CHECK-NEXT: {
201-
; CHECK-NEXT: call __hexagon_fast_divdf3
202-
; CHECK-NEXT: allocframe(r29,#0):raw
203-
; CHECK-NEXT: }
204162
; CHECK-NEXT: {
205-
; CHECK-NEXT: r31:30 = dealloc_return(r30):raw
163+
; CHECK-NEXT: jump __hexagon_fast_divdf3
206164
; CHECK-NEXT: }
207165
%result = fdiv nnan ninf nsz afn double %x, %y
208166
ret double %result
@@ -217,15 +175,8 @@ define float @sqrt_f32__afn(float %x) {
217175
; CHECK-LABEL: sqrt_f32__afn:
218176
; CHECK: .cfi_startproc
219177
; CHECK-NEXT: // %bb.0:
220-
; CHECK-NEXT: .cfi_def_cfa r30, 8
221-
; CHECK-NEXT: .cfi_offset r31, -4
222-
; CHECK-NEXT: .cfi_offset r30, -8
223-
; CHECK-NEXT: {
224-
; CHECK-NEXT: call __hexagon_sqrtf
225-
; CHECK-NEXT: allocframe(r29,#0):raw
226-
; CHECK-NEXT: }
227178
; CHECK-NEXT: {
228-
; CHECK-NEXT: r31:30 = dealloc_return(r30):raw
179+
; CHECK-NEXT: jump __hexagon_sqrtf
229180
; CHECK-NEXT: }
230181
%result = call afn float @llvm.sqrt.f32(float %x)
231182
ret float %result
@@ -235,15 +186,8 @@ define float @sqrt_f32__afn_ninf(float %x) {
235186
; CHECK-LABEL: sqrt_f32__afn_ninf:
236187
; CHECK: .cfi_startproc
237188
; CHECK-NEXT: // %bb.0:
238-
; CHECK-NEXT: .cfi_def_cfa r30, 8
239-
; CHECK-NEXT: .cfi_offset r31, -4
240-
; CHECK-NEXT: .cfi_offset r30, -8
241189
; CHECK-NEXT: {
242-
; CHECK-NEXT: call __hexagon_sqrtf
243-
; CHECK-NEXT: allocframe(r29,#0):raw
244-
; CHECK-NEXT: }
245-
; CHECK-NEXT: {
246-
; CHECK-NEXT: r31:30 = dealloc_return(r30):raw
190+
; CHECK-NEXT: jump __hexagon_sqrtf
247191
; CHECK-NEXT: }
248192
%result = call afn ninf float @llvm.sqrt.f32(float %x)
249193
ret float %result
@@ -253,15 +197,8 @@ define float @sqrt_f32__afn_nnan(float %x) {
253197
; CHECK-LABEL: sqrt_f32__afn_nnan:
254198
; CHECK: .cfi_startproc
255199
; CHECK-NEXT: // %bb.0:
256-
; CHECK-NEXT: .cfi_def_cfa r30, 8
257-
; CHECK-NEXT: .cfi_offset r31, -4
258-
; CHECK-NEXT: .cfi_offset r30, -8
259200
; CHECK-NEXT: {
260-
; CHECK-NEXT: call __hexagon_sqrtf
261-
; CHECK-NEXT: allocframe(r29,#0):raw
262-
; CHECK-NEXT: }
263-
; CHECK-NEXT: {
264-
; CHECK-NEXT: r31:30 = dealloc_return(r30):raw
201+
; CHECK-NEXT: jump __hexagon_sqrtf
265202
; CHECK-NEXT: }
266203
%result = call afn nnan float @llvm.sqrt.f32(float %x)
267204
ret float %result
@@ -271,15 +208,8 @@ define float @sqrt_f32__nnan(float %x) {
271208
; CHECK-LABEL: sqrt_f32__nnan:
272209
; CHECK: .cfi_startproc
273210
; CHECK-NEXT: // %bb.0:
274-
; CHECK-NEXT: .cfi_def_cfa r30, 8
275-
; CHECK-NEXT: .cfi_offset r31, -4
276-
; CHECK-NEXT: .cfi_offset r30, -8
277-
; CHECK-NEXT: {
278-
; CHECK-NEXT: call __hexagon_sqrtf
279-
; CHECK-NEXT: allocframe(r29,#0):raw
280-
; CHECK-NEXT: }
281211
; CHECK-NEXT: {
282-
; CHECK-NEXT: r31:30 = dealloc_return(r30):raw
212+
; CHECK-NEXT: jump __hexagon_sqrtf
283213
; CHECK-NEXT: }
284214
%result = call nnan float @llvm.sqrt.f32(float %x)
285215
ret float %result
@@ -289,15 +219,8 @@ define float @sqrt_f32_nnan_ninf_afn(float %x) {
289219
; CHECK-LABEL: sqrt_f32_nnan_ninf_afn:
290220
; CHECK: .cfi_startproc
291221
; CHECK-NEXT: // %bb.0:
292-
; CHECK-NEXT: .cfi_def_cfa r30, 8
293-
; CHECK-NEXT: .cfi_offset r31, -4
294-
; CHECK-NEXT: .cfi_offset r30, -8
295-
; CHECK-NEXT: {
296-
; CHECK-NEXT: call __hexagon_sqrtf
297-
; CHECK-NEXT: allocframe(r29,#0):raw
298-
; CHECK-NEXT: }
299222
; CHECK-NEXT: {
300-
; CHECK-NEXT: r31:30 = dealloc_return(r30):raw
223+
; CHECK-NEXT: jump __hexagon_sqrtf
301224
; CHECK-NEXT: }
302225
%result = call nnan ninf afn float @llvm.sqrt.f32(float %x)
303226
ret float %result

llvm/test/CodeGen/Hexagon/fminmax-v67.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33

44
; CHECK-LABEL: t1
5-
; CHECK: call fmax
5+
; CHECK: jump fmax
66

77
define dso_local double @t1(double %a, double %b) local_unnamed_addr {
88
entry:
@@ -11,7 +11,7 @@ entry:
1111
}
1212

1313
; CHECK-LABEL: t2
14-
; CHECK: call fmin
14+
; CHECK: jump fmin
1515

1616
define dso_local double @t2(double %a, double %b) local_unnamed_addr {
1717
entry:
@@ -20,7 +20,7 @@ entry:
2020
}
2121

2222
; CHECK-LABEL: t3
23-
; CHECK: call fmaxf
23+
; CHECK: jump fmaxf
2424

2525
define dso_local float @t3(float %a, float %b) local_unnamed_addr {
2626
entry:
@@ -29,7 +29,7 @@ entry:
2929
}
3030

3131
; CHECK-LABEL: t4
32-
; CHECK: call fminf
32+
; CHECK: jump fminf
3333

3434
define dso_local float @t4(float %a, float %b) local_unnamed_addr {
3535
entry:

llvm/test/CodeGen/Hexagon/fminmax.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,31 @@ target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i
44
target triple = "hexagon"
55

66
; CHECK-LABEL: cfminf
7-
; CHECK: call fminf
7+
; CHECK: jump fminf
88
define float @cfminf(float %x, float %y) #0 {
99
entry:
1010
%call = tail call float @fminf(float %x, float %y) #1
1111
ret float %call
1212
}
1313

1414
; CHECK-LABEL: cfmaxf
15-
; CHECK: call fmaxf
15+
; CHECK: jump fmaxf
1616
define float @cfmaxf(float %x, float %y) #0 {
1717
entry:
1818
%call = tail call float @fmaxf(float %x, float %y) #1
1919
ret float %call
2020
}
2121

2222
; CHECK-LABEL: minnum
23-
; CHECK: call fminf
23+
; CHECK: jump fminf
2424
define float @minnum(float %x, float %y) #0 {
2525
entry:
2626
%call = tail call float @llvm.minnum.f32(float %x, float %y) #1
2727
ret float %call
2828
}
2929

3030
; CHECK-LABEL: maxnum
31-
; CHECK: call fmaxf
31+
; CHECK: jump fmaxf
3232
define float @maxnum(float %x, float %y) #0 {
3333
entry:
3434
%call = tail call float @llvm.maxnum.f32(float %x, float %y) #1

llvm/test/CodeGen/Hexagon/fp16.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
; Validate that we generate correct lib calls to convert fp16
1414

1515
;CHECK-LABEL: @test1
16-
;CHECK: call __extendhfsf2
16+
;CHECK: jump __extendhfsf2
1717
;CHECK: r0 = memuh
1818
define dso_local float @test1(ptr nocapture readonly %a) local_unnamed_addr #0 {
1919
entry:

llvm/test/CodeGen/Hexagon/inline-division-space.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ entry:
1414
; Function Attrs: optsize
1515
define dso_local float @testFloat(float %a, float %b) local_unnamed_addr #0 {
1616
entry:
17-
;CHECK: call __hexagon_divsf3
17+
;CHECK: jump __hexagon_divsf3
1818
%div = fdiv float %a, %b
1919
ret float %div
2020
}
2121

2222
; Function Attrs: optsize
2323
define dso_local double @testDouble(double %a, double %b) local_unnamed_addr #0 {
2424
entry:
25-
;CHECK: call __hexagon_divdf3
25+
;CHECK: jump __hexagon_divdf3
2626
%div = fdiv double %a, %b
2727
ret double %div
2828
}

llvm/test/CodeGen/Hexagon/inline-division.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ entry:
2323

2424
define dso_local double @testDouble(double %a, double %b) local_unnamed_addr {
2525
entry:
26-
;CHECK: call __hexagon_divdf3
26+
;CHECK: jump __hexagon_divdf3
2727
%div = fdiv double %a, %b
2828
ret double %div
2929
}

0 commit comments

Comments
 (0)