[llvm] [RISCV] Add lowerVECTOR_SHUFFLEAsCONCAT_VECTORS. (PR #109948)

Han-Kuan Chen via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 25 03:02:54 PDT 2024


https://github.com/HanKuanChen created https://github.com/llvm/llvm-project/pull/109948

None

>From a34cd5911d8dbae1a44208b3d2706fb88198b1b0 Mon Sep 17 00:00:00 2001
From: Han-Kuan Chen <hankuan.chen at sifive.com>
Date: Tue, 24 Sep 2024 20:47:07 -0700
Subject: [PATCH 1/2] [RISCV] Pre-commit test.

---
 .../fixed-vectors-shuffle-concat-vectors.ll   | 49 +++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-concat-vectors.ll

diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-concat-vectors.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-concat-vectors.ll
new file mode 100644
index 00000000000000..d97252a7afd5c1
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-concat-vectors.ll
@@ -0,0 +1,49 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple riscv64 -mattr=+v -riscv-v-vector-bits-min=512 -verify-machineinstrs < %s | FileCheck %s
+
+define <16 x float> @test1(<8 x float> %0) {
+; CHECK-LABEL: test1:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    lui a0, %hi(.LCPI0_0)
+; CHECK-NEXT:    addi a0, a0, %lo(.LCPI0_0)
+; CHECK-NEXT:    vsetivli zero, 16, e32, m1, ta, ma
+; CHECK-NEXT:    vle32.v v10, (a0)
+; CHECK-NEXT:    vrgather.vv v9, v8, v10
+; CHECK-NEXT:    vmv.v.v v8, v9
+; CHECK-NEXT:    ret
+entry:
+  %1 = call <16 x float> @llvm.vector.insert.v16f32.v8f32(<16 x float> poison, <8 x float> poison, i64 8)
+  %2 = call <16 x float> @llvm.vector.insert.v16f32.v8f32(<16 x float> %1, <8 x float> %0, i64 0)
+  %3 = shufflevector <16 x float> %2, <16 x float> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
+  ret <16 x float> %3
+}
+
+define <16 x i32> @test2(<4 x i32> %0) {
+; CHECK-LABEL: test2:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    lui a0, 1
+; CHECK-NEXT:    addi a0, a0, 273
+; CHECK-NEXT:    vsetivli zero, 16, e32, m1, ta, ma
+; CHECK-NEXT:    vmv.s.x v0, a0
+; CHECK-NEXT:    vmv.v.i v9, 3
+; CHECK-NEXT:    vmerge.vim v10, v9, 0, v0
+; CHECK-NEXT:    lui a0, 2
+; CHECK-NEXT:    addi a0, a0, 546
+; CHECK-NEXT:    vmv.s.x v0, a0
+; CHECK-NEXT:    lui a0, 4
+; CHECK-NEXT:    addi a0, a0, 1092
+; CHECK-NEXT:    vmv.s.x v9, a0
+; CHECK-NEXT:    vmerge.vim v10, v10, 1, v0
+; CHECK-NEXT:    vmv.v.v v0, v9
+; CHECK-NEXT:    vmerge.vim v10, v10, 2, v0
+; CHECK-NEXT:    vrgather.vv v9, v8, v10
+; CHECK-NEXT:    vmv.v.v v8, v9
+; CHECK-NEXT:    ret
+entry:
+  %1 = call <16 x i32> @llvm.vector.insert.v16i32.v4i32(<16 x i32> poison, <4 x i32> poison, i64 4)
+  %2 = call <16 x i32> @llvm.vector.insert.v16i32.v4i32(<16 x i32> %1, <4 x i32> poison, i64 8)
+  %3 = call <16 x i32> @llvm.vector.insert.v16i32.v4i32(<16 x i32> %2, <4 x i32> poison, i64 12)
+  %4 = call <16 x i32> @llvm.vector.insert.v16i32.v4i32(<16 x i32> %3, <4 x i32> %0, i64 0)
+  %5 = shufflevector <16 x i32> %4, <16 x i32> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3>
+  ret <16 x i32> %5
+}

>From 01d601190f6f961bd0a5c2ef01626c82358f229d Mon Sep 17 00:00:00 2001
From: Han-Kuan Chen <hankuan.chen at sifive.com>
Date: Wed, 25 Sep 2024 02:44:02 -0700
Subject: [PATCH 2/2] [RISCV] Add lowerVECTOR_SHUFFLEAsCONCAT_VECTORS.

---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp   | 37 +++++++++++++++++++
 .../fixed-vectors-shuffle-concat-vectors.ll   | 27 ++++----------
 2 files changed, 44 insertions(+), 20 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index bf822eb2c6eeb5..fe14b1991d5da2 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -5130,6 +5130,40 @@ static SDValue lowerVECTOR_SHUFFLEAsRotate(ShuffleVectorSDNode *SVN,
   return DAG.getBitcast(VT, Rotate);
 }
 
+// e.g.,
+// t10 = insert_subvector undef:v16i32, t4, Constant:i64<0>
+// vector_shuffle<0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3> t10, undef:v16i32
+// ->
+// concat_vectors t4, t4, t4, t4
+static SDValue
+lowerVECTOR_SHUFFLEAsCONCAT_VECTORS(ShuffleVectorSDNode *SVN, SelectionDAG &DAG,
+                                    const RISCVSubtarget &Subtarget) {
+  assert(SVN->getOperand(1).isUndef());
+  SDValue V1 = SVN->getOperand(0);
+  if (V1.getOpcode() != ISD::INSERT_SUBVECTOR)
+    return SDValue();
+  if (!V1.getOperand(0).isUndef())
+    return SDValue();
+  SDValue InsertValue = V1.getOperand(1);
+  MVT SubVecVT = InsertValue.getSimpleValueType();
+  unsigned SubVecNumElements = SubVecVT.getVectorNumElements();
+  uint64_t InsertIndex = cast<ConstantSDNode>(V1.getOperand(2))->getZExtValue();
+  if (InsertIndex != 0)
+    return SDValue();
+  ArrayRef<int> Mask = SVN->getMask();
+  if (Mask.size() % SubVecNumElements != 0)
+    return SDValue();
+  SmallVector<int> RepeatedPattern(
+      createSequentialMask(0, SubVecNumElements, 0));
+  // Check the Mask repeatedly uses the same subvector.
+  for (unsigned I = 0; I != Mask.size(); I += SubVecNumElements)
+    if (!Mask.slice(I, SubVecNumElements).equals(RepeatedPattern))
+      return SDValue();
+  SDLoc DL(SVN);
+  SmallVector<SDValue> Ops(Mask.size() / SubVecNumElements, InsertValue);
+  return DAG.getNode(ISD::CONCAT_VECTORS, DL, SVN->getSimpleValueType(0), Ops);
+}
+
 // If compiling with an exactly known VLEN, see if we can split a
 // shuffle on m2 or larger into a small number of m1 sized shuffles
 // which write each destination registers exactly once.
@@ -5432,6 +5466,9 @@ static SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG,
     if (SDValue V = lowerVECTOR_SHUFFLEAsRotate(SVN, DAG, Subtarget))
       return V;
 
+    if (SDValue V = lowerVECTOR_SHUFFLEAsCONCAT_VECTORS(SVN, DAG, Subtarget))
+      return V;
+
     if (VT.getScalarSizeInBits() == 8 &&
         any_of(Mask, [&](const auto &Idx) { return Idx > 255; })) {
       // On such a vector we're unable to use i8 as the index type.
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-concat-vectors.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-concat-vectors.ll
index d97252a7afd5c1..e3a790afeb41dd 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-concat-vectors.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-concat-vectors.ll
@@ -4,11 +4,9 @@
 define <16 x float> @test1(<8 x float> %0) {
 ; CHECK-LABEL: test1:
 ; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    lui a0, %hi(.LCPI0_0)
-; CHECK-NEXT:    addi a0, a0, %lo(.LCPI0_0)
+; CHECK-NEXT:    vmv1r.v v9, v8
 ; CHECK-NEXT:    vsetivli zero, 16, e32, m1, ta, ma
-; CHECK-NEXT:    vle32.v v10, (a0)
-; CHECK-NEXT:    vrgather.vv v9, v8, v10
+; CHECK-NEXT:    vslideup.vi v9, v8, 8
 ; CHECK-NEXT:    vmv.v.v v8, v9
 ; CHECK-NEXT:    ret
 entry:
@@ -21,23 +19,12 @@ entry:
 define <16 x i32> @test2(<4 x i32> %0) {
 ; CHECK-LABEL: test2:
 ; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    lui a0, 1
-; CHECK-NEXT:    addi a0, a0, 273
+; CHECK-NEXT:    vmv1r.v v9, v8
+; CHECK-NEXT:    vsetivli zero, 8, e32, mf2, ta, ma
+; CHECK-NEXT:    vslideup.vi v9, v8, 4
+; CHECK-NEXT:    vmv1r.v v8, v9
 ; CHECK-NEXT:    vsetivli zero, 16, e32, m1, ta, ma
-; CHECK-NEXT:    vmv.s.x v0, a0
-; CHECK-NEXT:    vmv.v.i v9, 3
-; CHECK-NEXT:    vmerge.vim v10, v9, 0, v0
-; CHECK-NEXT:    lui a0, 2
-; CHECK-NEXT:    addi a0, a0, 546
-; CHECK-NEXT:    vmv.s.x v0, a0
-; CHECK-NEXT:    lui a0, 4
-; CHECK-NEXT:    addi a0, a0, 1092
-; CHECK-NEXT:    vmv.s.x v9, a0
-; CHECK-NEXT:    vmerge.vim v10, v10, 1, v0
-; CHECK-NEXT:    vmv.v.v v0, v9
-; CHECK-NEXT:    vmerge.vim v10, v10, 2, v0
-; CHECK-NEXT:    vrgather.vv v9, v8, v10
-; CHECK-NEXT:    vmv.v.v v8, v9
+; CHECK-NEXT:    vslideup.vi v8, v9, 8
 ; CHECK-NEXT:    ret
 entry:
   %1 = call <16 x i32> @llvm.vector.insert.v16i32.v4i32(<16 x i32> poison, <4 x i32> poison, i64 4)



More information about the llvm-commits mailing list