@@ -450,6 +450,7 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
450
450
setOperationAction(ISD::UINT_TO_FP, MVT::i32, Legal);
451
451
} else {
452
452
// PowerPC turns FP_TO_SINT into FCTIWZ and some load/stores.
453
+ setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i32, Custom);
453
454
setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
454
455
455
456
// PowerPC does not have [U|S]INT_TO_FP
@@ -582,12 +583,15 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
582
583
583
584
if (Subtarget.has64BitSupport()) {
584
585
// They also have instructions for converting between i64 and fp.
586
+ setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i64, Custom);
587
+ setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i64, Expand);
585
588
setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
586
589
setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand);
587
590
setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
588
591
setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand);
589
592
// This is just the low 32 bits of a (signed) fp->i64 conversion.
590
593
// We cannot do this with Promote because i64 is not a legal type.
594
+ setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i32, Custom);
591
595
setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
592
596
593
597
if (Subtarget.hasLFIWAX() || Subtarget.isPPC64())
@@ -597,19 +601,25 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
597
601
if (Subtarget.hasSPE()) {
598
602
setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i32, Legal);
599
603
setOperationAction(ISD::FP_TO_UINT, MVT::i32, Legal);
600
- } else
604
+ } else {
605
+ setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i32, Expand);
601
606
setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
607
+ }
602
608
}
603
609
604
610
// With the instructions enabled under FPCVT, we can do everything.
605
611
if (Subtarget.hasFPCVT()) {
606
612
if (Subtarget.has64BitSupport()) {
613
+ setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i64, Custom);
614
+ setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i64, Custom);
607
615
setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
608
616
setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom);
609
617
setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
610
618
setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom);
611
619
}
612
620
621
+ setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i32, Custom);
622
+ setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i32, Custom);
613
623
setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
614
624
setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
615
625
setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
@@ -1464,6 +1474,14 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
1464
1474
case PPCISD::MAT_PCREL_ADDR: return "PPCISD::MAT_PCREL_ADDR";
1465
1475
case PPCISD::LD_SPLAT: return "PPCISD::LD_SPLAT";
1466
1476
case PPCISD::FNMSUB: return "PPCISD::FNMSUB";
1477
+ case PPCISD::STRICT_FCTIDZ:
1478
+ return "PPCISD::STRICT_FCTIDZ";
1479
+ case PPCISD::STRICT_FCTIWZ:
1480
+ return "PPCISD::STRICT_FCTIWZ";
1481
+ case PPCISD::STRICT_FCTIDUZ:
1482
+ return "PPCISD::STRICT_FCTIDUZ";
1483
+ case PPCISD::STRICT_FCTIWUZ:
1484
+ return "PPCISD::STRICT_FCTIWUZ";
1467
1485
}
1468
1486
return nullptr;
1469
1487
}
@@ -7938,28 +7956,57 @@ SDValue PPCTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
7938
7956
return Op;
7939
7957
}
7940
7958
7959
+ static unsigned getPPCStrictOpcode(unsigned Opc) {
7960
+ switch (Opc) {
7961
+ default:
7962
+ llvm_unreachable("No strict version of this opcode!");
7963
+ case PPCISD::FCTIDZ:
7964
+ return PPCISD::STRICT_FCTIDZ;
7965
+ case PPCISD::FCTIWZ:
7966
+ return PPCISD::STRICT_FCTIWZ;
7967
+ case PPCISD::FCTIDUZ:
7968
+ return PPCISD::STRICT_FCTIDUZ;
7969
+ case PPCISD::FCTIWUZ:
7970
+ return PPCISD::STRICT_FCTIWUZ;
7971
+ }
7972
+ }
7973
+
7941
7974
static SDValue convertFPToInt(SDValue Op, SelectionDAG &DAG,
7942
7975
const PPCSubtarget &Subtarget) {
7943
7976
SDLoc dl(Op);
7944
- bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT;
7945
- SDValue Src = Op.getOperand(0);
7977
+ bool IsStrict = Op->isStrictFPOpcode();
7978
+ bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT ||
7979
+ Op.getOpcode() == ISD::STRICT_FP_TO_SINT;
7980
+ // For strict nodes, source is the second operand.
7981
+ SDValue Src = Op.getOperand(IsStrict ? 1 : 0);
7982
+ SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
7946
7983
assert(Src.getValueType().isFloatingPoint());
7947
- if (Src.getValueType() == MVT::f32)
7948
- Src = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Src);
7984
+ if (Src.getValueType() == MVT::f32) {
7985
+ if (IsStrict) {
7986
+ Src = DAG.getNode(ISD::STRICT_FP_EXTEND, dl, {MVT::f64, MVT::Other},
7987
+ {Chain, Src});
7988
+ Chain = Src.getValue(1);
7989
+ } else
7990
+ Src = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Src);
7991
+ }
7949
7992
SDValue Conv;
7993
+ unsigned Opc = ISD::DELETED_NODE;
7950
7994
switch (Op.getSimpleValueType().SimpleTy) {
7951
7995
default: llvm_unreachable("Unhandled FP_TO_INT type in custom expander!");
7952
7996
case MVT::i32:
7953
- Conv = DAG.getNode(
7954
- IsSigned ? PPCISD::FCTIWZ
7955
- : (Subtarget.hasFPCVT() ? PPCISD::FCTIWUZ : PPCISD::FCTIDZ),
7956
- dl, MVT::f64, Src);
7997
+ Opc = IsSigned ? PPCISD::FCTIWZ
7998
+ : (Subtarget.hasFPCVT() ? PPCISD::FCTIWUZ : PPCISD::FCTIDZ);
7957
7999
break;
7958
8000
case MVT::i64:
7959
8001
assert((IsSigned || Subtarget.hasFPCVT()) &&
7960
8002
"i64 FP_TO_UINT is supported only with FPCVT");
7961
- Conv = DAG.getNode(IsSigned ? PPCISD::FCTIDZ : PPCISD::FCTIDUZ, dl,
7962
- MVT::f64, Src);
8003
+ Opc = IsSigned ? PPCISD::FCTIDZ : PPCISD::FCTIDUZ;
8004
+ }
8005
+ if (IsStrict) {
8006
+ Opc = getPPCStrictOpcode(Opc);
8007
+ Conv = DAG.getNode(Opc, dl, {MVT::f64, MVT::Other}, {Chain, Src});
8008
+ } else {
8009
+ Conv = DAG.getNode(Opc, dl, MVT::f64, Src);
7963
8010
}
7964
8011
return Conv;
7965
8012
}
@@ -7968,7 +8015,9 @@ void PPCTargetLowering::LowerFP_TO_INTForReuse(SDValue Op, ReuseLoadInfo &RLI,
7968
8015
SelectionDAG &DAG,
7969
8016
const SDLoc &dl) const {
7970
8017
SDValue Tmp = convertFPToInt(Op, DAG, Subtarget);
7971
- bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT;
8018
+ bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT ||
8019
+ Op.getOpcode() == ISD::STRICT_FP_TO_SINT;
8020
+ bool IsStrict = Op->isStrictFPOpcode();
7972
8021
7973
8022
// Convert the FP value to an int value through memory.
7974
8023
bool i32Stack = Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
@@ -7979,18 +8028,18 @@ void PPCTargetLowering::LowerFP_TO_INTForReuse(SDValue Op, ReuseLoadInfo &RLI,
7979
8028
MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI);
7980
8029
7981
8030
// Emit a store to the stack slot.
7982
- SDValue Chain;
8031
+ SDValue Chain = IsStrict ? Tmp.getValue(1) : DAG.getEntryNode() ;
7983
8032
Align Alignment(DAG.getEVTAlign(Tmp.getValueType()));
7984
8033
if (i32Stack) {
7985
8034
MachineFunction &MF = DAG.getMachineFunction();
7986
8035
Alignment = Align(4);
7987
8036
MachineMemOperand *MMO =
7988
8037
MF.getMachineMemOperand(MPI, MachineMemOperand::MOStore, 4, Alignment);
7989
- SDValue Ops[] = { DAG.getEntryNode() , Tmp, FIPtr };
8038
+ SDValue Ops[] = { Chain , Tmp, FIPtr };
7990
8039
Chain = DAG.getMemIntrinsicNode(PPCISD::STFIWX, dl,
7991
8040
DAG.getVTList(MVT::Other), Ops, MVT::i32, MMO);
7992
8041
} else
7993
- Chain = DAG.getStore(DAG.getEntryNode() , dl, Tmp, FIPtr, MPI, Alignment);
8042
+ Chain = DAG.getStore(Chain , dl, Tmp, FIPtr, MPI, Alignment);
7994
8043
7995
8044
// Result is a load from the stack slot. If loading 4 bytes, make sure to
7996
8045
// add in a bias on big endian.
@@ -8012,23 +8061,29 @@ void PPCTargetLowering::LowerFP_TO_INTForReuse(SDValue Op, ReuseLoadInfo &RLI,
8012
8061
SDValue PPCTargetLowering::LowerFP_TO_INTDirectMove(SDValue Op,
8013
8062
SelectionDAG &DAG,
8014
8063
const SDLoc &dl) const {
8015
- assert(Op.getOperand(0).getValueType().isFloatingPoint());
8016
- return DAG.getNode(PPCISD::MFVSR, dl, Op.getSimpleValueType().SimpleTy,
8017
- convertFPToInt(Op, DAG, Subtarget));
8064
+ SDValue Conv = convertFPToInt(Op, DAG, Subtarget);
8065
+ SDValue Mov = DAG.getNode(PPCISD::MFVSR, dl, Op.getValueType(), Conv);
8066
+ if (Op->isStrictFPOpcode())
8067
+ return DAG.getMergeValues({Mov, Conv.getValue(1)}, dl);
8068
+ else
8069
+ return Mov;
8018
8070
}
8019
8071
8020
8072
SDValue PPCTargetLowering::LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG,
8021
8073
const SDLoc &dl) const {
8022
- SDValue Src = Op.getOperand(0);
8074
+ bool IsStrict = Op->isStrictFPOpcode();
8075
+ bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT ||
8076
+ Op.getOpcode() == ISD::STRICT_FP_TO_SINT;
8077
+ SDValue Src = Op.getOperand(IsStrict ? 1 : 0);
8023
8078
// FP to INT conversions are legal for f128.
8024
8079
if (Src.getValueType() == MVT::f128)
8025
8080
return Op;
8026
8081
8027
8082
// Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
8028
8083
// PPC (the libcall is not available).
8029
- if (Src.getValueType() == MVT::ppcf128) {
8084
+ if (Src.getValueType() == MVT::ppcf128 && !IsStrict ) {
8030
8085
if (Op.getValueType() == MVT::i32) {
8031
- if (Op.getOpcode() == ISD::FP_TO_SINT ) {
8086
+ if (IsSigned ) {
8032
8087
SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::f64, Src,
8033
8088
DAG.getIntPtrConstant(0, dl));
8034
8089
SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::f64, Src,
@@ -8039,8 +8094,7 @@ SDValue PPCTargetLowering::LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG,
8039
8094
8040
8095
// Now use a smaller FP_TO_SINT.
8041
8096
return DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Res);
8042
- }
8043
- if (Op.getOpcode() == ISD::FP_TO_UINT) {
8097
+ } else {
8044
8098
const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8045
8099
APFloat APF = APFloat(APFloat::PPCDoubleDouble(), APInt(128, TwoE31));
8046
8100
SDValue Tmp = DAG.getConstantFP(APF, dl, MVT::ppcf128);
@@ -10458,6 +10512,8 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
10458
10512
case ISD::STORE: return LowerSTORE(Op, DAG);
10459
10513
case ISD::TRUNCATE: return LowerTRUNCATE(Op, DAG);
10460
10514
case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
10515
+ case ISD::STRICT_FP_TO_UINT:
10516
+ case ISD::STRICT_FP_TO_SINT:
10461
10517
case ISD::FP_TO_UINT:
10462
10518
case ISD::FP_TO_SINT: return LowerFP_TO_INT(Op, DAG, SDLoc(Op));
10463
10519
case ISD::UINT_TO_FP:
@@ -10548,10 +10604,13 @@ void PPCTargetLowering::ReplaceNodeResults(SDNode *N,
10548
10604
}
10549
10605
return;
10550
10606
}
10607
+ case ISD::STRICT_FP_TO_SINT:
10608
+ case ISD::STRICT_FP_TO_UINT:
10551
10609
case ISD::FP_TO_SINT:
10552
10610
case ISD::FP_TO_UINT:
10553
10611
// LowerFP_TO_INT() can only handle f32 and f64.
10554
- if (N->getOperand(0).getValueType() == MVT::ppcf128)
10612
+ if (N->getOperand(N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
10613
+ MVT::ppcf128)
10555
10614
return;
10556
10615
Results.push_back(LowerFP_TO_INT(SDValue(N, 0), DAG, dl));
10557
10616
return;
0 commit comments