@@ -232,9 +232,14 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
232
232
for (auto Op : {ISD::FP_TO_SINT, ISD::STRICT_FP_TO_SINT,
233
233
ISD::SINT_TO_FP, ISD::STRICT_SINT_TO_FP})
234
234
setOperationAction (Op, VT, Custom);
235
- for (auto Op : {ISD::FP_TO_UINT, ISD::STRICT_FP_TO_UINT,
236
- ISD::UINT_TO_FP, ISD::STRICT_UINT_TO_FP})
235
+ for (auto Op : {ISD::FP_TO_UINT, ISD::STRICT_FP_TO_UINT})
237
236
setOperationAction (Op, VT, Custom);
237
+ for (auto Op : {ISD::UINT_TO_FP, ISD::STRICT_UINT_TO_FP}) {
238
+ // Handle unsigned 32-bit input types as signed 64-bit types on z10.
239
+ auto OpAction =
240
+ (!Subtarget.hasFPExtension () && VT == MVT::i32 ) ? Promote : Custom;
241
+ setOperationAction (Op, VT, OpAction);
242
+ }
238
243
}
239
244
}
240
245
@@ -578,7 +583,6 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
578
583
579
584
// Special treatment.
580
585
setOperationAction (ISD::IS_FPCLASS, VT, Custom);
581
- setOperationAction (ISD::FCOPYSIGN, VT, Custom);
582
586
583
587
// Handle constrained floating-point operations.
584
588
setOperationAction (ISD::STRICT_FADD, VT, Legal);
@@ -6825,22 +6829,18 @@ SDValue SystemZTargetLowering::lower_FP_TO_INT(SDValue Op,
6825
6829
EVT InVT = InOp.getValueType ();
6826
6830
6827
6831
// FP to unsigned is not directly supported on z10. Promoting an i32
6828
- // result to i64 doesn't generate an inexact condition for values that are
6829
- // outside the i32 range but in the i64 range, so use the default
6830
- // expansion.
6832
+ // result to (signed) i64 doesn't generate an inexact condition (fp
6833
+ // exception) for values that are outside the i32 range but in the i64
6834
+ // range, so use the default expansion.
6831
6835
if (!Subtarget.hasFPExtension () && !IsSigned)
6832
- return SDValue (); // Expand (i32 / i64).
6836
+ // Expand i32/i64. F16 values will be recognized to fit and extended.
6837
+ return SDValue ();
6833
6838
6839
+ // Conversion from f16 is done via f32.
6834
6840
if (InOp.getSimpleValueType () == MVT::f16 ) {
6835
- // f16: Extend to f32 before the conversion.
6836
- if (!IsStrict) {
6837
- SDValue InF32 = DAG.getFPExtendOrRound (InOp, SDLoc (InOp), MVT::f32 );
6838
- return DAG.getNode (Op->getOpcode (), DL, Op.getSimpleValueType (), InF32);
6839
- }
6840
- SDValue InF32;
6841
- std::tie (InF32, Chain) =
6842
- DAG.getStrictFPExtendOrRound (InOp, Chain, DL, MVT::f32 );
6843
- return DAG.getNode (Op->getOpcode (), DL, Op->getVTList (), {Chain, InF32});
6841
+ SmallVector<SDValue, 2 > Results;
6842
+ LowerOperationWrapper (Op.getNode (), Results, DAG);
6843
+ return DAG.getMergeValues (Results, DL);
6844
6844
}
6845
6845
6846
6846
if (VT == MVT::i128 ) {
@@ -6863,45 +6863,17 @@ SDValue SystemZTargetLowering::lower_INT_TO_FP(SDValue Op,
6863
6863
SDValue Chain = IsStrict ? Op.getOperand (0 ) : DAG.getEntryNode ();
6864
6864
EVT InVT = InOp.getValueType ();
6865
6865
6866
- auto roundToF16 = [&DAG, &IsStrict, &DL, &Chain](SDValue V) -> SDValue {
6867
- if (!IsStrict)
6868
- return DAG.getFPExtendOrRound (V, DL, MVT::f16 );
6869
- SDValue F16Res;
6870
- std::tie (F16Res, Chain) =
6871
- DAG.getStrictFPExtendOrRound (V, V.getValue (1 ), DL, MVT::f16 );
6872
- return DAG.getMergeValues ({F16Res, Chain}, DL);
6873
- };
6874
-
6875
- // Unsigned to fp is not directly supported on z10.
6876
- if (!Subtarget.hasFPExtension () && !IsSigned) {
6877
- if (InVT == MVT::i32 ) { // Conversion from i32 is promoted to i64 (signed).
6878
- SDValue I64In = DAG.getZExtOrTrunc (InOp, DL, MVT::i64 );
6879
- SDValue FPRes;
6880
- MVT ResVT = VT == MVT::f16 ? MVT::f32 : VT;
6881
- if (!IsStrict)
6882
- FPRes = DAG.getNode (ISD::SINT_TO_FP, DL, ResVT, I64In);
6883
- else
6884
- FPRes = DAG.getNode (ISD::STRICT_SINT_TO_FP, DL,
6885
- DAG.getVTList (ResVT, MVT::Other), {Chain, I64In});
6886
- return VT == MVT::f16 ? roundToF16 (FPRes) : FPRes;
6887
- }
6888
- assert (InVT == MVT::i64 && " i32 and i64 are the only legal int types." );
6889
- if (VT != MVT::f16 )
6890
- return SDValue (); // Expand
6891
- }
6892
-
6893
6866
// Conversion to f16 is done via f32.
6894
6867
if (VT == MVT::f16 ) {
6895
- SDValue PromotedOp;
6896
- if (!IsStrict)
6897
- PromotedOp = DAG.getNode (Op->getOpcode (), DL, MVT::f32 , InOp);
6898
- else
6899
- PromotedOp =
6900
- DAG.getNode (Op->getOpcode (), DL, DAG.getVTList (MVT::f32 , MVT::Other),
6901
- {Chain, InOp});
6902
- return roundToF16 (PromotedOp);
6868
+ SmallVector<SDValue, 2 > Results;
6869
+ LowerOperationWrapper (Op.getNode (), Results, DAG);
6870
+ return DAG.getMergeValues (Results, DL);
6903
6871
}
6904
6872
6873
+ // Unsigned to fp is not directly supported on z10.
6874
+ if (!Subtarget.hasFPExtension () && !IsSigned)
6875
+ return SDValue (); // Expand i64.
6876
+
6905
6877
if (InVT == MVT::i128 ) {
6906
6878
RTLIB::Libcall LC =
6907
6879
IsSigned ? RTLIB::getSINTTOFP (InVT, VT) : RTLIB::getUINTTOFP (InVT, VT);
@@ -7019,23 +6991,17 @@ SDValue SystemZTargetLowering::lowerIS_FPCLASS(SDValue Op,
7019
6991
7020
6992
SDValue SystemZTargetLowering::lowerFCOPYSIGN (SDValue Op,
7021
6993
SelectionDAG &DAG) const {
7022
- SDValue Op0 = Op.getOperand (0 );
7023
- SDValue Op1 = Op.getOperand (1 );
7024
- MVT Op0VT = Op0.getSimpleValueType ();
7025
- MVT Op1VT = Op1.getSimpleValueType ();
7026
- if (Op0VT != MVT::f16 && Op1VT != MVT::f16 )
7027
- return Op; // Legal
6994
+ MVT VT = Op.getSimpleValueType ();
6995
+ SDValue ValOp = Op.getOperand (0 );
6996
+ SDValue SignOp = Op.getOperand (1 );
7028
6997
7029
- // Perform the copy on to the largest type present, or f32 if it was f16.
7030
- MVT VT = (Op0VT.getSizeInBits () > Op1VT.getSizeInBits ()) ? Op0VT : Op1VT;
7031
- if (VT == MVT::f16 )
7032
- VT = MVT::f32 ;
6998
+ // Remove the rounding which would result in a libcall for half.
6999
+ if (VT == MVT::f16 && SignOp.getOpcode () == ISD::FP_ROUND) {
7000
+ SDValue WideOp = SignOp.getOperand (0 );
7001
+ return DAG.getNode (ISD::FCOPYSIGN, SDLoc (Op), VT, ValOp, WideOp);
7002
+ }
7033
7003
7034
- SDLoc DL (Op);
7035
- SDValue Op0Conv = DAG.getFPExtendOrRound (Op0, DL, VT);
7036
- SDValue Op1Conv = DAG.getFPExtendOrRound (Op1, DL, VT);
7037
- SDValue ResConv = DAG.getNode (ISD::FCOPYSIGN, DL, VT, {Op0Conv, Op1Conv});
7038
- return DAG.getFPExtendOrRound (ResConv, DL, Op0VT);
7004
+ return Op; // Legal
7039
7005
}
7040
7006
7041
7007
SDValue SystemZTargetLowering::lowerREADCYCLECOUNTER (SDValue Op,
@@ -7359,71 +7325,60 @@ SystemZTargetLowering::LowerOperationWrapper(SDNode *N,
7359
7325
}
7360
7326
break ;
7361
7327
}
7328
+ case ISD::UINT_TO_FP:
7362
7329
case ISD::SINT_TO_FP:
7363
- case ISD::UINT_TO_FP: {
7364
- if (useSoftFloat ())
7365
- return ;
7366
- SDLoc DL (N);
7367
- SDValue Src = N->getOperand (0 );
7368
- EVT ResVT = N->getValueType (0 );
7369
- if (ResVT == MVT::f16 ) {
7370
- SDValue F32Res = DAG.getNode (N->getOpcode (), DL, MVT::f32 , Src);
7371
- Results.push_back (DAG.getFPExtendOrRound (F32Res, DL, MVT::f16 ));
7372
- }
7373
- break ;
7374
- }
7375
- case ISD::STRICT_SINT_TO_FP:
7376
- case ISD::STRICT_UINT_TO_FP: {
7330
+ case ISD::STRICT_UINT_TO_FP:
7331
+ case ISD::STRICT_SINT_TO_FP: {
7377
7332
if (useSoftFloat ())
7378
7333
return ;
7334
+ bool IsStrict = N->isStrictFPOpcode ();
7379
7335
SDLoc DL (N);
7380
- SDValue Chain = N->getOperand (0 );
7381
- SDValue Src = N->getOperand (1 );
7336
+ SDValue InOp = N->getOperand (IsStrict ? 1 : 0 );
7382
7337
EVT ResVT = N->getValueType (0 );
7338
+ SDValue Chain = IsStrict ? N->getOperand (0 ) : DAG.getEntryNode ();
7383
7339
if (ResVT == MVT::f16 ) {
7384
- SDValue F32Res =
7385
- DAG.getNode (N->getOpcode (), DL, DAG.getVTList (MVT::f32 , MVT::Other),
7386
- {Chain, Src});
7387
- SDValue F16Res;
7388
- std::tie (F16Res, Chain) = DAG.getStrictFPExtendOrRound (
7389
- F32Res, F32Res.getValue (1 ), DL, MVT::f16 );
7390
- Results.push_back (F16Res);
7391
- Results.push_back (Chain);
7340
+ if (!IsStrict) {
7341
+ SDValue OpF32 = DAG.getNode (N->getOpcode (), DL, MVT::f32 , InOp);
7342
+ Results.push_back (DAG.getFPExtendOrRound (OpF32, DL, MVT::f16 ));
7343
+ } else {
7344
+ SDValue OpF32 =
7345
+ DAG.getNode (N->getOpcode (), DL, DAG.getVTList (MVT::f32 , MVT::Other),
7346
+ {Chain, InOp});
7347
+ SDValue F16Res;
7348
+ std::tie (F16Res, Chain) = DAG.getStrictFPExtendOrRound (
7349
+ OpF32, OpF32.getValue (1 ), DL, MVT::f16 );
7350
+ Results.push_back (F16Res);
7351
+ Results.push_back (Chain);
7352
+ }
7392
7353
}
7393
7354
break ;
7394
7355
}
7395
7356
case ISD::FP_TO_UINT:
7396
- case ISD::FP_TO_SINT: {
7397
- if (useSoftFloat ())
7398
- return ;
7399
- SDLoc DL (N);
7400
- SDValue Src = N->getOperand (0 );
7401
- EVT SrcVT = Src->getValueType (0 );
7402
- if (SrcVT == MVT::f16 ) {
7403
- SDValue SrcF32 = DAG.getFPExtendOrRound (Src, DL, MVT::f32 );
7404
- SDValue OpF32 =
7405
- DAG.getNode (N->getOpcode (), DL, N->getValueType (0 ), SrcF32);
7406
- Results.push_back (OpF32);
7407
- }
7408
- break ;
7409
- }
7357
+ case ISD::FP_TO_SINT:
7410
7358
case ISD::STRICT_FP_TO_UINT:
7411
7359
case ISD::STRICT_FP_TO_SINT: {
7412
7360
if (useSoftFloat ())
7413
7361
return ;
7362
+ bool IsStrict = N->isStrictFPOpcode ();
7414
7363
SDLoc DL (N);
7415
7364
EVT ResVT = N->getValueType (0 );
7416
- SDValue Chain = N->getOperand (0 );
7417
- SDValue Src = N->getOperand (1 );
7418
- EVT SrcVT = Src->getValueType (0 );
7419
- if (SrcVT == MVT::f16 ) {
7420
- SDValue InF32;
7421
- std::tie (InF32, Chain) =
7422
- DAG.getStrictFPExtendOrRound (Src, Chain, DL, MVT::f32 );
7423
- SDValue OpF32 = DAG.getNode (
7424
- N->getOpcode (), DL, DAG.getVTList (ResVT, MVT::Other), {Chain, InF32});
7425
- Results.push_back (OpF32);
7426
- Results.push_back (OpF32.getValue (1 ));
7365
+ SDValue InOp = N->getOperand (IsStrict ? 1 : 0 );
7366
+ EVT InVT = InOp->getValueType (0 );
7367
+ SDValue Chain = IsStrict ? N->getOperand (0 ) : DAG.getEntryNode ();
7368
+ if (InVT == MVT::f16 ) {
7369
+ if (!IsStrict) {
7370
+ SDValue InF32 = DAG.getFPExtendOrRound (InOp, DL, MVT::f32 );
7371
+ Results.push_back (DAG.getNode (N->getOpcode (), DL, ResVT, InF32));
7372
+ } else {
7373
+ SDValue InF32;
7374
+ std::tie (InF32, Chain) =
7375
+ DAG.getStrictFPExtendOrRound (InOp, Chain, DL, MVT::f32 );
7376
+ SDValue OpF32 =
7377
+ DAG.getNode (N->getOpcode (), DL, DAG.getVTList (ResVT, MVT::Other),
7378
+ {Chain, InF32});
7379
+ Results.push_back (OpF32);
7380
+ Results.push_back (OpF32.getValue (1 ));
7381
+ }
7427
7382
}
7428
7383
break ;
7429
7384
}
0 commit comments