@@ -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,60 @@ 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,
2382
+ FirstIndex) ||
2383
+ !GetConvertedLane (Op.getOperand (1 ), SecondOpcode, SecondSrcVec,
2384
+ SecondIndex))
2385
+ return SDValue ();
2386
+
2387
+ // If we're converting to v4f32, check the third and fourth lanes, too.
2388
+ if (NumLanes == 4 && (!GetConvertedLane (Op.getOperand (2 ), ThirdOpcode,
2389
+ ThirdSrcVec, ThirdIndex) ||
2390
+ !GetConvertedLane (Op.getOperand (3 ), FourthOpcode,
2391
+ FourthSrcVec, FourthIndex)))
2392
+ return SDValue ();
2393
+
2394
+ if (FirstOpcode != SecondOpcode)
2379
2395
return SDValue ();
2380
2396
2381
- if (LHSOpcode != RHSOpcode)
2397
+ // TODO Add an optimization similar to the v2f64 below for shuffling the
2398
+ // vectors when the lanes are in the wrong order or come from different src
2399
+ // vectors.
2400
+ if (NumLanes == 4 &&
2401
+ (FirstOpcode != ThirdOpcode || FirstOpcode != FourthOpcode ||
2402
+ FirstSrcVec != SecondSrcVec || FirstSrcVec != ThirdSrcVec ||
2403
+ FirstSrcVec != FourthSrcVec || FirstIndex != 0 || SecondIndex != 1 ||
2404
+ ThirdIndex != 2 || FourthIndex != 3 ))
2382
2405
return SDValue ();
2383
2406
2384
2407
MVT ExpectedSrcVT;
2385
- switch (LHSOpcode ) {
2408
+ switch (FirstOpcode ) {
2386
2409
case WebAssemblyISD::CONVERT_LOW_S:
2387
2410
case WebAssemblyISD::CONVERT_LOW_U:
2388
2411
ExpectedSrcVT = MVT::v4i32;
2389
2412
break ;
2390
2413
case WebAssemblyISD::PROMOTE_LOW:
2391
- ExpectedSrcVT = MVT::v4f32;
2414
+ ExpectedSrcVT = NumLanes == 2 ? MVT::v4f32 : MVT::v8i16 ;
2392
2415
break ;
2393
2416
}
2394
- if (LHSSrcVec .getValueType () != ExpectedSrcVT)
2417
+ if (FirstSrcVec .getValueType () != ExpectedSrcVT)
2395
2418
return SDValue ();
2396
2419
2397
- auto Src = LHSSrcVec;
2398
- if (LHSIndex != 0 || RHSIndex != 1 || LHSSrcVec != RHSSrcVec) {
2420
+ auto Src = FirstSrcVec;
2421
+ if (NumLanes == 2 &&
2422
+ (FirstIndex != 0 || SecondIndex != 1 || FirstSrcVec != SecondSrcVec)) {
2399
2423
// Shuffle the source vector so that the converted lanes are the low lanes.
2400
- Src = DAG.getVectorShuffle (
2401
- ExpectedSrcVT, DL, LHSSrcVec, RHSSrcVec ,
2402
- { static_cast < int >(LHSIndex), static_cast <int >(RHSIndex ) + 4 , -1 , -1 });
2424
+ Src = DAG.getVectorShuffle (ExpectedSrcVT, DL, FirstSrcVec, SecondSrcVec,
2425
+ { static_cast < int >(FirstIndex) ,
2426
+ static_cast <int >(SecondIndex ) + 4 , -1 , -1 });
2403
2427
}
2404
- return DAG.getNode (LHSOpcode, DL, MVT::v2f64, Src);
2428
+ return DAG.getNode (FirstOpcode, DL, NumLanes == 2 ? MVT::v2f64 : MVT::v4f32,
2429
+ Src);
2405
2430
}
2406
2431
2407
2432
SDValue WebAssemblyTargetLowering::LowerBUILD_VECTOR (SDValue Op,
0 commit comments