@@ -173,10 +173,9 @@ class SelectionDAGLegalize {
173
173
SDValue NewIntValue) const ;
174
174
SDValue ExpandFCOPYSIGN (SDNode *Node) const ;
175
175
SDValue ExpandFABS (SDNode *Node) const ;
176
- SDValue ExpandLegalINT_TO_FP (bool isSigned, SDValue Op0, EVT DestVT,
177
- const SDLoc &dl);
178
- SDValue PromoteLegalINT_TO_FP (SDValue LegalOp, EVT DestVT, bool isSigned,
179
- const SDLoc &dl);
176
+ SDValue ExpandLegalINT_TO_FP (SDNode *Node, SDValue &Chain);
177
+ void PromoteLegalINT_TO_FP (SDNode *N, const SDLoc &dl,
178
+ SmallVectorImpl<SDValue> &Results);
180
179
void PromoteLegalFP_TO_INT (SDNode *N, const SDLoc &dl,
181
180
SmallVectorImpl<SDValue> &Results);
182
181
@@ -1010,6 +1009,8 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {
1010
1009
Action = TLI.getOperationAction (Node->getOpcode (),
1011
1010
Node->getOperand (0 ).getValueType ());
1012
1011
break ;
1012
+ case ISD::STRICT_SINT_TO_FP:
1013
+ case ISD::STRICT_UINT_TO_FP:
1013
1014
case ISD::STRICT_LRINT:
1014
1015
case ISD::STRICT_LLRINT:
1015
1016
case ISD::STRICT_LROUND:
@@ -2338,9 +2339,14 @@ SelectionDAGLegalize::ExpandSinCosLibCall(SDNode *Node,
2338
2339
// / INT_TO_FP operation of the specified operand when the target requests that
2339
2340
// / we expand it. At this point, we know that the result and operand types are
2340
2341
// / legal for the target.
2341
- SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP (bool isSigned, SDValue Op0,
2342
- EVT DestVT,
2343
- const SDLoc &dl) {
2342
+ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP (SDNode *Node,
2343
+ SDValue &Chain) {
2344
+ bool isSigned = (Node->getOpcode () == ISD::STRICT_SINT_TO_FP ||
2345
+ Node->getOpcode () == ISD::SINT_TO_FP);
2346
+ EVT DestVT = Node->getValueType (0 );
2347
+ SDLoc dl (Node);
2348
+ unsigned OpNo = Node->isStrictFPOpcode () ? 1 : 0 ;
2349
+ SDValue Op0 = Node->getOperand (OpNo);
2344
2350
EVT SrcVT = Op0.getValueType ();
2345
2351
2346
2352
// TODO: Should any fast-math-flags be set for the created nodes?
@@ -2387,16 +2393,38 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned, SDValue Op0,
2387
2393
BitsToDouble (0x4330000080000000ULL ) :
2388
2394
BitsToDouble (0x4330000000000000ULL ),
2389
2395
dl, MVT::f64 );
2390
- // subtract the bias
2391
- SDValue Sub = DAG.getNode (ISD::FSUB, dl, MVT::f64 , Load, Bias);
2392
- // final result
2393
- SDValue Result = DAG.getFPExtendOrRound (Sub, dl, DestVT);
2396
+ // Subtract the bias and get the final result.
2397
+ SDValue Sub;
2398
+ SDValue Result;
2399
+ if (Node->isStrictFPOpcode ()) {
2400
+ Sub = DAG.getNode (ISD::STRICT_FSUB, dl, {MVT::f64 , MVT::Other},
2401
+ {Node->getOperand (0 ), Load, Bias});
2402
+ if (DestVT != Sub.getValueType ()) {
2403
+ std::pair<SDValue, SDValue> ResultPair;
2404
+ ResultPair =
2405
+ DAG.getStrictFPExtendOrRound (Sub, SDValue (Node, 1 ), dl, DestVT);
2406
+ Result = ResultPair.first ;
2407
+ Chain = ResultPair.second ;
2408
+ }
2409
+ else
2410
+ Result = Sub;
2411
+ } else {
2412
+ Sub = DAG.getNode (ISD::FSUB, dl, MVT::f64 , Load, Bias);
2413
+ Result = DAG.getFPExtendOrRound (Sub, dl, DestVT);
2414
+ }
2394
2415
return Result;
2395
2416
}
2396
2417
assert (!isSigned && " Legalize cannot Expand SINT_TO_FP for i64 yet" );
2397
2418
// Code below here assumes !isSigned without checking again.
2419
+ // FIXME: This can produce slightly incorrect results. See details in
2420
+ // FIXME: https://reviews.llvm.org/D69275
2398
2421
2399
- SDValue Tmp1 = DAG.getNode (ISD::SINT_TO_FP, dl, DestVT, Op0);
2422
+ SDValue Tmp1;
2423
+ if (Node->isStrictFPOpcode ()) {
2424
+ Tmp1 = DAG.getNode (ISD::STRICT_SINT_TO_FP, dl, { DestVT, MVT::Other },
2425
+ { Node->getOperand (0 ), Op0 });
2426
+ } else
2427
+ Tmp1 = DAG.getNode (ISD::SINT_TO_FP, dl, DestVT, Op0);
2400
2428
2401
2429
SDValue SignSet = DAG.getSetCC (dl, getSetCCResultType (SrcVT), Op0,
2402
2430
DAG.getConstant (0 , dl, SrcVT), ISD::SETLT);
@@ -2442,6 +2470,13 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned, SDValue Op0,
2442
2470
FudgeInReg = Handle.getValue ();
2443
2471
}
2444
2472
2473
+ if (Node->isStrictFPOpcode ()) {
2474
+ SDValue Result = DAG.getNode (ISD::STRICT_FADD, dl, { DestVT, MVT::Other },
2475
+ { Tmp1.getValue (1 ), Tmp1, FudgeInReg });
2476
+ Chain = Result.getValue (1 );
2477
+ return Result;
2478
+ }
2479
+
2445
2480
return DAG.getNode (ISD::FADD, dl, DestVT, Tmp1, FudgeInReg);
2446
2481
}
2447
2482
@@ -2450,9 +2485,16 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned, SDValue Op0,
2450
2485
// / we promote it. At this point, we know that the result and operand types are
2451
2486
// / legal for the target, and that there is a legal UINT_TO_FP or SINT_TO_FP
2452
2487
// / operation that takes a larger input.
2453
- SDValue SelectionDAGLegalize::PromoteLegalINT_TO_FP (SDValue LegalOp, EVT DestVT,
2454
- bool isSigned,
2455
- const SDLoc &dl) {
2488
+ void SelectionDAGLegalize::PromoteLegalINT_TO_FP (
2489
+ SDNode *N, const SDLoc &dl, SmallVectorImpl<SDValue> &Results) {
2490
+ bool IsStrict = N->isStrictFPOpcode ();
2491
+ bool IsSigned = N->getOpcode () == ISD::SINT_TO_FP ||
2492
+ N->getOpcode () == ISD::STRICT_SINT_TO_FP;
2493
+ EVT DestVT = N->getValueType (0 );
2494
+ SDValue LegalOp = N->getOperand (IsStrict ? 1 : 0 );
2495
+ unsigned UIntOp = IsStrict ? ISD::STRICT_UINT_TO_FP : ISD::UINT_TO_FP;
2496
+ unsigned SIntOp = IsStrict ? ISD::STRICT_SINT_TO_FP : ISD::SINT_TO_FP;
2497
+
2456
2498
// First step, figure out the appropriate *INT_TO_FP operation to use.
2457
2499
EVT NewInTy = LegalOp.getValueType ();
2458
2500
@@ -2464,15 +2506,16 @@ SDValue SelectionDAGLegalize::PromoteLegalINT_TO_FP(SDValue LegalOp, EVT DestVT,
2464
2506
assert (NewInTy.isInteger () && " Ran out of possibilities!" );
2465
2507
2466
2508
// If the target supports SINT_TO_FP of this type, use it.
2467
- if (TLI.isOperationLegalOrCustom (ISD::SINT_TO_FP , NewInTy)) {
2468
- OpToUse = ISD::SINT_TO_FP ;
2509
+ if (TLI.isOperationLegalOrCustom (SIntOp , NewInTy)) {
2510
+ OpToUse = SIntOp ;
2469
2511
break ;
2470
2512
}
2471
- if (isSigned) continue ;
2513
+ if (IsSigned)
2514
+ continue ;
2472
2515
2473
2516
// If the target supports UINT_TO_FP of this type, use it.
2474
- if (TLI.isOperationLegalOrCustom (ISD::UINT_TO_FP , NewInTy)) {
2475
- OpToUse = ISD::UINT_TO_FP ;
2517
+ if (TLI.isOperationLegalOrCustom (UIntOp , NewInTy)) {
2518
+ OpToUse = UIntOp ;
2476
2519
break ;
2477
2520
}
2478
2521
@@ -2481,9 +2524,20 @@ SDValue SelectionDAGLegalize::PromoteLegalINT_TO_FP(SDValue LegalOp, EVT DestVT,
2481
2524
2482
2525
// Okay, we found the operation and type to use. Zero extend our input to the
2483
2526
// desired type then run the operation on it.
2484
- return DAG.getNode (OpToUse, dl, DestVT,
2485
- DAG.getNode (isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND,
2486
- dl, NewInTy, LegalOp));
2527
+ if (IsStrict) {
2528
+ SDValue Res =
2529
+ DAG.getNode (OpToUse, dl, {DestVT, MVT::Other},
2530
+ {N->getOperand (0 ),
2531
+ DAG.getNode (IsSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND,
2532
+ dl, NewInTy, LegalOp)});
2533
+ Results.push_back (Res);
2534
+ Results.push_back (Res.getValue (1 ));
2535
+ }
2536
+
2537
+ Results.push_back (
2538
+ DAG.getNode (OpToUse, dl, DestVT,
2539
+ DAG.getNode (IsSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND,
2540
+ dl, NewInTy, LegalOp)));
2487
2541
}
2488
2542
2489
2543
// / This function is responsible for legalizing a
@@ -2899,15 +2953,20 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
2899
2953
break ;
2900
2954
}
2901
2955
case ISD::UINT_TO_FP:
2902
- if (TLI.expandUINT_TO_FP (Node, Tmp1, DAG)) {
2956
+ case ISD::STRICT_UINT_TO_FP:
2957
+ if (TLI.expandUINT_TO_FP (Node, Tmp1, Tmp2, DAG)) {
2903
2958
Results.push_back (Tmp1);
2959
+ if (Node->isStrictFPOpcode ())
2960
+ Results.push_back (Tmp2);
2904
2961
break ;
2905
2962
}
2906
2963
LLVM_FALLTHROUGH;
2907
2964
case ISD::SINT_TO_FP:
2908
- Tmp1 = ExpandLegalINT_TO_FP (Node-> getOpcode () == ISD::SINT_TO_FP,
2909
- Node-> getOperand ( 0 ), Node-> getValueType ( 0 ), dl );
2965
+ case ISD::STRICT_SINT_TO_FP:
2966
+ Tmp1 = ExpandLegalINT_TO_FP ( Node, Tmp2 );
2910
2967
Results.push_back (Tmp1);
2968
+ if (Node->isStrictFPOpcode ())
2969
+ Results.push_back (Tmp2);
2911
2970
break ;
2912
2971
case ISD::FP_TO_SINT:
2913
2972
if (TLI.expandFP_TO_SINT (Node, Tmp1, DAG))
@@ -4194,6 +4253,9 @@ void SelectionDAGLegalize::PromoteNode(SDNode *Node) {
4194
4253
Node->getOpcode () == ISD::INSERT_VECTOR_ELT) {
4195
4254
OVT = Node->getOperand (0 ).getSimpleValueType ();
4196
4255
}
4256
+ if (Node->getOpcode () == ISD::STRICT_UINT_TO_FP ||
4257
+ Node->getOpcode () == ISD::STRICT_SINT_TO_FP)
4258
+ OVT = Node->getOperand (1 ).getSimpleValueType ();
4197
4259
if (Node->getOpcode () == ISD::BR_CC)
4198
4260
OVT = Node->getOperand (2 ).getSimpleValueType ();
4199
4261
MVT NVT = TLI.getTypeToPromoteTo (Node->getOpcode (), OVT);
@@ -4248,10 +4310,10 @@ void SelectionDAGLegalize::PromoteNode(SDNode *Node) {
4248
4310
PromoteLegalFP_TO_INT (Node, dl, Results);
4249
4311
break ;
4250
4312
case ISD::UINT_TO_FP:
4313
+ case ISD::STRICT_UINT_TO_FP:
4251
4314
case ISD::SINT_TO_FP:
4252
- Tmp1 = PromoteLegalINT_TO_FP (Node->getOperand (0 ), Node->getValueType (0 ),
4253
- Node->getOpcode () == ISD::SINT_TO_FP, dl);
4254
- Results.push_back (Tmp1);
4315
+ case ISD::STRICT_SINT_TO_FP:
4316
+ PromoteLegalINT_TO_FP (Node, dl, Results);
4255
4317
break ;
4256
4318
case ISD::VAARG: {
4257
4319
SDValue Chain = Node->getOperand (0 ); // Get the chain.
0 commit comments