[llvm] [LoongArch] Try to widen shuffle mask (PR #136081)

via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 17 00:22:07 PDT 2025


https://github.com/tangaac updated https://github.com/llvm/llvm-project/pull/136081

>From ba35038b17e61395acf8c1da3227e77a67aa4d6f Mon Sep 17 00:00:00 2001
From: tangaac <tangyan01 at loongson.cn>
Date: Thu, 17 Apr 2025 12:43:10 +0800
Subject: [PATCH 1/2] Try to widen shuffle mask

---
 .../LoongArch/LoongArchISelLowering.cpp       | 34 +++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index f72b55e1d175c..e9cdbd2104f18 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -31,6 +31,7 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/KnownBits.h"
 #include "llvm/Support/MathExtras.h"
+#include <llvm/Analysis/VectorUtils.h>
 
 using namespace llvm;
 
@@ -1671,6 +1672,36 @@ static SDValue lower256BitShuffle(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
 
   return SDValue();
 }
+// Widen element type to get a new mask value (if possible).
+// For example:
+//  shufflevector <4 x i32> %a, <4 x i32> %b,
+//                <4 x i32> <i32 6, i32 7, i32 2, i32 3>
+// is equivalent to:
+//  shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 3, i32 1>
+// can be lowered to:
+//  VPACKOD_D vr0, vr0, vr1
+static SDValue widenShuffleMask(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
+                                SDValue V1, SDValue V2, SelectionDAG &DAG) {
+  unsigned EltBits = VT.getScalarSizeInBits();
+
+  if (EltBits > 32 || EltBits == 1)
+    return SDValue();
+
+  SmallVector<int, 8> NewMask;
+  if (widenShuffleMaskElts(Mask, NewMask)) {
+    MVT NewEltVT = VT.isFloatingPoint() ? MVT::getFloatingPointVT(EltBits * 2)
+                                        : MVT::getIntegerVT(EltBits * 2);
+    MVT NewVT = MVT::getVectorVT(NewEltVT, VT.getVectorNumElements() / 2);
+    if (DAG.getTargetLoweringInfo().isTypeLegal(NewVT)) {
+      SDValue NewV1 = DAG.getBitcast(NewVT, V1);
+      SDValue NewV2 = DAG.getBitcast(NewVT, V2);
+      return DAG.getBitcast(
+          VT, DAG.getVectorShuffle(NewVT, DL, NewV1, NewV2, NewMask));
+    }
+  }
+
+  return SDValue();
+}
 
 SDValue LoongArchTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
                                                      SelectionDAG &DAG) const {
@@ -1705,6 +1736,9 @@ SDValue LoongArchTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
     return DAG.getVectorShuffle(VT, DL, V1, V2, NewMask);
   }
 
+  if (SDValue NewShuffle = widenShuffleMask(DL, OrigMask, VT, V1, V2, DAG))
+    return NewShuffle;
+
   // Check for illegal shuffle mask element index values.
   int MaskUpperLimit = OrigMask.size() * (V2IsUndef ? 1 : 2);
   (void)MaskUpperLimit;

>From 331fbc317c1d5d7e1dc05f8532555dad8862fa22 Mon Sep 17 00:00:00 2001
From: tangaac <tangyan01 at loongson.cn>
Date: Thu, 17 Apr 2025 15:14:49 +0800
Subject: [PATCH 2/2] widen shuffle mask as late as possible

---
 .../LoongArch/LoongArchISelLowering.cpp       | 68 ++++++++++---------
 1 file changed, 35 insertions(+), 33 deletions(-)

diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index e9cdbd2104f18..e5ef716e8ae2a 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -544,6 +544,37 @@ SDValue LoongArchTargetLowering::lowerBITREVERSE(SDValue Op,
   }
 }
 
