Skip to content

Commit 5fd406e

Browse files
committed
[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
1 parent df0ba47 commit 5fd406e

File tree

4 files changed

+118
-4
lines changed

4 files changed

+118
-4
lines changed

llvm/include/llvm/IR/IntrinsicsPowerPC.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1755,6 +1755,11 @@ let TargetPrefix = "ppc" in {
17551755
def int_ppc_test_data_class_f : Intrinsic<[llvm_i32_ty],
17561756
[llvm_float_ty, llvm_i32_ty],
17571757
[IntrNoMem, ImmArg<ArgIndex<1>>]>;
1758+
1759+
def int_ppc_convert_f128_to_ppcf128
1760+
: Intrinsic<[llvm_ppcf128_ty], [llvm_f128_ty], [IntrNoMem]>;
1761+
def int_ppc_convert_ppcf128_to_f128
1762+
: Intrinsic<[llvm_f128_ty], [llvm_ppcf128_ty], [IntrNoMem]>;
17581763
}
17591764

17601765
//===----------------------------------------------------------------------===//

llvm/include/llvm/IR/RuntimeLibcalls.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,8 @@ HANDLE_LIBCALL(UINTTOFP_I128_F64, "__floatuntidf")
376376
HANDLE_LIBCALL(UINTTOFP_I128_F80, "__floatuntixf")
377377
HANDLE_LIBCALL(UINTTOFP_I128_F128, "__floatuntitf")
378378
HANDLE_LIBCALL(UINTTOFP_I128_PPCF128, "__floatuntitf")
379+
HANDLE_LIBCALL(CONVERT_F128_PPCF128, "__extendkftf2")
380+
HANDLE_LIBCALL(CONVERT_PPCF128_F128, "__trunctfkf2")
379381

380382
// Comparison
381383
HANDLE_LIBCALL(OEQ_F32, "__eqsf2")

llvm/lib/Target/PowerPC/PPCISelLowering.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10484,6 +10484,17 @@ SDValue PPCTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
1048410484
DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
1048510485
0);
1048610486
}
10487+
case Intrinsic::ppc_convert_f128_to_ppcf128:
10488+
case Intrinsic::ppc_convert_ppcf128_to_f128: {
10489+
RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
10490+
? RTLIB::CONVERT_PPCF128_F128
10491+
: RTLIB::CONVERT_F128_PPCF128;
10492+
MakeLibCallOptions CallOptions;
10493+
std::pair<SDValue, SDValue> Result =
10494+
makeLibCall(DAG, LC, Op.getValueType(), Op.getOperand(1), CallOptions,
10495+
dl, SDValue());
10496+
return Result.first;
10497+
}
1048710498
}
1048810499

