[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:
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user