@@ -2341,7 +2341,7 @@ WebAssemblyTargetLowering::LowerEXTEND_VECTOR_INREG(SDValue Op,
23412341
23422342static SDValue LowerConvertLow (SDValue Op, SelectionDAG &DAG) {
23432343 SDLoc DL (Op);
2344- if (Op.getValueType () != MVT::v2f64)
2344+ if (Op.getValueType () != MVT::v2f64 && Op. getValueType () != MVT::v4f32 )
23452345 return SDValue ();
23462346
23472347 auto GetConvertedLane = [](SDValue Op, unsigned &Opcode, SDValue &SrcVec,
@@ -2354,6 +2354,7 @@ static SDValue LowerConvertLow(SDValue Op, SelectionDAG &DAG) {
23542354 Opcode = WebAssemblyISD::CONVERT_LOW_U;
23552355 break ;
23562356 case ISD::FP_EXTEND:
2357+ case ISD::FP16_TO_FP:
23572358 Opcode = WebAssemblyISD::PROMOTE_LOW;
23582359 break ;
23592360 default :
@@ -2372,36 +2373,52 @@ static SDValue LowerConvertLow(SDValue Op, SelectionDAG &DAG) {
23722373 return true ;
23732374 };
23742375
2375- unsigned LHSOpcode, RHSOpcode, LHSIndex, RHSIndex;
2376- SDValue LHSSrcVec, RHSSrcVec;
2377- if (!GetConvertedLane (Op.getOperand (0 ), LHSOpcode, LHSSrcVec, LHSIndex) ||
2378- !GetConvertedLane (Op.getOperand (1 ), RHSOpcode, RHSSrcVec, RHSIndex))
2376+ unsigned NumLanes = Op.getValueType () == MVT::v2f64 ? 2 : 4 ;
2377+ unsigned FirstOpcode = 0 , SecondOpcode = 0 , ThirdOpcode = 0 , FourthOpcode = 0 ;
2378+ unsigned FirstIndex = 0 , SecondIndex = 0 , ThirdIndex = 0 , FourthIndex = 0 ;
2379+ SDValue FirstSrcVec, SecondSrcVec, ThirdSrcVec, FourthSrcVec;
2380+
2381+ if (!GetConvertedLane (Op.getOperand (0 ), FirstOpcode, FirstSrcVec, FirstIndex) ||
2382+ !GetConvertedLane (Op.getOperand (1 ), SecondOpcode, SecondSrcVec, SecondIndex))
2383+ return SDValue ();
2384+
2385+ // If we're converting to v4f32, check the third and fourth lanes, too.
2386+ if (NumLanes == 4 && (!GetConvertedLane (Op.getOperand (2 ), ThirdOpcode, ThirdSrcVec, ThirdIndex) ||
2387+ !GetConvertedLane (Op.getOperand (3 ), FourthOpcode, FourthSrcVec, FourthIndex)))
2388+ return SDValue ();
2389+
2390+ if (FirstOpcode != SecondOpcode)
23792391 return SDValue ();
23802392
2381- if (LHSOpcode != RHSOpcode)
2393+ // TODO Add an optimization similar to the v2f64 below for shuffling the
2394+ // vectors when the lanes are in the wrong order or come from different src
2395+ // vectors.
2396+ if (NumLanes == 4 && (FirstOpcode != ThirdOpcode || FirstOpcode != FourthOpcode ||
2397+ FirstSrcVec != SecondSrcVec || FirstSrcVec != ThirdSrcVec || FirstSrcVec != FourthSrcVec ||
2398+ FirstIndex != 0 || SecondIndex != 1 || ThirdIndex != 2 || FourthIndex != 3 ))
23822399 return SDValue ();
23832400
23842401 MVT ExpectedSrcVT;
2385- switch (LHSOpcode ) {
2402+ switch (FirstOpcode ) {
23862403 case WebAssemblyISD::CONVERT_LOW_S:
23872404 case WebAssemblyISD::CONVERT_LOW_U:
23882405 ExpectedSrcVT = MVT::v4i32;
23892406 break ;
23902407 case WebAssemblyISD::PROMOTE_LOW:
2391- ExpectedSrcVT = MVT::v4f32;
2408+ ExpectedSrcVT = NumLanes == 2 ? MVT::v4f32 : MVT::v8i16 ;
23922409 break ;
23932410 }
2394- if (LHSSrcVec .getValueType () != ExpectedSrcVT)
2411+ if (FirstSrcVec .getValueType () != ExpectedSrcVT)
23952412 return SDValue ();
23962413
2397- auto Src = LHSSrcVec ;
2398- if (LHSIndex != 0 || RHSIndex != 1 || LHSSrcVec != RHSSrcVec ) {
2414+ auto Src = FirstSrcVec ;
2415+ if (NumLanes == 2 && (FirstIndex != 0 || SecondIndex != 1 || FirstSrcVec != SecondSrcVec) ) {
23992416 // Shuffle the source vector so that the converted lanes are the low lanes.
24002417 Src = DAG.getVectorShuffle (
2401- ExpectedSrcVT, DL, LHSSrcVec, RHSSrcVec ,
2402- {static_cast <int >(LHSIndex ), static_cast <int >(RHSIndex ) + 4 , -1 , -1 });
2418+ ExpectedSrcVT, DL, FirstSrcVec, SecondSrcVec ,
2419+ {static_cast <int >(FirstIndex ), static_cast <int >(SecondIndex ) + 4 , -1 , -1 });
24032420 }
2404- return DAG.getNode (LHSOpcode , DL, MVT::v2f64, Src);
2421+ return DAG.getNode (FirstOpcode , DL, NumLanes == 2 ? MVT::v2f64 : MVT::v4f32 , Src);
24052422}
24062423
24072424SDValue WebAssemblyTargetLowering::LowerBUILD_VECTOR (SDValue Op,
0 commit comments