[PowerPC] Support conversion between f16 and f128 (#130158)

Enables conversion between f16 and f128.
Expanding on pre-Power9 targets and using HW instructions on Power9.

Fixes https://github.com/llvm/llvm-project/issues/92866
Commandeer of:  https://github.com/llvm/llvm-project/pull/97677

---------

Co-authored-by: esmeyi <esme.yi@ibm.com>
This commit is contained in:
Lei Huang
2025-03-19 10:19:57 -04:00
committed by GitHub
parent be0a3b223a
commit ade22fc1d9
5 changed files with 215 additions and 300 deletions

View File

@@ -82,6 +82,7 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT) {
setLibcallName(RTLIB::POWI_F128, "__powikf2");
setLibcallName(RTLIB::FPEXT_F32_F128, "__extendsfkf2");
setLibcallName(RTLIB::FPEXT_F64_F128, "__extenddfkf2");
setLibcallName(RTLIB::FPROUND_F128_F16, "__trunckfhf2");
setLibcallName(RTLIB::FPROUND_F128_F32, "__trunckfsf2");
setLibcallName(RTLIB::FPROUND_F128_F64, "__trunckfdf2");
setLibcallName(RTLIB::FPTOSINT_F128_I32, "__fixkfsi");

View File

@@ -223,13 +223,19 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i8, Expand);
}
setTruncStoreAction(MVT::f128, MVT::f16, Expand);
setOperationAction(ISD::FP_TO_FP16, MVT::f128, Expand);
if (Subtarget.isISA3_0()) {
setLoadExtAction(ISD::EXTLOAD, MVT::f128, MVT::f16, Legal);
setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f16, Legal);
setLoadExtAction(ISD::EXTLOAD, MVT::f32, MVT::f16, Legal);
setTruncStoreAction(MVT::f64, MVT::f16, Legal);
setTruncStoreAction(MVT::f32, MVT::f16, Legal);
} else {
// No extending loads from f16 or HW conversions back and forth.
setLoadExtAction(ISD::EXTLOAD, MVT::f128, MVT::f16, Expand);
setOperationAction(ISD::FP16_TO_FP, MVT::f128, Expand);
setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f16, Expand);
setOperationAction(ISD::FP16_TO_FP, MVT::f64, Expand);
setOperationAction(ISD::FP_TO_FP16, MVT::f64, Expand);

View File

@@ -3995,6 +3995,8 @@ defm : ScalToVecWPermute<
(SUBREG_TO_REG (i64 1), (VEXTSH2Ds (LXSIHZX ForceXForm:$src)), sub_64)>;
// Load/convert and convert/store patterns for f16.
def : Pat<(f128 (extloadf16 ForceXForm:$src)),
(f128 (XSCVDPQP (XSCVHPDP (LXSIHZX ForceXForm:$src))))>;
def : Pat<(f64 (extloadf16 ForceXForm:$src)),
(f64 (XSCVHPDP (LXSIHZX ForceXForm:$src)))>;
def : Pat<(truncstoref16 f64:$src, ForceXForm:$dst),
@@ -4003,6 +4005,8 @@ def : Pat<(f32 (extloadf16 ForceXForm:$src)),
(f32 (COPY_TO_REGCLASS (XSCVHPDP (LXSIHZX ForceXForm:$src)), VSSRC))>;
def : Pat<(truncstoref16 f32:$src, ForceXForm:$dst),
(STXSIHX (XSCVDPHP (COPY_TO_REGCLASS $src, VSFRC)), ForceXForm:$dst)>;
def : Pat<(f128 (f16_to_fp i32:$A)),
(f128 (XSCVDPQP (XSCVHPDP (MTVSRWZ $A))))>;
def : Pat<(f64 (f16_to_fp i32:$A)),
(f64 (XSCVHPDP (MTVSRWZ $A)))>;
def : Pat<(f32 (f16_to_fp i32:$A)),

File diff suppressed because it is too large Load Diff

View File

@@ -30,6 +30,15 @@ define fp128 @divkf3(fp128 %a, fp128 %b) {
ret fp128 %1
}
define fp128 @extendsfkf2_f16(half %a) {
; CHECK-LABEL: extendsfkf2_f16:
; CHECK: __extendsfkf2
entry:
%i = fpext half %a to fp128
ret fp128 %i
}
define fp128 @extendsfkf2(float %a) {
; CHECK-LABEL: extendsfkf2:
; CHECK: __extendsfkf2
@@ -44,6 +53,14 @@ define fp128 @extenddfkf2(double %a) {
ret fp128 %1
}
define half @trunctfhf2(fp128 %a) {
; CHECK-LABEL: trunctfhf2:
; CHECK: __trunckfhf2
entry:
%i = fptrunc fp128 %a to half
ret half %i
}
define float @trunckfsf2(fp128 %a) {
; CHECK-LABEL: trunckfsf2:
; CHECK: __trunckfsf2