+// Widen element type to get a new mask value (if possible).
+// For example:
+//  shufflevector <4 x i32> %a, <4 x i32> %b,
+//                <4 x i32> <i32 6, i32 7, i32 2, i32 3>
+// is equivalent to:
+//  shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 3, i32 1>
+// can be lowered to:
+//  VPACKOD_D vr0, vr0, vr1
+static SDValue widenShuffleMask(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
+                                SDValue V1, SDValue V2, SelectionDAG &DAG) {
+  unsigned EltBits = VT.getScalarSizeInBits();
+
+  if (EltBits > 32 || EltBits == 1)
+    return SDValue();
+
+  SmallVector<int, 8> NewMask;
+  if (widenShuffleMaskElts(Mask, NewMask)) {
+    MVT NewEltVT = VT.isFloatingPoint() ? MVT::getFloatingPointVT(EltBits * 2)
+                                        : MVT::getIntegerVT(EltBits * 2);
+    MVT NewVT = MVT::getVectorVT(NewEltVT, VT.getVectorNumElements() / 2);
+    if (DAG.getTargetLoweringInfo().isTypeLegal(NewVT)) {
+      SDValue NewV1 = DAG.getBitcast(NewVT, V1);
+      SDValue NewV2 = DAG.getBitcast(NewVT, V2);
+      return DAG.getBitcast(
+          VT, DAG.getVectorShuffle(NewVT, DL, NewV1, NewV2, NewMask));
+    }
+  }
+
+  return SDValue();
+}
+
 /// Attempts to match a shuffle mask against the VBSLL, VBSRL, VSLLI and VSRLI
 /// instruction.
 // The funciton matches elements from one of the input vector shuffled to the
@@ -1231,6 +1262,8 @@ static SDValue lower128BitShuffle(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
   if ((Result =
            lowerVECTOR_SHUFFLEAsShift(DL, Mask, VT, V1, V2, DAG, Zeroable)))
     return Result;
+  if (SDValue NewShuffle = widenShuffleMask(DL, Mask, VT, V1, V2, DAG))
+    return NewShuffle;
   if ((Result = lowerVECTOR_SHUFFLE_VSHUF(DL, Mask, VT, V1, V2, DAG)))
     return Result;
   return SDValue();
@@ -1667,41 +1700,13 @@ static SDValue lower256BitShuffle(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
   if ((Result =
            lowerVECTOR_SHUFFLEAsShift(DL, NewMask, VT, V1, V2, DAG, Zeroable)))
     return Result;
+  if (SDValue NewShuffle = widenShuffleMask(DL, NewMask, VT, V1, V2, DAG))
+    return NewShuffle;
   if ((Result = lowerVECTOR_SHUFFLE_XVSHUF(DL, NewMask, VT, V1, V2, DAG)))
     return Result;
 
   return SDValue();
 }
-// Widen element type to get a new mask value (if possible).
-// For example:
-//  shufflevector <4 x i32> %a, <4 x i32> %b,
-//                <4 x i32> <i32 6, i32 7, i32 2, i32 3>
-// is equivalent to:
-//  shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 3, i32 1>
-// can be lowered to:
-//  VPACKOD_D vr0, vr0, vr1
-static SDValue widenShuffleMask(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
-                                SDValue V1, SDValue V2, SelectionDAG &DAG) {
-  unsigned EltBits = VT.getScalarSizeInBits();
-
-  if (EltBits > 32 || EltBits == 1)
-    return SDValue();
-
-  SmallVector<int, 8> NewMask;
-  if (widenShuffleMaskElts(Mask, NewMask)) {
-    MVT NewEltVT = VT.isFloatingPoint() ? MVT::getFloatingPointVT(EltBits * 2)
-                                        : MVT::getIntegerVT(EltBits * 2);
-    MVT NewVT = MVT::getVectorVT(NewEltVT, VT.getVectorNumElements() / 2);
-    if (DAG.getTargetLoweringInfo().isTypeLegal(NewVT)) {
-      SDValue NewV1 = DAG.getBitcast(NewVT, V1);
-      SDValue NewV2 = DAG.getBitcast(NewVT, V2);
-      return DAG.getBitcast(
-          VT, DAG.getVectorShuffle(NewVT, DL, NewV1, NewV2, NewMask));
-    }
-  }
-
-  return SDValue();
-}
 
 SDValue LoongArchTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
                                                      SelectionDAG &DAG) const {
@@ -1736,9 +1741,6 @@ SDValue LoongArchTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
     return DAG.getVectorShuffle(VT, DL, V1, V2, NewMask);
   }
 
-  if (SDValue NewShuffle = widenShuffleMask(DL, OrigMask, VT, V1, V2, DAG))
-    return NewShuffle;
-
   // Check for illegal shuffle mask element index values.
   int MaskUpperLimit = OrigMask.size() * (V2IsUndef ? 1 : 2);
   (void)MaskUpperLimit;



More information about the llvm-commits mailing list