@@ -2341,7 +2341,7 @@ WebAssemblyTargetLowering::LowerEXTEND_VECTOR_INREG(SDValue Op,
2341
2341
2342
2342
static SDValue LowerConvertLow (SDValue Op, SelectionDAG &DAG) {
2343
2343
SDLoc DL (Op);
2344
- if (Op.getValueType () != MVT::v2f64)
2344
+ if (Op.getValueType () != MVT::v2f64 && Op. getValueType () != MVT::v4f32 )
2345
2345
return SDValue ();
2346
2346
2347
2347
auto GetConvertedLane = [](SDValue Op, unsigned &Opcode, SDValue &SrcVec,
@@ -2354,6 +2354,7 @@ static SDValue LowerConvertLow(SDValue Op, SelectionDAG &DAG) {
2354
2354
Opcode = WebAssemblyISD::CONVERT_LOW_U;
2355
2355
break ;
2356
2356
case ISD::FP_EXTEND:
2357
+ case ISD::FP16_TO_FP:
2357
2358
Opcode = WebAssemblyISD::PROMOTE_LOW;
2358
2359
break ;
2359
2360
default :
@@ -2372,36 +2373,52 @@ static SDValue LowerConvertLow(SDValue Op, SelectionDAG &DAG) {
2372
2373
return true ;
2373
2374
};
2374
2375
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)
2379
2391
return SDValue ();
2380
2392
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 ))
2382
2399
return SDValue ();
2383
2400
2384
2401
MVT ExpectedSrcVT;
2385
- switch (LHSOpcode ) {
2402
+ switch (FirstOpcode ) {
2386
2403
case WebAssemblyISD::CONVERT_LOW_S:
2387
2404
case WebAssemblyISD::CONVERT_LOW_U:
2388
2405
ExpectedSrcVT = MVT::v4i32;
2389
2406
break ;
2390
2407
case WebAssemblyISD::PROMOTE_LOW:
2391
- ExpectedSrcVT = MVT::v4f32;
2408
+ ExpectedSrcVT = NumLanes == 2 ? MVT::v4f32 : MVT::v8i16 ;
2392
2409
break ;
2393
2410
}
2394
- if (LHSSrcVec .getValueType () != ExpectedSrcVT)
2411
+ if (FirstSrcVec .getValueType () != ExpectedSrcVT)
2395
2412
return SDValue ();
2396
2413
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) ) {
2399
2416
// Shuffle the source vector so that the converted lanes are the low lanes.
2400
2417
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 });
2403
2420
}
2404
- return DAG.getNode (LHSOpcode , DL, MVT::v2f64, Src);
2421
+ return DAG.getNode (FirstOpcode , DL, NumLanes == 2 ? MVT::v2f64 : MVT::v4f32 , Src);
2405
2422
}
2406
2423
2407
2424
SDValue WebAssemblyTargetLowering::LowerBUILD_VECTOR (SDValue Op,
0 commit comments