@@ -2627,7 +2627,12 @@ LoongArchTargetLowering::lowerEXTRACT_VECTOR_ELT(SDValue Op,
26272627 llvm_unreachable (" Unexpected type" );
26282628 case MVT::v32i8:
26292629 case MVT::v16i16: {
2630+ // Consider the source vector as v8i32 type.
26302631 SDValue NewVec = DAG.getBitcast (MVT::v8i32, Vec);
2632+
2633+ // Compute the adjusted index and use it to broadcast the vector.
2634+ // The original desired i8/i16 element is now replicated in each
2635+ // i32 lane of the splatted vector.
26312636 SDValue NewIdx = DAG.getNode (
26322637 LoongArchISD::BSTRPICK, DL, GRLenVT, Idx,
26332638 DAG.getConstant (31 , DL, GRLenVT),
@@ -2637,6 +2642,9 @@ LoongArchTargetLowering::lowerEXTRACT_VECTOR_ELT(SDValue Op,
26372642 DAG.getNode (LoongArchISD::XVPERM, DL, MVT::v8i32, NewVec, SplatIdx);
26382643 SDValue SplatVec = DAG.getBitcast (VecTy, SplatValue);
26392644
2645+ // Compute the local index of the original i8/i16 element within the
2646+ // i32 element and then use it to broadcast the vector. Each elements
2647+ // of the vector will be the desired element.
26402648 SDValue LocalIdx = DAG.getNode (
26412649 ISD::AND, DL, GRLenVT, Idx,
26422650 DAG.getConstant (((VecTy == MVT::v32i8) ? 3 : 1 ), DL, GRLenVT));
@@ -2657,7 +2665,11 @@ LoongArchTargetLowering::lowerEXTRACT_VECTOR_ELT(SDValue Op,
26572665 }
26582666 case MVT::v4i64:
26592667 case MVT::v4f64: {
2668+ // Consider the source vector as v8i32 type.
26602669 SDValue NewVec = DAG.getBitcast (MVT::v8i32, Vec);
2670+
2671+ // Split the original element index into low and high parts:
2672+ // Lo = Idx * 2, Hi = Idx * 2 + 1.
26612673 SDValue SplatIdx = DAG.getSplatBuildVector (MVT::v8i32, DL, Idx);
26622674 SDValue SplatIdxLo =
26632675 DAG.getNode (LoongArchISD::VSLLI, DL, MVT::v8i32, SplatIdx,
@@ -2667,10 +2679,15 @@ LoongArchTargetLowering::lowerEXTRACT_VECTOR_ELT(SDValue Op,
26672679 DAG.getSplatBuildVector (MVT::v8i32, DL,
26682680 DAG.getConstant (1 , DL, GRLenVT)));
26692681
2682+ // Use the broadcasted index to broadcast the low and high parts of the
2683+ // vector separately.
26702684 SDValue SplatVecLo =
26712685 DAG.getNode (LoongArchISD::XVPERM, DL, MVT::v8i32, NewVec, SplatIdxLo);
26722686 SDValue SplatVecHi =
26732687 DAG.getNode (LoongArchISD::XVPERM, DL, MVT::v8i32, NewVec, SplatIdxHi);
2688+
2689+ // Combine the low and high i32 parts to reconstruct the original i64/f64
2690+ // element.
26742691 SDValue SplatValue = DAG.getNode (LoongArchISD::VILVL, DL, MVT::v8i32,
26752692 SplatVecHi, SplatVecLo);
26762693 SDValue ExtractVec = DAG.getBitcast (VecTy, SplatValue);
0 commit comments