@@ -6198,114 +6198,50 @@ bool TargetLowering::expandUINT_TO_FP(SDNode *Node, SDValue &Result,
61986198 EVT SrcVT = Src.getValueType ();
61996199 EVT DstVT = Node->getValueType (0 );
62006200
6201- if (SrcVT.getScalarType () != MVT::i64 )
6201+ if (SrcVT.getScalarType () != MVT::i64 || DstVT.getScalarType () != MVT::f64 )
6202+ return false ;
6203+
6204+ // Only expand vector types if we have the appropriate vector bit operations.
6205+ if (SrcVT.isVector () && (!isOperationLegalOrCustom (ISD::SRL, SrcVT) ||
6206+ !isOperationLegalOrCustom (ISD::FADD, DstVT) ||
6207+ !isOperationLegalOrCustom (ISD::FSUB, DstVT) ||
6208+ !isOperationLegalOrCustomOrPromote (ISD::OR, SrcVT) ||
6209+ !isOperationLegalOrCustomOrPromote (ISD::AND, SrcVT)))
62026210 return false ;
62036211
62046212 SDLoc dl (SDValue (Node, 0 ));
62056213 EVT ShiftVT = getShiftAmountTy (SrcVT, DAG.getDataLayout ());
62066214
6207- if (DstVT.getScalarType () == MVT::f32 ) {
6208- // Only expand vector types if we have the appropriate vector bit
6209- // operations.
6210- if (SrcVT.isVector () &&
6211- (!isOperationLegalOrCustom (ISD::SRL, SrcVT) ||
6212- !isOperationLegalOrCustom (ISD::FADD, DstVT) ||
6213- !isOperationLegalOrCustom (ISD::SINT_TO_FP, SrcVT) ||
6214- !isOperationLegalOrCustomOrPromote (ISD::OR, SrcVT) ||
6215- !isOperationLegalOrCustomOrPromote (ISD::AND, SrcVT)))
6216- return false ;
6217-
6218- // For unsigned conversions, convert them to signed conversions using the
6219- // algorithm from the x86_64 __floatundisf in compiler_rt.
6220-
6221- // TODO: This really should be implemented using a branch rather than a
6222- // select. We happen to get lucky and machinesink does the right
6223- // thing most of the time. This would be a good candidate for a
6224- // pseudo-op, or, even better, for whole-function isel.
6225- EVT SetCCVT =
6226- getSetCCResultType (DAG.getDataLayout (), *DAG.getContext (), SrcVT);
6227-
6228- SDValue SignBitTest = DAG.getSetCC (
6229- dl, SetCCVT, Src, DAG.getConstant (0 , dl, SrcVT), ISD::SETLT);
6230-
6231- SDValue ShiftConst = DAG.getConstant (1 , dl, ShiftVT);
6232- SDValue Shr = DAG.getNode (ISD::SRL, dl, SrcVT, Src, ShiftConst);
6233- SDValue AndConst = DAG.getConstant (1 , dl, SrcVT);
6234- SDValue And = DAG.getNode (ISD::AND, dl, SrcVT, Src, AndConst);
6235- SDValue Or = DAG.getNode (ISD::OR, dl, SrcVT, And, Shr);
6236-
6237- SDValue Slow, Fast;
6238- if (Node->isStrictFPOpcode ()) {
6239- // In strict mode, we must avoid spurious exceptions, and therefore
6240- // must make sure to only emit a single STRICT_SINT_TO_FP.
6241- SDValue InCvt = DAG.getSelect (dl, SrcVT, SignBitTest, Or, Src);
6242- Fast = DAG.getNode (ISD::STRICT_SINT_TO_FP, dl, { DstVT, MVT::Other },
6243- { Node->getOperand (0 ), InCvt });
6244- Slow = DAG.getNode (ISD::STRICT_FADD, dl, { DstVT, MVT::Other },
6245- { Fast.getValue (1 ), Fast, Fast });
6246- Chain = Slow.getValue (1 );
6247- // The STRICT_SINT_TO_FP inherits the exception mode from the
6248- // incoming STRICT_UINT_TO_FP node; the STRICT_FADD node can
6249- // never raise any exception.
6250- SDNodeFlags Flags;
6251- Flags.setNoFPExcept (Node->getFlags ().hasNoFPExcept ());
6252- Fast->setFlags (Flags);
6253- Flags.setNoFPExcept (true );
6254- Slow->setFlags (Flags);
6255- } else {
6256- SDValue SignCvt = DAG.getNode (ISD::SINT_TO_FP, dl, DstVT, Or);
6257- Slow = DAG.getNode (ISD::FADD, dl, DstVT, SignCvt, SignCvt);
6258- Fast = DAG.getNode (ISD::SINT_TO_FP, dl, DstVT, Src);
6259- }
6260-
6261- Result = DAG.getSelect (dl, DstVT, SignBitTest, Slow, Fast);
6262- return true ;
6263- }
6264-
6265- if (DstVT.getScalarType () == MVT::f64 ) {
6266- // Only expand vector types if we have the appropriate vector bit
6267- // operations.
6268- if (SrcVT.isVector () &&
6269- (!isOperationLegalOrCustom (ISD::SRL, SrcVT) ||
6270- !isOperationLegalOrCustom (ISD::FADD, DstVT) ||
6271- !isOperationLegalOrCustom (ISD::FSUB, DstVT) ||
6272- !isOperationLegalOrCustomOrPromote (ISD::OR, SrcVT) ||
6273- !isOperationLegalOrCustomOrPromote (ISD::AND, SrcVT)))
6274- return false ;
6275-
6276- // Implementation of unsigned i64 to f64 following the algorithm in
6277- // __floatundidf in compiler_rt. This implementation has the advantage
6278- // of performing rounding correctly, both in the default rounding mode
6279- // and in all alternate rounding modes.
6280- SDValue TwoP52 = DAG.getConstant (UINT64_C (0x4330000000000000 ), dl, SrcVT);
6281- SDValue TwoP84PlusTwoP52 = DAG.getConstantFP (
6282- BitsToDouble (UINT64_C (0x4530000000100000 )), dl, DstVT);
6283- SDValue TwoP84 = DAG.getConstant (UINT64_C (0x4530000000000000 ), dl, SrcVT);
6284- SDValue LoMask = DAG.getConstant (UINT64_C (0x00000000FFFFFFFF ), dl, SrcVT);
6285- SDValue HiShift = DAG.getConstant (32 , dl, ShiftVT);
6286-
6287- SDValue Lo = DAG.getNode (ISD::AND, dl, SrcVT, Src, LoMask);
6288- SDValue Hi = DAG.getNode (ISD::SRL, dl, SrcVT, Src, HiShift);
6289- SDValue LoOr = DAG.getNode (ISD::OR, dl, SrcVT, Lo, TwoP52);
6290- SDValue HiOr = DAG.getNode (ISD::OR, dl, SrcVT, Hi, TwoP84);
6291- SDValue LoFlt = DAG.getBitcast (DstVT, LoOr);
6292- SDValue HiFlt = DAG.getBitcast (DstVT, HiOr);
6293- if (Node->isStrictFPOpcode ()) {
6294- SDValue HiSub =
6295- DAG.getNode (ISD::STRICT_FSUB, dl, {DstVT, MVT::Other},
6296- {Node->getOperand (0 ), HiFlt, TwoP84PlusTwoP52});
6297- Result = DAG.getNode (ISD::STRICT_FADD, dl, {DstVT, MVT::Other},
6298- {HiSub.getValue (1 ), LoFlt, HiSub});
6299- Chain = Result.getValue (1 );
6300- } else {
6301- SDValue HiSub =
6302- DAG.getNode (ISD::FSUB, dl, DstVT, HiFlt, TwoP84PlusTwoP52);
6303- Result = DAG.getNode (ISD::FADD, dl, DstVT, LoFlt, HiSub);
6304- }
6305- return true ;
6215+ // Implementation of unsigned i64 to f64 following the algorithm in
6216+ // __floatundidf in compiler_rt. This implementation has the advantage
6217+ // of performing rounding correctly, both in the default rounding mode
6218+ // and in all alternate rounding modes.
6219+ SDValue TwoP52 = DAG.getConstant (UINT64_C (0x4330000000000000 ), dl, SrcVT);
6220+ SDValue TwoP84PlusTwoP52 = DAG.getConstantFP (
6221+ BitsToDouble (UINT64_C (0x4530000000100000 )), dl, DstVT);
6222+ SDValue TwoP84 = DAG.getConstant (UINT64_C (0x4530000000000000 ), dl, SrcVT);
6223+ SDValue LoMask = DAG.getConstant (UINT64_C (0x00000000FFFFFFFF ), dl, SrcVT);
6224+ SDValue HiShift = DAG.getConstant (32 , dl, ShiftVT);
6225+
6226+ SDValue Lo = DAG.getNode (ISD::AND, dl, SrcVT, Src, LoMask);
6227+ SDValue Hi = DAG.getNode (ISD::SRL, dl, SrcVT, Src, HiShift);
6228+ SDValue LoOr = DAG.getNode (ISD::OR, dl, SrcVT, Lo, TwoP52);
6229+ SDValue HiOr = DAG.getNode (ISD::OR, dl, SrcVT, Hi, TwoP84);
6230+ SDValue LoFlt = DAG.getBitcast (DstVT, LoOr);
6231+ SDValue HiFlt = DAG.getBitcast (DstVT, HiOr);
6232+ if (Node->isStrictFPOpcode ()) {
6233+ SDValue HiSub =
6234+ DAG.getNode (ISD::STRICT_FSUB, dl, {DstVT, MVT::Other},
6235+ {Node->getOperand (0 ), HiFlt, TwoP84PlusTwoP52});
6236+ Result = DAG.getNode (ISD::STRICT_FADD, dl, {DstVT, MVT::Other},
6237+ {HiSub.getValue (1 ), LoFlt, HiSub});
6238+ Chain = Result.getValue (1 );
6239+ } else {
6240+ SDValue HiSub =
6241+ DAG.getNode (ISD::FSUB, dl, DstVT, HiFlt, TwoP84PlusTwoP52);
6242+ Result = DAG.getNode (ISD::FADD, dl, DstVT, LoFlt, HiSub);
63066243 }
6307-
6308- return false ;
6244+ return true ;
63096245}
63106246
63116247SDValue TargetLowering::expandFMINNUM_FMAXNUM (SDNode *Node,
0 commit comments