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
34 changes: 26 additions & 8 deletions llvm/include/llvm/IR/RuntimeLibcalls.td
Original file line number Diff line number Diff line change
Expand Up @@ -1614,13 +1614,6 @@ def __aeabi_h2f : RuntimeLibcallImpl<FPEXT_F16_F32>; // CallingConv::ARM_AAPCS
def __gnu_f2h_ieee : RuntimeLibcallImpl<FPROUND_F32_F16>;
def __gnu_h2f_ieee : RuntimeLibcallImpl<FPEXT_F16_F32>;

// In EABI, these functions have an __aeabi_ prefix, but in GNUEABI
// they have a __gnu_ prefix (which is the default).
def EABIHalfConvertCalls : LibcallImpls<(add __aeabi_f2h, __aeabi_h2f),
isTargetAEABIAndAAPCS_ABI> {
let CallingConv = ARM_AAPCS;
}

// The half <-> float conversion functions are always soft-float on
// non-watchos platforms, but are needed for some targets which use a
// hard-float calling convention by default.
Expand All @@ -1629,6 +1622,27 @@ def ARMHalfConvertLibcallCallingConv : LibcallCallingConv<
(isAAPCS_ABI(TT, ABIName) ? CallingConv::ARM_AAPCS : CallingConv::ARM_APCS)}]
>;

def ARMLibgccHalfConvertCalls :
LibcallImpls<(add __truncsfhf2, __extendhfsf2),
RuntimeLibcallPredicate<[{!TT.isTargetAEABI() && TT.isOSBinFormatMachO()}]>> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I follow this - the old code would add these on !Watch ABI as either AAPCS or APCS.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are the default values, and !WatchABI is not mutually exclusive. This needs to be expressed as the positive set of cases where it is used

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, but what I mean to say is that this feels like it applies to far more cases than previously.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sadly that test coverage is missing the cases for MachO/WatchABI. Would you mind adding a few cases to ensure that that the WatchOS ABI targets are properly handled?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to do this before, but update_llc_test_checks for some reason breaks on the watchOS triples. I do see no difference with and without this, but those triples also do not use the libcalls in the first place.

Part of the problem I'm trying to solve here is the conflation of does-this-call-exist and will this call be used

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hacked the triple into update_llc_test_checks

let CallingConv = ARMHalfConvertLibcallCallingConv;
}

// FIXME: These conditions are probably bugged. We're using the
// default libgcc call when the other cases are replaced.
def ARMDoubleToHalfCalls :
LibcallImpls<(add __truncdfhf2),
RuntimeLibcallPredicate<[{!TT.isTargetAEABI()}]>> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise

let CallingConv = ARMHalfConvertLibcallCallingConv;
}

// In EABI, these functions have an __aeabi_ prefix, but in GNUEABI
// they have a __gnu_ prefix (which is the default).
def EABIHalfConvertCalls : LibcallImpls<(add __aeabi_f2h, __aeabi_h2f),
isTargetAEABIAndAAPCS_ABI> {
let CallingConv = ARM_AAPCS;
}

