[llvm] [LoongArch] Custom legalize vector_shuffle to `xvextrins` (PR #164375)

via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 17 03:15:58 PDT 2026


================
@@ -2523,6 +2523,82 @@ static SDValue lowerVECTOR_SHUFFLE_XVPICKOD(const SDLoc &DL, ArrayRef<int> Mask,
   return DAG.getNode(LoongArchISD::VPICKOD, DL, VT, V2, V1);
 }
 
+/// Lower VECTOR_SHUFFLE into XVEXTRINS (if possible).
+static SDValue
+lowerVECTOR_SHUFFLE_XVEXTRINS(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
+                              SDValue V1, SDValue V2, SelectionDAG &DAG,
+                              const LoongArchSubtarget &Subtarget) {
+  int NumElts = VT.getVectorNumElements();
+  MVT EltVT = VT.getVectorElementType();
+  MVT GRLenVT = Subtarget.getGRLenVT();
+
+  if ((int)Mask.size() != NumElts)
+    return SDValue();
+
+  auto tryLowerToExtrAndIns = [&](int Base) -> SDValue {
+    SmallVector<int> DiffPos;
+    for (int i = 0; i < NumElts; ++i) {
+      if (Mask[i] == -1)
+        continue;
+      if (Mask[i] != Base + i) {
+        DiffPos.push_back(i);
+        if (DiffPos.size() > 2)
+          return SDValue();
+      }
+    }
+
+    // Need exactly two differing element to lower into XVEXTRINS.
+    if (DiffPos.size() != 2 || DiffPos[1] != DiffPos[0] + NumElts / 2)
+      return SDValue();
+
+    // DiffMask must be in its low or high part.
+    int DiffMaskLo = Mask[DiffPos[0]];
+    int DiffMaskHi = Mask[DiffPos[1]];
+    if (!(DiffMaskLo >= 0 && DiffMaskLo < NumElts / 2) &&
+        !(DiffMaskLo >= NumElts && DiffMaskLo < NumElts + NumElts / 2))
+      return SDValue();
+    if (!(DiffMaskHi >= NumElts / 2 && DiffMaskHi < NumElts) &&
+        !(DiffMaskHi >= NumElts + NumElts / 2 && DiffMaskHi < 2 * NumElts))
+      return SDValue();
+    if (DiffMaskHi != DiffMaskLo + NumElts / 2)
+      return SDValue();
+
+    // Determine source vector and source index.
+    SDValue SrcVec = (DiffMaskLo < NumElts / 2) ? V1 : V2;
+    int SrcIdxLo =
+        (DiffMaskLo < NumElts / 2) ? DiffMaskLo : (DiffMaskLo - NumElts);
+    bool IsEltFP = EltVT.isFloatingPoint();
+
+    auto extractVal = [&](int Idx) -> SDValue {
+      SDValue Extracted =
+          DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, IsEltFP ? EltVT : GRLenVT,
+                      SrcVec, DAG.getConstant(Idx, DL, GRLenVT));
+      SDValue InsertVal = Extracted;
+      if (!IsEltFP && EltVT != GRLenVT)
+        InsertVal =
+            DAG.getNode(ISD::ANY_EXTEND, DL, GRLenVT,
+                        DAG.getNode(ISD::TRUNCATE, DL, EltVT, Extracted));
----------------
zhaoqi5 wrote:

Removed. Thanks.

https://github.com/llvm/llvm-project/pull/164375


More information about the llvm-commits mailing list