diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h --- a/llvm/include/llvm/IR/Intrinsics.h +++ b/llvm/include/llvm/IR/Intrinsics.h @@ -123,6 +123,7 @@ BFloat, Float, Double, + DoubleDouble, Quad, Integer, Vector, diff --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td --- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td +++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td @@ -1744,6 +1744,10 @@ def int_ppc_test_data_class_f : Intrinsic<[llvm_i32_ty], [llvm_float_ty, llvm_i32_ty], [IntrNoMem, ImmArg>]>; + def int_ppc_convert_f128_to_ppcf128 + : Intrinsic<[llvm_ppcf128_ty], [llvm_f128_ty], [IntrNoMem]>; + def int_ppc_convert_ppcf128_to_f128 + : Intrinsic<[llvm_f128_ty], [llvm_ppcf128_ty], [IntrNoMem]>; } //===----------------------------------------------------------------------===// diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.def b/llvm/include/llvm/IR/RuntimeLibcalls.def --- a/llvm/include/llvm/IR/RuntimeLibcalls.def +++ b/llvm/include/llvm/IR/RuntimeLibcalls.def @@ -376,6 +376,8 @@ HANDLE_LIBCALL(UINTTOFP_I128_F80, "__floatuntixf") HANDLE_LIBCALL(UINTTOFP_I128_F128, "__floatuntitf") HANDLE_LIBCALL(UINTTOFP_I128_PPCF128, "__floatuntitf") +HANDLE_LIBCALL(CONVERT_F128_PPCF128, "__trunctfkf2") +HANDLE_LIBCALL(CONVERT_PPCF128_F128, "__extendkftf2") // Comparison HANDLE_LIBCALL(OEQ_F32, "__eqsf2") diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -979,7 +979,8 @@ IIT_BF16 = 48, IIT_STRUCT9 = 49, IIT_V256 = 50, - IIT_AMX = 51 + IIT_AMX = 51, + IIT_PPCF128 = 52 }; static void DecodeIITType(unsigned &NextElt, ArrayRef Infos, @@ -1026,6 +1027,9 @@ case IIT_F128: OutputTable.push_back(IITDescriptor::get(IITDescriptor::Quad, 0)); return; + case IIT_PPCF128: + OutputTable.push_back(IITDescriptor::get(IITDescriptor::DoubleDouble, 0)); + return; case IIT_I1: OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 1)); return; @@ -1249,6 +1253,7 @@ case IITDescriptor::BFloat: return Type::getBFloatTy(Context); case IITDescriptor::Float: return Type::getFloatTy(Context); case IITDescriptor::Double: return Type::getDoubleTy(Context); + case IITDescriptor::DoubleDouble: return Type::getPPC_FP128Ty(Context); case IITDescriptor::Quad: return Type::getFP128Ty(Context); case IITDescriptor::Integer: @@ -1431,6 +1436,7 @@ case IITDescriptor::BFloat: return !Ty->isBFloatTy(); case IITDescriptor::Float: return !Ty->isFloatTy(); case IITDescriptor::Double: return !Ty->isDoubleTy(); + case IITDescriptor::DoubleDouble: return !Ty->isPPC_FP128Ty(); case IITDescriptor::Quad: return !Ty->isFP128Ty(); case IITDescriptor::Integer: return !Ty->isIntegerTy(D.Integer_Width); case IITDescriptor::Vector: { diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -601,6 +601,7 @@ // We want to custom lower some of our intrinsics. setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); + setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::ppcf128, Custom); // To handle counter-based loop conditions. setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i1, Custom); @@ -10406,6 +10407,17 @@ DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}), 0); } + case Intrinsic::ppc_convert_f128_to_ppcf128: + case Intrinsic::ppc_convert_ppcf128_to_f128: { + RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128 + ? RTLIB::CONVERT_PPCF128_F128 + : RTLIB::CONVERT_F128_PPCF128; + MakeLibCallOptions CallOptions; + std::pair Result = + makeLibCall(DAG, LC, Op.getValueType(), Op.getOperand(1), CallOptions, + dl, SDValue()); + return Result.first; + } } // If this is a lowered altivec predicate compare, CompareOpc is set to the @@ -11043,6 +11055,12 @@ Results.push_back(NewInt.getValue(1)); break; } + case ISD::INTRINSIC_WO_CHAIN: + if (cast(N->getOperand(0))->getZExtValue() == + Intrinsic::ppc_convert_f128_to_ppcf128) { + Results.push_back(LowerINTRINSIC_WO_CHAIN(SDValue(N, 0), DAG)); + } + break; case ISD::VAARG: { if (!Subtarget.isSVR4ABI() || Subtarget.isPPC64()) return; diff --git a/llvm/test/CodeGen/PowerPC/f128-truncateNconv.ll b/llvm/test/CodeGen/PowerPC/f128-truncateNconv.ll --- a/llvm/test/CodeGen/PowerPC/f128-truncateNconv.ll +++ b/llvm/test/CodeGen/PowerPC/f128-truncateNconv.ll @@ -1403,3 +1403,96 @@ store i8 %conv, i8* %res, align 1 ret void } + +define void @qpConvppcf128(fp128 %src, ppc_fp128* %dst) { +; CHECK-LABEL: qpConvppcf128: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mflr r0 +; CHECK-NEXT: .cfi_def_cfa_offset 48 +; CHECK-NEXT: .cfi_offset lr, 16 +; CHECK-NEXT: .cfi_offset r30, -16 +; CHECK-NEXT: std r30, -16(r1) # 8-byte Folded Spill +; CHECK-NEXT: std r0, 16(r1) +; CHECK-NEXT: stdu r1, -48(r1) +; CHECK-NEXT: mr r30, r5 +; CHECK-NEXT: bl __trunctfkf2 +; CHECK-NEXT: nop +; CHECK-NEXT: stfd f2, 8(r30) +; CHECK-NEXT: stfd f1, 0(r30) +; CHECK-NEXT: addi r1, r1, 48 +; CHECK-NEXT: ld r0, 16(r1) +; CHECK-NEXT: ld r30, -16(r1) # 8-byte Folded Reload +; CHECK-NEXT: mtlr r0 +; CHECK-NEXT: blr +; +; CHECK-P8-LABEL: qpConvppcf128: +; CHECK-P8: # %bb.0: # %entry +; CHECK-P8-NEXT: mflr r0 +; CHECK-P8-NEXT: .cfi_def_cfa_offset 48 +; CHECK-P8-NEXT: .cfi_offset lr, 16 +; CHECK-P8-NEXT: .cfi_offset r30, -16 +; CHECK-P8-NEXT: std r30, -16(r1) # 8-byte Folded Spill +; CHECK-P8-NEXT: std r0, 16(r1) +; CHECK-P8-NEXT: stdu r1, -48(r1) +; CHECK-P8-NEXT: mr r30, r5 +; CHECK-P8-NEXT: bl __trunctfkf2 +; CHECK-P8-NEXT: nop +; CHECK-P8-NEXT: stfd f2, 8(r30) +; CHECK-P8-NEXT: stfd f1, 0(r30) +; CHECK-P8-NEXT: addi r1, r1, 48 +; CHECK-P8-NEXT: ld r0, 16(r1) +; CHECK-P8-NEXT: ld r30, -16(r1) # 8-byte Folded Reload +; CHECK-P8-NEXT: mtlr r0 +; CHECK-P8-NEXT: blr +entry: + %res = call ppc_fp128 @llvm.ppc.convert.f128.to.ppcf128(fp128 %src) + store ppc_fp128 %res, ppc_fp128* %dst, align 16 + ret void +} + +define void @ppcf128Convqp(ppc_fp128 %src, fp128* %dst) { +; CHECK-LABEL: ppcf128Convqp: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mflr r0 +; CHECK-NEXT: .cfi_def_cfa_offset 48 +; CHECK-NEXT: .cfi_offset lr, 16 +; CHECK-NEXT: .cfi_offset r30, -16 +; CHECK-NEXT: std r30, -16(r1) # 8-byte Folded Spill +; CHECK-NEXT: std r0, 16(r1) +; CHECK-NEXT: stdu r1, -48(r1) +; CHECK-NEXT: mr r30, r5 +; CHECK-NEXT: bl __extendkftf2 +; CHECK-NEXT: nop +; CHECK-NEXT: stxv v2, 0(r30) +; CHECK-NEXT: addi r1, r1, 48 +; CHECK-NEXT: ld r0, 16(r1) +; CHECK-NEXT: ld r30, -16(r1) # 8-byte Folded Reload +; CHECK-NEXT: mtlr r0 +; CHECK-NEXT: blr +; +; CHECK-P8-LABEL: ppcf128Convqp: +; CHECK-P8: # %bb.0: # %entry +; CHECK-P8-NEXT: mflr r0 +; CHECK-P8-NEXT: .cfi_def_cfa_offset 48 +; CHECK-P8-NEXT: .cfi_offset lr, 16 +; CHECK-P8-NEXT: .cfi_offset r30, -16 +; CHECK-P8-NEXT: std r30, -16(r1) # 8-byte Folded Spill +; CHECK-P8-NEXT: std r0, 16(r1) +; CHECK-P8-NEXT: stdu r1, -48(r1) +; CHECK-P8-NEXT: mr r30, r5 +; CHECK-P8-NEXT: bl __extendkftf2 +; CHECK-P8-NEXT: nop +; CHECK-P8-NEXT: stvx v2, 0, r30 +; CHECK-P8-NEXT: addi r1, r1, 48 +; CHECK-P8-NEXT: ld r0, 16(r1) +; CHECK-P8-NEXT: ld r30, -16(r1) # 8-byte Folded Reload +; CHECK-P8-NEXT: mtlr r0 +; CHECK-P8-NEXT: blr +entry: + %res = call fp128 @llvm.ppc.convert.ppcf128.to.f128(ppc_fp128 %src) + store fp128 %res, fp128* %dst, align 16 + ret void +} + +declare ppc_fp128 @llvm.ppc.convert.f128.to.ppcf128(fp128) +declare fp128 @llvm.ppc.convert.ppcf128.to.f128(ppc_fp128) diff --git a/llvm/utils/TableGen/IntrinsicEmitter.cpp b/llvm/utils/TableGen/IntrinsicEmitter.cpp --- a/llvm/utils/TableGen/IntrinsicEmitter.cpp +++ b/llvm/utils/TableGen/IntrinsicEmitter.cpp @@ -249,7 +249,8 @@ IIT_BF16 = 48, IIT_STRUCT9 = 49, IIT_V256 = 50, - IIT_AMX = 51 + IIT_AMX = 51, + IIT_PPCF128 = 52, }; static void EncodeFixedValueType(MVT::SimpleValueType VT, @@ -274,6 +275,7 @@ case MVT::f32: return Sig.push_back(IIT_F32); case MVT::f64: return Sig.push_back(IIT_F64); case MVT::f128: return Sig.push_back(IIT_F128); + case MVT::ppcf128: return Sig.push_back(IIT_PPCF128); case MVT::token: return Sig.push_back(IIT_TOKEN); case MVT::Metadata: return Sig.push_back(IIT_METADATA); case MVT::x86mmx: return Sig.push_back(IIT_MMX);