Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3958,3 +3958,41 @@ bool HexagonTargetLowering::isMaskAndCmp0FoldingBeneficial(
return false;
return Mask->getValue().isPowerOf2();
}

// Check if the result of the node is only used as a return value, as
// otherwise we can't perform a tail-call.
bool HexagonTargetLowering::isUsedByReturnOnly(SDNode *N,
SDValue &Chain) const {
if (N->getNumValues() != 1)
return false;
if (!N->hasNUsesOfValue(1, 0))
return false;

SDNode *Copy = *N->user_begin();

if (Copy->getOpcode() == ISD::BITCAST) {
return isUsedByReturnOnly(Copy, Chain);
}

if (Copy->getOpcode() != ISD::CopyToReg) {
return false;
}

// If the ISD::CopyToReg has a glue operand, we conservatively assume it
// isn't safe to perform a tail call.
if (Copy->getOperand(Copy->getNumOperands() - 1).getValueType() == MVT::Glue)
return false;

// The copy must be used by a HexagonISD::RET_GLUE, and nothing else.
bool HasRet = false;
for (SDNode *Node : Copy->users()) {
if (Node->getOpcode() != HexagonISD::RET_GLUE)
return false;
HasRet = true;
}
if (!HasRet)
return false;

Chain = Copy->getOperand(0);
return true;
}
2 changes: 2 additions & 0 deletions llvm/lib/Target/Hexagon/HexagonISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ class HexagonTargetLowering : public TargetLowering {

bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const override;

bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override;

/// Return true if an FMA operation is faster than a pair of mul and add
/// instructions. fmuladd intrinsics will be expanded to FMAs when this
/// method returns true (and FMAs are legal), otherwise fmuladd is
Expand Down
99 changes: 11 additions & 88 deletions llvm/test/CodeGen/Hexagon/fast-math-libcalls.ll
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,8 @@ define float @fast_sqrt_f32(float %x) {
; CHECK-LABEL: fast_sqrt_f32:
; CHECK: .cfi_startproc
; CHECK-NEXT: // %bb.0:
; CHECK-NEXT: .cfi_def_cfa r30, 8
; CHECK-NEXT: .cfi_offset r31, -4
; CHECK-NEXT: .cfi_offset r30, -8
; CHECK-NEXT: {
; CHECK-NEXT: call __hexagon_fast2_sqrtf
; CHECK-NEXT: allocframe(r29,#0):raw
; CHECK-NEXT: }
; CHECK-NEXT: {
; CHECK-NEXT: r31:30 = dealloc_return(r30):raw
; CHECK-NEXT: jump __hexagon_fast2_sqrtf
; CHECK-NEXT: }
%result = call nnan ninf nsz afn float @llvm.sqrt.f32(float %x)
ret float %result
Expand All @@ -27,15 +20,8 @@ define double @fast_sqrt_f64(double %x) {
; CHECK-LABEL: fast_sqrt_f64:
; CHECK: .cfi_startproc
; CHECK-NEXT: // %bb.0:
; CHECK-NEXT: .cfi_def_cfa r30, 8
; CHECK-NEXT: .cfi_offset r31, -4
; CHECK-NEXT: .cfi_offset r30, -8
; CHECK-NEXT: {
; CHECK-NEXT: call __hexagon_fast2_sqrtdf2
; CHECK-NEXT: allocframe(r29,#0):raw
; CHECK-NEXT: }
; CHECK-NEXT: {
; CHECK-NEXT: r31:30 = dealloc_return(r30):raw
; CHECK-NEXT: jump __hexagon_fast2_sqrtdf2
; CHECK-NEXT: }
%result = call nnan ninf nsz afn double @llvm.sqrt.f64(double %x)
ret double %result
Expand All @@ -61,15 +47,8 @@ define double @fast_add_f64(double %x, double %y) {
; CHECK-LABEL: fast_add_f64:
; CHECK: .cfi_startproc
; CHECK-NEXT: // %bb.0:
; CHECK-NEXT: .cfi_def_cfa r30, 8
; CHECK-NEXT: .cfi_offset r31, -4
; CHECK-NEXT: .cfi_offset r30, -8
; CHECK-NEXT: {
; CHECK-NEXT: call __hexagon_fast_adddf3
; CHECK-NEXT: allocframe(r29,#0):raw
; CHECK-NEXT: }
; CHECK-NEXT: {
; CHECK-NEXT: r31:30 = dealloc_return(r30):raw
; CHECK-NEXT: jump __hexagon_fast_adddf3
; CHECK-NEXT: }
%result = fadd nnan ninf nsz afn double %x, %y
ret double %result
Expand All @@ -95,15 +74,8 @@ define double @fast_sub_f64(double %x, double %y) {
; CHECK-LABEL: fast_sub_f64:
; CHECK: .cfi_startproc
; CHECK-NEXT: // %bb.0:
; CHECK-NEXT: .cfi_def_cfa r30, 8
; CHECK-NEXT: .cfi_offset r31, -4
; CHECK-NEXT: .cfi_offset r30, -8
; CHECK-NEXT: {
; CHECK-NEXT: call __hexagon_fast_subdf3
; CHECK-NEXT: allocframe(r29,#0):raw
; CHECK-NEXT: }
; CHECK-NEXT: {
; CHECK-NEXT: r31:30 = dealloc_return(r30):raw
; CHECK-NEXT: jump __hexagon_fast_subdf3
; CHECK-NEXT: }
%result = fsub nnan ninf nsz afn double %x, %y
ret double %result
Expand All @@ -129,15 +101,8 @@ define double @fast_mul_f64(double %x, double %y) {
; CHECK-LABEL: fast_mul_f64:
; CHECK: .cfi_startproc
; CHECK-NEXT: // %bb.0:
; CHECK-NEXT: .cfi_def_cfa r30, 8
; CHECK-NEXT: .cfi_offset r31, -4
; CHECK-NEXT: .cfi_offset r30, -8
; CHECK-NEXT: {
; CHECK-NEXT: call __hexagon_fast_muldf3
; CHECK-NEXT: allocframe(r29,#0):raw
; CHECK-NEXT: }
; CHECK-NEXT: {
; CHECK-NEXT: r31:30 = dealloc_return(r30):raw
; CHECK-NEXT: jump __hexagon_fast_muldf3
; CHECK-NEXT: }
%result = fmul nnan ninf nsz afn double %x, %y
ret double %result
Expand Down Expand Up @@ -194,15 +159,8 @@ define double @fast_div_f64(double %x, double %y) {
; CHECK-LABEL: fast_div_f64:
; CHECK: .cfi_startproc
; CHECK-NEXT: // %bb.0:
; CHECK-NEXT: .cfi_def_cfa r30, 8
; CHECK-NEXT: .cfi_offset r31, -4
; CHECK-NEXT: .cfi_offset r30, -8
; CHECK-NEXT: {
; CHECK-NEXT: call __hexagon_fast_divdf3
; CHECK-NEXT: allocframe(r29,#0):raw
; CHECK-NEXT: }
; CHECK-NEXT: {
; CHECK-NEXT: r31:30 = dealloc_return(r30):raw
; CHECK-NEXT: jump __hexagon_fast_divdf3
; CHECK-NEXT: }
%result = fdiv nnan ninf nsz afn double %x, %y
ret double %result
Expand All @@ -217,15 +175,8 @@ define float @sqrt_f32__afn(float %x) {
; CHECK-LABEL: sqrt_f32__afn:
; CHECK: .cfi_startproc
; CHECK-NEXT: // %bb.0:
; CHECK-NEXT: .cfi_def_cfa r30, 8
; CHECK-NEXT: .cfi_offset r31, -4
; CHECK-NEXT: .cfi_offset r30, -8
; CHECK-NEXT: {
; CHECK-NEXT: call __hexagon_sqrtf
; CHECK-NEXT: allocframe(r29,#0):raw
; CHECK-NEXT: }
; CHECK-NEXT: {
; CHECK-NEXT: r31:30 = dealloc_return(r30):raw
; CHECK-NEXT: jump __hexagon_sqrtf
; CHECK-NEXT: }
%result = call afn float @llvm.sqrt.f32(float %x)
ret float %result
Expand All @@ -235,15 +186,8 @@ define float @sqrt_f32__afn_ninf(float %x) {
; CHECK-LABEL: sqrt_f32__afn_ninf:
; CHECK: .cfi_startproc
; CHECK-NEXT: // %bb.0:
; CHECK-NEXT: .cfi_def_cfa r30, 8
; CHECK-NEXT: .cfi_offset r31, -4
; CHECK-NEXT: .cfi_offset r30, -8
; CHECK-NEXT: {
; CHECK-NEXT: call __hexagon_sqrtf
; CHECK-NEXT: allocframe(r29,#0):raw
; CHECK-NEXT: }
; CHECK-NEXT: {
; CHECK-NEXT: r31:30 = dealloc_return(r30):raw
; CHECK-NEXT: jump __hexagon_sqrtf
; CHECK-NEXT: }
%result = call afn ninf float @llvm.sqrt.f32(float %x)
ret float %result
Expand All @@ -253,15 +197,8 @@ define float @sqrt_f32__afn_nnan(float %x) {
; CHECK-LABEL: sqrt_f32__afn_nnan:
; CHECK: .cfi_startproc
; CHECK-NEXT: // %bb.0:
; CHECK-NEXT: .cfi_def_cfa r30, 8
; CHECK-NEXT: .cfi_offset r31, -4
; CHECK-NEXT: .cfi_offset r30, -8
; CHECK-NEXT: {
; CHECK-NEXT: call __hexagon_sqrtf
; CHECK-NEXT: allocframe(r29,#0):raw
; CHECK-NEXT: }
; CHECK-NEXT: {
; CHECK-NEXT: r31:30 = dealloc_return(r30):raw
; CHECK-NEXT: jump __hexagon_sqrtf
; CHECK-NEXT: }
%result = call afn nnan float @llvm.sqrt.f32(float %x)
ret float %result
Expand All @@ -271,15 +208,8 @@ define float @sqrt_f32__nnan(float %x) {
; CHECK-LABEL: sqrt_f32__nnan:
; CHECK: .cfi_startproc
; CHECK-NEXT: // %bb.0:
; CHECK-NEXT: .cfi_def_cfa r30, 8
; CHECK-NEXT: .cfi_offset r31, -4
; CHECK-NEXT: .cfi_offset r30, -8
; CHECK-NEXT: {
; CHECK-NEXT: call __hexagon_sqrtf
; CHECK-NEXT: allocframe(r29,#0):raw
; CHECK-NEXT: }
; CHECK-NEXT: {
; CHECK-NEXT: r31:30 = dealloc_return(r30):raw
; CHECK-NEXT: jump __hexagon_sqrtf
; CHECK-NEXT: }
%result = call nnan float @llvm.sqrt.f32(float %x)
ret float %result
Expand All @@ -289,15 +219,8 @@ define float @sqrt_f32_nnan_ninf_afn(float %x) {
; CHECK-LABEL: sqrt_f32_nnan_ninf_afn:
; CHECK: .cfi_startproc
; CHECK-NEXT: // %bb.0:
; CHECK-NEXT: .cfi_def_cfa r30, 8
; CHECK-NEXT: .cfi_offset r31, -4
; CHECK-NEXT: .cfi_offset r30, -8
; CHECK-NEXT: {
; CHECK-NEXT: call __hexagon_sqrtf
; CHECK-NEXT: allocframe(r29,#0):raw
; CHECK-NEXT: }
; CHECK-NEXT: {
; CHECK-NEXT: r31:30 = dealloc_return(r30):raw
; CHECK-NEXT: jump __hexagon_sqrtf
; CHECK-NEXT: }
%result = call nnan ninf afn float @llvm.sqrt.f32(float %x)
ret float %result
Expand Down
8 changes: 4 additions & 4 deletions llvm/test/CodeGen/Hexagon/fminmax-v67.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@


; CHECK-LABEL: t1
; CHECK: call fmax
; CHECK: jump fmax

define dso_local double @t1(double %a, double %b) local_unnamed_addr {
entry:
Expand All @@ -11,7 +11,7 @@ entry:
}

; CHECK-LABEL: t2
; CHECK: call fmin
; CHECK: jump fmin

define dso_local double @t2(double %a, double %b) local_unnamed_addr {
entry:
Expand All @@ -20,7 +20,7 @@ entry:
}

; CHECK-LABEL: t3
; CHECK: call fmaxf
; CHECK: jump fmaxf

define dso_local float @t3(float %a, float %b) local_unnamed_addr {
entry:
Expand All @@ -29,7 +29,7 @@ entry:
}

; CHECK-LABEL: t4
; CHECK: call fminf
; CHECK: jump fminf

define dso_local float @t4(float %a, float %b) local_unnamed_addr {
entry:
Expand Down
8 changes: 4 additions & 4 deletions llvm/test/CodeGen/Hexagon/fminmax.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
target triple = "hexagon"

; CHECK-LABEL: cfminf
; CHECK: call fminf
; CHECK: jump fminf
define float @cfminf(float %x, float %y) #0 {
entry:
%call = tail call float @fminf(float %x, float %y) #1
ret float %call
}

; CHECK-LABEL: cfmaxf
; CHECK: call fmaxf
; CHECK: jump fmaxf
define float @cfmaxf(float %x, float %y) #0 {
entry:
%call = tail call float @fmaxf(float %x, float %y) #1
ret float %call
}

; CHECK-LABEL: minnum
; CHECK: call fminf
; CHECK: jump fminf
define float @minnum(float %x, float %y) #0 {
entry:
%call = tail call float @llvm.minnum.f32(float %x, float %y) #1
ret float %call
}

; CHECK-LABEL: maxnum
; CHECK: call fmaxf
; CHECK: jump fmaxf
define float @maxnum(float %x, float %y) #0 {
entry:
%call = tail call float @llvm.maxnum.f32(float %x, float %y) #1
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/Hexagon/fp16.ll
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
; Validate that we generate correct lib calls to convert fp16

;CHECK-LABEL: @test1
;CHECK: call __extendhfsf2
;CHECK: jump __extendhfsf2
;CHECK: r0 = memuh
define dso_local float @test1(ptr nocapture readonly %a) local_unnamed_addr #0 {
entry:
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/CodeGen/Hexagon/inline-division-space.ll
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ entry:
; Function Attrs: optsize
define dso_local float @testFloat(float %a, float %b) local_unnamed_addr #0 {
entry:
;CHECK: call __hexagon_divsf3
;CHECK: jump __hexagon_divsf3
%div = fdiv float %a, %b
ret float %div
}

; Function Attrs: optsize
define dso_local double @testDouble(double %a, double %b) local_unnamed_addr #0 {
entry:
;CHECK: call __hexagon_divdf3
;CHECK: jump __hexagon_divdf3
%div = fdiv double %a, %b
ret double %div
}
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/Hexagon/inline-division.ll
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ entry:

define dso_local double @testDouble(double %a, double %b) local_unnamed_addr {
entry:
;CHECK: call __hexagon_divdf3
;CHECK: jump __hexagon_divdf3
%div = fdiv double %a, %b
ret double %div
}
Loading
Loading