[llvm] 5fd406e - [PowerPC] Add intrinsic to convert between ppc_fp128 and fp128
Qiu Chaofan via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 5 02:02:33 PDT 2021
Author: Qiu Chaofan
Date: 2021-11-05T16:58:38+08:00
New Revision: 5fd406e254b22f26743284729ec5da99cc927add
URL: https://github.com/llvm/llvm-project/commit/5fd406e254b22f26743284729ec5da99cc927add
DIFF: https://github.com/llvm/llvm-project/commit/5fd406e254b22f26743284729ec5da99cc927add.diff
LOG: [PowerPC] Add intrinsic to convert between ppc_fp128 and fp128
ppc_fp128 and fp128 are both 128-bit floating point types. However, we
can't do conversion between them now, since trunc/ext are not allowed
for same-size fp types.
This patch adds two new intrinsics: llvm.ppc.convert.f128.to.ppcf128 and
llvm.convert.ppcf128.to.f128, to support such conversion.
Reviewed By: shchenz
Differential Revision: https://reviews.llvm.org/D109421
Added:
Modified:
llvm/include/llvm/IR/IntrinsicsPowerPC.td
llvm/include/llvm/IR/RuntimeLibcalls.def
llvm/lib/Target/PowerPC/PPCISelLowering.cpp
llvm/test/CodeGen/PowerPC/f128-truncateNconv.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
index 4161e3b8b0f23..8290342c0d51a 100644
--- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td
+++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
@@ -1755,6 +1755,11 @@ let TargetPrefix = "ppc" in {
def int_ppc_test_data_class_f : Intrinsic<[llvm_i32_ty],
[llvm_float_ty, llvm_i32_ty],
[IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+ 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
index 5f295660557ad..62d67308114f8 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.def
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.def
@@ -376,6 +376,8 @@ HANDLE_LIBCALL(UINTTOFP_I128_F64, "__floatuntidf")
HANDLE_LIBCALL(UINTTOFP_I128_F80, "__floatuntixf")
HANDLE_LIBCALL(UINTTOFP_I128_F128, "__floatuntitf")
HANDLE_LIBCALL(UINTTOFP_I128_PPCF128, "__floatuntitf")
+HANDLE_LIBCALL(CONVERT_F128_PPCF128, "__extendkftf2")
+HANDLE_LIBCALL(CONVERT_PPCF128_F128, "__trunctfkf2")
// Comparison
HANDLE_LIBCALL(OEQ_F32, "__eqsf2")
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 0f9b70406c369..d8333023a0b59 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -10484,6 +10484,17 @@ SDValue PPCTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
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<SDValue, SDValue> 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
@@ -11122,12 +11133,15 @@ void PPCTargetLowering::ReplaceNodeResults(SDNode *N,
break;
}
case ISD::INTRINSIC_WO_CHAIN: {
- unsigned IntrinsicID =
- cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
-
- if (IntrinsicID == Intrinsic::ppc_pack_longdouble)
+ switch (cast<ConstantSDNode>(N->getOperand(0))->getZExtValue()) {
+ case Intrinsic::ppc_pack_longdouble:
Results.push_back(DAG.getNode(ISD::BUILD_PAIR, dl, MVT::ppcf128,
N->getOperand(2), N->getOperand(1)));
+ break;
+ case Intrinsic::ppc_convert_f128_to_ppcf128:
+ Results.push_back(LowerINTRINSIC_WO_CHAIN(SDValue(N, 0), DAG));
+ break;
+ }
break;
}
case ISD::VAARG: {
diff --git a/llvm/test/CodeGen/PowerPC/f128-truncateNconv.ll b/llvm/test/CodeGen/PowerPC/f128-truncateNconv.ll
index 0fcf5c81c4bf0..61c41dcef982a 100644
--- a/llvm/test/CodeGen/PowerPC/f128-truncateNconv.ll
+++ b/llvm/test/CodeGen/PowerPC/f128-truncateNconv.ll
@@ -1403,3 +1403,96 @@ entry:
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 __extendkftf2
+; 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 __extendkftf2
+; 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 __trunctfkf2
+; 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 __trunctfkf2
+; 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)
More information about the llvm-commits
mailing list