@@ -2627,7 +2627,12 @@ LoongArchTargetLowering::lowerEXTRACT_VECTOR_ELT(SDValue Op,
2627
2627
llvm_unreachable (" Unexpected type" );
2628
2628
case MVT::v32i8:
2629
2629
case MVT::v16i16: {
2630
+ // Consider the source vector as v8i32 type.
2630
2631
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.
2631
2636
SDValue NewIdx = DAG.getNode (
2632
2637
LoongArchISD::BSTRPICK, DL, GRLenVT, Idx,
2633
2638
DAG.getConstant (31 , DL, GRLenVT),
@@ -2637,6 +2642,9 @@ LoongArchTargetLowering::lowerEXTRACT_VECTOR_ELT(SDValue Op,
2637
2642
DAG.getNode (LoongArchISD::XVPERM, DL, MVT::v8i32, NewVec, SplatIdx);
2638
2643
SDValue SplatVec = DAG.getBitcast (VecTy, SplatValue);
2639
2644
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.
2640
2648
SDValue LocalIdx = DAG.getNode (
2641
2649
ISD::AND, DL, GRLenVT, Idx,
2642
2650
DAG.getConstant (((VecTy == MVT::v32i8) ? 3 : 1 ), DL, GRLenVT));
@@ -2657,7 +2665,11 @@ LoongArchTargetLowering::lowerEXTRACT_VECTOR_ELT(SDValue Op,
2657
2665
}
2658
2666
case MVT::v4i64:
2659
2667
case MVT::v4f64: {
2668
+ // Consider the source vector as v8i32 type.
2660
2669
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.
2661
2673
SDValue SplatIdx = DAG.getSplatBuildVector (MVT::v8i32, DL, Idx);
2662
2674
SDValue SplatIdxLo =
2663
2675
DAG.getNode (LoongArchISD::VSLLI, DL, MVT::v8i32, SplatIdx,
@@ -2667,10 +2679,15 @@ LoongArchTargetLowering::lowerEXTRACT_VECTOR_ELT(SDValue Op,
2667
2679
DAG.getSplatBuildVector (MVT::v8i32, DL,
2668
2680
DAG.getConstant (1 , DL, GRLenVT)));
2669
2681
2682
+ // Use the broadcasted index to broadcast the low and high parts of the
2683
+ // vector separately.
2670
2684
SDValue SplatVecLo =
2671
2685
DAG.getNode (LoongArchISD::XVPERM, DL, MVT::v8i32, NewVec, SplatIdxLo);
2672
2686
SDValue SplatVecHi =
2673
2687
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.
2674
2691
SDValue SplatValue = DAG.getNode (LoongArchISD::VILVL, DL, MVT::v8i32,
2675
2692
SplatVecHi, SplatVecLo);
2676
2693
SDValue ExtractVec = DAG.getBitcast (VecTy, SplatValue);
0 commit comments