def GNUEABIHalfConvertCalls :
LibcallImpls<(add __gnu_f2h_ieee, __gnu_h2f_ieee),
RuntimeLibcallPredicate<[{!TT.isOSBinFormatMachO() &&
Expand Down Expand Up @@ -1755,7 +1769,9 @@ def isARMOrThumb : RuntimeLibcallPredicate<"TT.isARM() || TT.isThumb()">;

def ARMSystemLibrary
: SystemRuntimeLibrary<isARMOrThumb,
(add WinDefaultLibcallImpls,
(add (sub WinDefaultLibcallImpls, ARMLibgccHalfConvertCalls,
GNUEABIHalfConvertCalls,
ARMDoubleToHalfCalls),
LibcallImpls<(add __powisf2, __powidf2), isNotOSMSVCRT>,
LibmHasFrexpF32, LibmHasLdexpF32,
LibmHasFrexpF128, LibmHasLdexpF128,
Expand All @@ -1769,8 +1785,10 @@ def ARMSystemLibrary

AEABICalls,
AEABI45MemCalls,
ARMLibgccHalfConvertCalls,
EABIHalfConvertCalls,
GNUEABIHalfConvertCalls,
ARMDoubleToHalfCalls,

// Use divmod compiler-rt calls for iOS 5.0 and later.
LibcallImpls<(add __divmodsi4, __udivmodsi4),
Expand Down
25 changes: 0 additions & 25 deletions llvm/lib/IR/RuntimeLibcalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,31 +33,6 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
EABI EABIVersion, StringRef ABIName) {
setTargetRuntimeLibcallSets(TT, ExceptionModel, FloatABI, EABIVersion,
ABIName);

if (TT.isARM() || TT.isThumb()) {
// The half <-> float conversion functions are always soft-float on
// non-watchos platforms, but are needed for some targets which use a
// hard-float calling convention by default.
if (!TT.isWatchABI()) {
if (isAAPCS_ABI(TT, ABIName)) {
setLibcallImplCallingConv(RTLIB::impl___truncsfhf2,
CallingConv::ARM_AAPCS);
setLibcallImplCallingConv(RTLIB::impl___truncdfhf2,
CallingConv::ARM_AAPCS);
setLibcallImplCallingConv(RTLIB::impl___extendhfsf2,
CallingConv::ARM_AAPCS);
} else {
setLibcallImplCallingConv(RTLIB::impl___truncsfhf2,
CallingConv::ARM_APCS);
setLibcallImplCallingConv(RTLIB::impl___truncdfhf2,
CallingConv::ARM_APCS);
setLibcallImplCallingConv(RTLIB::impl___extendhfsf2,
CallingConv::ARM_APCS);
}
}

return;
}
}

LLVM_ATTRIBUTE_ALWAYS_INLINE
Expand Down
91 changes: 91 additions & 0 deletions llvm/test/CodeGen/ARM/issue147935-half-convert-libcall-abi.ll
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
; RUN: llc -mtriple=arm-unknown-linux-eabi -mattr=+vfp2 < %s | FileCheck -check-prefixes=AAPCS-SOFT,EABI-SOFT %s
; RUN: llc -mtriple=armv7-unknown-linux -target-abi=apcs -float-abi=soft < %s | FileCheck -check-prefix=APCS %s
; RUN: llc -mtriple=armv7-unknown-linux -target-abi=apcs -float-abi=hard < %s | FileCheck -check-prefix=APCS %s
; RUN: llc -mtriple=armv7k-apple-watchos2.0 -mcpu=cortex-a7 < %s | FileCheck -check-prefix=WATCHABI-HARD %s
; RUN: llc -mtriple=armv7k-apple-watchos2.0 -mcpu=cortex-a7 -float-abi=soft < %s | FileCheck -check-prefix=WATCHABI-SOFT %s

define i1 @test(half %self) #0 {
; GNU-AAPCS-HARD-LABEL: test:
Expand Down Expand Up @@ -72,6 +74,26 @@ define i1 @test(half %self) #0 {
; APCS-NEXT: movwvs r0, #1
; APCS-NEXT: pop {lr}
; APCS-NEXT: bx lr
;
; WATCHABI-HARD-LABEL: test:
; WATCHABI-HARD: @ %bb.0:
; WATCHABI-HARD-NEXT: vcvtb.f32.f16 s0, s0
; WATCHABI-HARD-NEXT: mov r0, #0
; WATCHABI-HARD-NEXT: vcmp.f32 s0, s0
; WATCHABI-HARD-NEXT: vmrs APSR_nzcv, fpscr
; WATCHABI-HARD-NEXT: movwvs r0, #1
; WATCHABI-HARD-NEXT: bx lr
;
; WATCHABI-SOFT-LABEL: test:
; WATCHABI-SOFT: @ %bb.0:
; WATCHABI-SOFT-NEXT: vmov s0, r0
; WATCHABI-SOFT-NEXT: mov r1, #0
; WATCHABI-SOFT-NEXT: vcvtb.f32.f16 s0, s0
; WATCHABI-SOFT-NEXT: vcmp.f32 s0, s0
; WATCHABI-SOFT-NEXT: vmrs APSR_nzcv, fpscr
; WATCHABI-SOFT-NEXT: movwvs r1, #1
; WATCHABI-SOFT-NEXT: mov r0, r1
; WATCHABI-SOFT-NEXT: bx lr
%_0 = fcmp une half %self, %self
ret i1 %_0
}
Expand Down Expand Up @@ -111,6 +133,21 @@ define float @f16_to_f32(ptr %p) #0 {
; APCS: @ %bb.0:
; APCS-NEXT: ldrh r0, [r0]
; APCS-NEXT: b __gnu_h2f_ieee
;
; WATCHABI-HARD-LABEL: f16_to_f32:
; WATCHABI-HARD: @ %bb.0:
; WATCHABI-HARD-NEXT: ldrh r0, [r0]
; WATCHABI-HARD-NEXT: vmov s0, r0
; WATCHABI-HARD-NEXT: vcvtb.f32.f16 s0, s0
; WATCHABI-HARD-NEXT: bx lr
;
; WATCHABI-SOFT-LABEL: f16_to_f32:
; WATCHABI-SOFT: @ %bb.0:
; WATCHABI-SOFT-NEXT: ldrh r0, [r0]
; WATCHABI-SOFT-NEXT: vmov s0, r0
; WATCHABI-SOFT-NEXT: vcvtb.f32.f16 s0, s0
; WATCHABI-SOFT-NEXT: vmov r0, s0
; WATCHABI-SOFT-NEXT: bx lr
%load = load half, ptr %p
%cvt = fpext half %load to float
ret float %cvt
Expand Down Expand Up @@ -169,6 +206,21 @@ define void @f32_to_f16(ptr %p, float %arg) #0 {
; APCS-NEXT: bl __gnu_f2h_ieee
; APCS-NEXT: strh r0, [r4]
; APCS-NEXT: pop {r4, pc}
;
; WATCHABI-HARD-LABEL: f32_to_f16:
; WATCHABI-HARD: @ %bb.0:
; WATCHABI-HARD-NEXT: vcvtb.f16.f32 s0, s0
; WATCHABI-HARD-NEXT: vmov r1, s0
; WATCHABI-HARD-NEXT: strh r1, [r0]
; WATCHABI-HARD-NEXT: bx lr
;
; WATCHABI-SOFT-LABEL: f32_to_f16:
; WATCHABI-SOFT: @ %bb.0:
; WATCHABI-SOFT-NEXT: vmov s0, r1
; WATCHABI-SOFT-NEXT: vcvtb.f16.f32 s0, s0
; WATCHABI-SOFT-NEXT: vmov r1, s0
; WATCHABI-SOFT-NEXT: strh r1, [r0]
; WATCHABI-SOFT-NEXT: bx lr
%cvt = fptrunc float %arg to half
store half %cvt, ptr %p
ret void
Expand Down Expand Up @@ -231,6 +283,23 @@ define double @f16_to_f64(ptr %p) #0 {
; APCS-NEXT: vmov r0, r1, d16
; APCS-NEXT: pop {lr}
; APCS-NEXT: bx lr
;
; WATCHABI-HARD-LABEL: f16_to_f64:
; WATCHABI-HARD: @ %bb.0:
; WATCHABI-HARD-NEXT: ldrh r0, [r0]
; WATCHABI-HARD-NEXT: vmov s0, r0
; WATCHABI-HARD-NEXT: vcvtb.f32.f16 s0, s0
; WATCHABI-HARD-NEXT: vcvt.f64.f32 d0, s0
; WATCHABI-HARD-NEXT: bx lr
;
; WATCHABI-SOFT-LABEL: f16_to_f64:
; WATCHABI-SOFT: @ %bb.0:
; WATCHABI-SOFT-NEXT: ldrh r0, [r0]
; WATCHABI-SOFT-NEXT: vmov s0, r0
; WATCHABI-SOFT-NEXT: vcvtb.f32.f16 s0, s0
; WATCHABI-SOFT-NEXT: vcvt.f64.f32 d16, s0
; WATCHABI-SOFT-NEXT: vmov r0, r1, d16
; WATCHABI-SOFT-NEXT: bx lr
%load = load half, ptr %p
%cvt = fpext half %load to double
ret double %cvt
Expand Down Expand Up @@ -269,6 +338,28 @@ define void @f64_to_f16(ptr %p, double %arg) #0 {
; APCS-NEXT: bl __truncdfhf2
; APCS-NEXT: strh r0, [r4]
; APCS-NEXT: pop {r4, pc}
;
; WATCHABI-HARD-LABEL: f64_to_f16:
; WATCHABI-HARD: @ %bb.0:
; WATCHABI-HARD-NEXT: push {r4, lr}
; WATCHABI-HARD-NEXT: sub sp, sp, #8
; WATCHABI-HARD-NEXT: mov r4, r0
; WATCHABI-HARD-NEXT: bl ___truncdfhf2
; WATCHABI-HARD-NEXT: strh r0, [r4]
; WATCHABI-HARD-NEXT: add sp, sp, #8
; WATCHABI-HARD-NEXT: pop {r4, pc}
;
; WATCHABI-SOFT-LABEL: f64_to_f16:
; WATCHABI-SOFT: @ %bb.0:
; WATCHABI-SOFT-NEXT: push {r4, lr}
; WATCHABI-SOFT-NEXT: sub sp, sp, #8
; WATCHABI-SOFT-NEXT: mov r4, r0
; WATCHABI-SOFT-NEXT: mov r1, r3
; WATCHABI-SOFT-NEXT: mov r0, r2
; WATCHABI-SOFT-NEXT: bl ___truncdfhf2
; WATCHABI-SOFT-NEXT: strh r0, [r4]
; WATCHABI-SOFT-NEXT: add sp, sp, #8
; WATCHABI-SOFT-NEXT: pop {r4, pc}
%cvt = fptrunc double %arg to half
store half %cvt, ptr %p
ret void
Expand Down
1 change: 1 addition & 0 deletions llvm/utils/UpdateTestChecks/asm.py
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,7 @@ def get_run_handler(triple):
"arm64-apple-macosx": (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),
"armv7-apple-ios": (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_IOS_RE),
"armv7-apple-darwin": (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_DARWIN_RE),
"armv7k-apple-watchos": (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_DARWIN_RE),
"thumb": (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
"thumb-macho": (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_MACHO_RE),
"thumbv5-macho": (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_MACHO_RE),
Expand Down
Loading