1048910500
// If this is a lowered altivec predicate compare, CompareOpc is set to the
@@ -11122,12 +11133,15 @@ void PPCTargetLowering::ReplaceNodeResults(SDNode *N,
1112211133
break;
1112311134
}
1112411135
case ISD::INTRINSIC_WO_CHAIN: {
11125-
unsigned IntrinsicID =
11126-
cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
11127-
11128-
if (IntrinsicID == Intrinsic::ppc_pack_longdouble)
11136+
switch (cast<ConstantSDNode>(N->getOperand(0))->getZExtValue()) {
11137+
case Intrinsic::ppc_pack_longdouble:
1112911138
Results.push_back(DAG.getNode(ISD::BUILD_PAIR, dl, MVT::ppcf128,
1113011139
N->getOperand(2), N->getOperand(1)));
11140+
break;
11141+
case Intrinsic::ppc_convert_f128_to_ppcf128:
11142+
Results.push_back(LowerINTRINSIC_WO_CHAIN(SDValue(N, 0), DAG));
11143+
break;
11144+
}
1113111145
break;
1113211146
}
1113311147
case ISD::VAARG: {

llvm/test/CodeGen/PowerPC/f128-truncateNconv.ll

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1403,3 +1403,96 @@ entry:
14031403
store i8 %conv, i8* %res, align 1
14041404
ret void
14051405
}
1406+
1407+
define void @qpConvppcf128(fp128 %src, ppc_fp128* %dst) {
1408+
; CHECK-LABEL: qpConvppcf128:
1409+
; CHECK: # %bb.0: # %entry
1410+
; CHECK-NEXT: mflr r0
1411+
; CHECK-NEXT: .cfi_def_cfa_offset 48
1412+
; CHECK-NEXT: .cfi_offset lr, 16
1413+
; CHECK-NEXT: .cfi_offset r30, -16
1414+
; CHECK-NEXT: std r30, -16(r1) # 8-byte Folded Spill
1415+
; CHECK-NEXT: std r0, 16(r1)
1416+
; CHECK-NEXT: stdu r1, -48(r1)
1417+
; CHECK-NEXT: mr r30, r5
1418+
; CHECK-NEXT: bl __extendkftf2
1419+
; CHECK-NEXT: nop
1420+
; CHECK-NEXT: stfd f2, 8(r30)
1421+
; CHECK-NEXT: stfd f1, 0(r30)
1422+
; CHECK-NEXT: addi r1, r1, 48
1423+
; CHECK-NEXT: ld r0, 16(r1)
1424+
; CHECK-NEXT: ld r30, -16(r1) # 8-byte Folded Reload
1425+
; CHECK-NEXT: mtlr r0
1426+
; CHECK-NEXT: blr
1427+
;
1428+
; CHECK-P8-LABEL: qpConvppcf128:
1429+
; CHECK-P8: # %bb.0: # %entry
1430+
; CHECK-P8-NEXT: mflr r0
1431+
; CHECK-P8-NEXT: .cfi_def_cfa_offset 48
1432+
; CHECK-P8-NEXT: .cfi_offset lr, 16
1433+
; CHECK-P8-NEXT: .cfi_offset r30, -16
1434+
; CHECK-P8-NEXT: std r30, -16(r1) # 8-byte Folded Spill
1435+
; CHECK-P8-NEXT: std r0, 16(r1)
1436+
; CHECK-P8-NEXT: stdu r1, -48(r1)
1437+
; CHECK-P8-NEXT: mr r30, r5
1438+
; CHECK-P8-NEXT: bl __extendkftf2
1439+
; CHECK-P8-NEXT: nop
1440+
; CHECK-P8-NEXT: stfd f2, 8(r30)
1441+
; CHECK-P8-NEXT: stfd f1, 0(r30)
1442+
; CHECK-P8-NEXT: addi r1, r1, 48
1443+
; CHECK-P8-NEXT: ld r0, 16(r1)
1444+
; CHECK-P8-NEXT: ld r30, -16(r1) # 8-byte Folded Reload
1445+
; CHECK-P8-NEXT: mtlr r0
1446+
; CHECK-P8-NEXT: blr
1447+
entry:
1448+
%res = call ppc_fp128 @llvm.ppc.convert.f128.to.ppcf128(fp128 %src)
1449+
store ppc_fp128 %res, ppc_fp128* %dst, align 16
1450+
ret void
1451+
}
1452+
1453+
define void @ppcf128Convqp(ppc_fp128 %src, fp128* %dst) {
1454+
; CHECK-LABEL: ppcf128Convqp:
1455+
; CHECK: # %bb.0: # %entry
1456+
; CHECK-NEXT: mflr r0
1457+
; CHECK-NEXT: .cfi_def_cfa_offset 48
1458+
; CHECK-NEXT: .cfi_offset lr, 16
1459+
; CHECK-NEXT: .cfi_offset r30, -16
1460+
; CHECK-NEXT: std r30, -16(r1) # 8-byte Folded Spill
1461+
; CHECK-NEXT: std r0, 16(r1)
1462+
; CHECK-NEXT: stdu r1, -48(r1)
1463+
; CHECK-NEXT: mr r30, r5
1464+
; CHECK-NEXT: bl __trunctfkf2
1465+
; CHECK-NEXT: nop
1466+
; CHECK-NEXT: stxv v2, 0(r30)
1467+
; CHECK-NEXT: addi r1, r1, 48
1468+
; CHECK-NEXT: ld r0, 16(r1)
1469+
; CHECK-NEXT: ld r30, -16(r1) # 8-byte Folded Reload
1470+
; CHECK-NEXT: mtlr r0
1471+
; CHECK-NEXT: blr
1472+
;
1473+
; CHECK-P8-LABEL: ppcf128Convqp:
1474+
; CHECK-P8: # %bb.0: # %entry
1475+
; CHECK-P8-NEXT: mflr r0
1476+
; CHECK-P8-NEXT: .cfi_def_cfa_offset 48
1477+
; CHECK-P8-NEXT: .cfi_offset lr, 16
1478+
; CHECK-P8-NEXT: .cfi_offset r30, -16
1479+
; CHECK-P8-NEXT: std r30, -16(r1) # 8-byte Folded Spill
1480+
; CHECK-P8-NEXT: std r0, 16(r1)
1481+
; CHECK-P8-NEXT: stdu r1, -48(r1)
1482+
; CHECK-P8-NEXT: mr r30, r5
1483+
; CHECK-P8-NEXT: bl __trunctfkf2
1484+
; CHECK-P8-NEXT: nop
1485+
; CHECK-P8-NEXT: stvx v2, 0, r30
1486+
; CHECK-P8-NEXT: addi r1, r1, 48
1487+
; CHECK-P8-NEXT: ld r0, 16(r1)
1488+
; CHECK-P8-NEXT: ld r30, -16(r1) # 8-byte Folded Reload
1489+
; CHECK-P8-NEXT: mtlr r0
1490+
; CHECK-P8-NEXT: blr
1491+
entry:
1492+
%res = call fp128 @llvm.ppc.convert.ppcf128.to.f128(ppc_fp128 %src)
1493+
store fp128 %res, fp128* %dst, align 16
1494+
ret void
1495+
}
1496+
1497+
declare ppc_fp128 @llvm.ppc.convert.f128.to.ppcf128(fp128)
1498+
declare fp128 @llvm.ppc.convert.ppcf128.to.f128(ppc_fp128)

0 commit comments

Comments
 (0)