[llvm] [RISCV] Handle zeroinitializer of vector tuple Type (PR #113995)

Brandon Wu via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 25 22:36:16 PST 2024


https://github.com/4vtomat updated https://github.com/llvm/llvm-project/pull/113995

>From 51cb9901b139b3ba5dcaddadae8c6f807e9cf17f Mon Sep 17 00:00:00 2001
From: Brandon Wu <brandon.wu at sifive.com>
Date: Tue, 29 Oct 2024 06:57:57 +0800
Subject: [PATCH 1/4] [RISCV] Handle zeroinitializer of vector tuple Type

It doesn't make sense to add a new generic ISD to handle riscv tuple
type. Instead we use `SPLAT_VECTOR` for ISD and further lower to `VMV_V_X`.

Note: If there's `visitSPLAT_VECTOR` in generic DAG combiner, it needs
to skip riscv vector tuple type.
---
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp |  3 ++
 .../SelectionDAG/SelectionDAGBuilder.cpp      |  7 ++++
 llvm/lib/IR/Type.cpp                          |  2 +-
 llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp   | 19 +++++++++
 .../RISCV/vector-tuple-zeroinitializer.ll     | 40 +++++++++++++++++++
 5 files changed, 70 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/CodeGen/RISCV/vector-tuple-zeroinitializer.ll

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 7c5ed04830b16a..3efc0d3450e686 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6434,6 +6434,9 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
       return getNode(ISD::VECREDUCE_AND, DL, VT, N1);
     break;
   case ISD::SPLAT_VECTOR:
+    // RISC-V vector tuple type is not a vector type.
+    if (VT.isRISCVVectorTuple())
+      break;
     assert(VT.isVector() && "Wrong return type!");
     // FIXME: Hexagon uses i32 scalar for a floating point zero vector so allow
     // that for now.
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 9d729d448502d8..e69c490cb7ef43 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -1896,6 +1896,13 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) {
                          DAG.getConstant(0, getCurSDLoc(), MVT::nxv16i1));
     }
 
+    if (VT.isRISCVVectorTuple()) {
+      assert(C->isNullValue() && "Can only zero this target type!");
+      return NodeMap[V] = DAG.getNode(
+                 ISD::SPLAT_VECTOR, getCurSDLoc(), VT,
+                 DAG.getConstant(0, getCurSDLoc(), MVT::getIntegerVT(8)));
+    }
+
     VectorType *VecTy = cast<VectorType>(V->getType());
 
     // Now that we know the number and type of the elements, get that number of
diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp
index ac6b8b4c197002..ffa80faf6e249f 100644
--- a/llvm/lib/IR/Type.cpp
+++ b/llvm/lib/IR/Type.cpp
@@ -990,7 +990,7 @@ static TargetTypeInfo getTargetTypeInfo(const TargetExtType *Ty) {
         Ty->getIntParameter(0);
     return TargetTypeInfo(
         ScalableVectorType::get(Type::getInt8Ty(C), TotalNumElts),
-        TargetExtType::CanBeLocal);
+        TargetExtType::CanBeLocal, TargetExtType::HasZeroInit);
   }
 
   // DirectX resources
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index c5432619a36462..66a7b3aeabf4c6 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -65,6 +65,25 @@ void RISCVDAGToDAGISel::PreprocessISelDAG() {
           VT.isInteger() ? RISCVISD::VMV_V_X_VL : RISCVISD::VFMV_V_F_VL;
       SDLoc DL(N);
       SDValue VL = CurDAG->getRegister(RISCV::X0, Subtarget->getXLenVT());
+
+      if (VT.isRISCVVectorTuple()) {
+        unsigned NF = VT.getRISCVVectorTupleNumFields();
+        unsigned NumScalElts = VT.getSizeInBits() / (NF * 8);
+        SDValue EltVal = CurDAG->getConstant(0, DL, Subtarget->getXLenVT());
+        MVT ScalTy =
+            MVT::getScalableVectorVT(MVT::getIntegerVT(8), NumScalElts);
+
+        SDValue Splat = CurDAG->getNode(RISCVISD::VMV_V_X_VL, DL, ScalTy,
+                                        CurDAG->getUNDEF(ScalTy), EltVal, VL);
+
+        Result = CurDAG->getUNDEF(VT);
+        for (unsigned i = 0; i < NF; ++i)
+          Result = CurDAG->getNode(RISCVISD::TUPLE_INSERT, DL, VT, Result,
+                                   Splat, CurDAG->getVectorIdxConstant(i, DL));
+
+        break;
+      }
+
       SDValue Src = N->getOperand(0);
       if (VT.isInteger())
         Src = CurDAG->getNode(ISD::ANY_EXTEND, DL, Subtarget->getXLenVT(),
diff --git a/llvm/test/CodeGen/RISCV/vector-tuple-zeroinitializer.ll b/llvm/test/CodeGen/RISCV/vector-tuple-zeroinitializer.ll
new file mode 100644
index 00000000000000..88e1315d560b07
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/vector-tuple-zeroinitializer.ll
@@ -0,0 +1,40 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -mattr=+v \
+; RUN:   -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK
+; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+v \
+; RUN:   -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK
+
+define target("riscv.vector.tuple", <vscale x 16 x i8>, 2) @test_tuple_zero0() {
+; CHECK-LABEL: test_tuple_zero0:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vsetvli a0, zero, e8, m2, ta, ma
+; CHECK-NEXT:    vmv.v.i v8, 0
+; CHECK-NEXT:    vmv.v.i v10, 0
+; CHECK-NEXT:    ret
+entry:
+  ret target("riscv.vector.tuple", <vscale x 16 x i8>, 2) zeroinitializer
+}
+
+define target("riscv.vector.tuple", <vscale x 16 x i8>, 2) @test_tuple_zero1(<vscale x 4 x i32> %a) {
+; CHECK-LABEL: test_tuple_zero1:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vsetvli a0, zero, e8, m2, ta, ma
+; CHECK-NEXT:    vmv.v.i v10, 0
+; CHECK-NEXT:    ret
+entry:
+  %1 = call target("riscv.vector.tuple", <vscale x 16 x i8>, 2) @llvm.riscv.tuple.insert.triscv.vector.tuple_nxv16i8_2t.nxv4i32(target("riscv.vector.tuple", <vscale x 16 x i8>, 2) zeroinitializer, <vscale x 4 x i32> %a, i32 0)
+  ret target("riscv.vector.tuple", <vscale x 16 x i8>, 2) %1
+}
+
+define target("riscv.vector.tuple", <vscale x 16 x i8>, 2) @test_tuple_zero2(<vscale x 4 x i32> %a) {
+; CHECK-LABEL: test_tuple_zero2:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vsetvli a0, zero, e8, m2, ta, ma
+; CHECK-NEXT:    vmv.v.i v6, 0
+; CHECK-NEXT:    vmv2r.v v10, v8
+; CHECK-NEXT:    vmv2r.v v8, v6
+; CHECK-NEXT:    ret
+entry:
+  %1 = call target("riscv.vector.tuple", <vscale x 16 x i8>, 2) @llvm.riscv.tuple.insert.triscv.vector.tuple_nxv16i8_2t.nxv4i32(target("riscv.vector.tuple", <vscale x 16 x i8>, 2) zeroinitializer, <vscale x 4 x i32> %a, i32 1)
+  ret target("riscv.vector.tuple", <vscale x 16 x i8>, 2) %1
+}

>From 08abba2e623673695e22349eef118abf85d537f7 Mon Sep 17 00:00:00 2001
From: Brandon Wu <brandon.wu at sifive.com>
Date: Mon, 18 Nov 2024 23:48:03 -0800
Subject: [PATCH 2/4] fixup! [RISCV] Handle zeroinitializer of vector tuple
 Type

---
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp |  3 ---
 .../SelectionDAG/SelectionDAGBuilder.cpp      |  8 ++++--
 llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp   | 25 +++++++++++--------
 3 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 3efc0d3450e686..7c5ed04830b16a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6434,9 +6434,6 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
       return getNode(ISD::VECREDUCE_AND, DL, VT, N1);
     break;
   case ISD::SPLAT_VECTOR:
-    // RISC-V vector tuple type is not a vector type.
-    if (VT.isRISCVVectorTuple())
-      break;
     assert(VT.isVector() && "Wrong return type!");
     // FIXME: Hexagon uses i32 scalar for a floating point zero vector so allow
     // that for now.
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index e69c490cb7ef43..a4e67284bc77f2 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -1899,8 +1899,12 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) {
     if (VT.isRISCVVectorTuple()) {
       assert(C->isNullValue() && "Can only zero this target type!");
       return NodeMap[V] = DAG.getNode(
-                 ISD::SPLAT_VECTOR, getCurSDLoc(), VT,
-                 DAG.getConstant(0, getCurSDLoc(), MVT::getIntegerVT(8)));
+                 ISD::BITCAST, getCurSDLoc(), VT,
+                 DAG.getNode(
+                     ISD::SPLAT_VECTOR, getCurSDLoc(),
+                     MVT::getScalableVectorVT(
+                         MVT::i8, VT.getSizeInBits().getKnownMinValue() / 8),
+                     DAG.getConstant(0, getCurSDLoc(), MVT::getIntegerVT(8))));
     }
 
     VectorType *VecTy = cast<VectorType>(V->getType());
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 66a7b3aeabf4c6..684abe94cd6c87 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -57,18 +57,14 @@ void RISCVDAGToDAGISel::PreprocessISelDAG() {
 
     SDValue Result;
     switch (N->getOpcode()) {
-    case ISD::SPLAT_VECTOR: {
-      // Convert integer SPLAT_VECTOR to VMV_V_X_VL and floating-point
-      // SPLAT_VECTOR to VFMV_V_F_VL to reduce isel burden.
+    case ISD::BITCAST: {
       MVT VT = N->getSimpleValueType(0);
-      unsigned Opc =
-          VT.isInteger() ? RISCVISD::VMV_V_X_VL : RISCVISD::VFMV_V_F_VL;
       SDLoc DL(N);
       SDValue VL = CurDAG->getRegister(RISCV::X0, Subtarget->getXLenVT());
-
-      if (VT.isRISCVVectorTuple()) {
+      if (VT.isRISCVVectorTuple() &&
+          N->getOperand(0)->getOpcode() == ISD::SPLAT_VECTOR) {
         unsigned NF = VT.getRISCVVectorTupleNumFields();
-        unsigned NumScalElts = VT.getSizeInBits() / (NF * 8);
+        unsigned NumScalElts = VT.getSizeInBits().getKnownMinValue() / (NF * 8);
         SDValue EltVal = CurDAG->getConstant(0, DL, Subtarget->getXLenVT());
         MVT ScalTy =
             MVT::getScalableVectorVT(MVT::getIntegerVT(8), NumScalElts);
@@ -80,10 +76,17 @@ void RISCVDAGToDAGISel::PreprocessISelDAG() {
         for (unsigned i = 0; i < NF; ++i)
           Result = CurDAG->getNode(RISCVISD::TUPLE_INSERT, DL, VT, Result,
                                    Splat, CurDAG->getVectorIdxConstant(i, DL));
-
-        break;
       }
-
+      break;
+    }
+    case ISD::SPLAT_VECTOR: {
+      // Convert integer SPLAT_VECTOR to VMV_V_X_VL and floating-point
+      // SPLAT_VECTOR to VFMV_V_F_VL to reduce isel burden.
+      MVT VT = N->getSimpleValueType(0);
+      unsigned Opc =
+          VT.isInteger() ? RISCVISD::VMV_V_X_VL : RISCVISD::VFMV_V_F_VL;
+      SDLoc DL(N);
+      SDValue VL = CurDAG->getRegister(RISCV::X0, Subtarget->getXLenVT());
       SDValue Src = N->getOperand(0);
       if (VT.isInteger())
         Src = CurDAG->getNode(ISD::ANY_EXTEND, DL, Subtarget->getXLenVT(),

>From 8fbfafcb8f36746552b37bd132d9d2cd1a62d8ec Mon Sep 17 00:00:00 2001
From: Brandon Wu <brandon.wu at sifive.com>
Date: Mon, 25 Nov 2024 20:55:49 -0800
Subject: [PATCH 3/4] fixup! [RISCV] Handle zeroinitializer of vector tuple
 Type

---
 .../SelectionDAG/SelectionDAGBuilder.cpp      |  5 ++--
 llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp   | 22 ---------------
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp   | 16 +++++++++++
 .../RISCV/vector-tuple-zeroinitializer.ll     | 28 +++++++++++++------
 4 files changed, 39 insertions(+), 32 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index a4e67284bc77f2..c3da09f0251225 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -1902,8 +1902,9 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) {
                  ISD::BITCAST, getCurSDLoc(), VT,
                  DAG.getNode(
                      ISD::SPLAT_VECTOR, getCurSDLoc(),
-                     MVT::getScalableVectorVT(
-                         MVT::i8, VT.getSizeInBits().getKnownMinValue() / 8),
+                     EVT::getVectorVT(*DAG.getContext(), MVT::i8,
+                                      VT.getSizeInBits().getKnownMinValue() / 8,
+                                      true),
                      DAG.getConstant(0, getCurSDLoc(), MVT::getIntegerVT(8))));
     }
 
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 684abe94cd6c87..c5432619a36462 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -57,28 +57,6 @@ void RISCVDAGToDAGISel::PreprocessISelDAG() {
 
     SDValue Result;
     switch (N->getOpcode()) {
-    case ISD::BITCAST: {
-      MVT VT = N->getSimpleValueType(0);
-      SDLoc DL(N);
-      SDValue VL = CurDAG->getRegister(RISCV::X0, Subtarget->getXLenVT());
-      if (VT.isRISCVVectorTuple() &&
-          N->getOperand(0)->getOpcode() == ISD::SPLAT_VECTOR) {
-        unsigned NF = VT.getRISCVVectorTupleNumFields();
-        unsigned NumScalElts = VT.getSizeInBits().getKnownMinValue() / (NF * 8);
-        SDValue EltVal = CurDAG->getConstant(0, DL, Subtarget->getXLenVT());
-        MVT ScalTy =
-            MVT::getScalableVectorVT(MVT::getIntegerVT(8), NumScalElts);
-
-        SDValue Splat = CurDAG->getNode(RISCVISD::VMV_V_X_VL, DL, ScalTy,
-                                        CurDAG->getUNDEF(ScalTy), EltVal, VL);
-
-        Result = CurDAG->getUNDEF(VT);
-        for (unsigned i = 0; i < NF; ++i)
-          Result = CurDAG->getNode(RISCVISD::TUPLE_INSERT, DL, VT, Result,
-                                   Splat, CurDAG->getVectorIdxConstant(i, DL));
-      }
-      break;
-    }
     case ISD::SPLAT_VECTOR: {
       // Convert integer SPLAT_VECTOR to VMV_V_X_VL and floating-point
       // SPLAT_VECTOR to VFMV_V_F_VL to reduce isel burden.
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 329b42d621ceec..59a438f361eef2 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -18054,6 +18054,22 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
     SDValue N0 = N->getOperand(0);
     EVT VT = N->getValueType(0);
     EVT SrcVT = N0.getValueType();
+    if (VT.isRISCVVectorTuple() && N0->getOpcode() == ISD::SPLAT_VECTOR) {
+      SDValue VL = DAG.getRegister(RISCV::X0, Subtarget.getXLenVT());
+      unsigned NF = VT.getRISCVVectorTupleNumFields();
+      unsigned NumScalElts = VT.getSizeInBits().getKnownMinValue() / (NF * 8);
+      SDValue EltVal = DAG.getConstant(0, DL, Subtarget.getXLenVT());
+      MVT ScalTy = MVT::getScalableVectorVT(MVT::getIntegerVT(8), NumScalElts);
+
+      SDValue Splat = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, ScalTy,
+                                  DAG.getUNDEF(ScalTy), EltVal, VL);
+
+      SDValue Result = DAG.getUNDEF(VT);
+      for (unsigned i = 0; i < NF; ++i)
+        Result = DAG.getNode(RISCVISD::TUPLE_INSERT, DL, VT, Result, Splat,
+                             DAG.getVectorIdxConstant(i, DL));
+      return Result;
+    }
     // If this is a bitcast between a MVT::v4i1/v2i1/v1i1 and an illegal integer
     // type, widen both sides to avoid a trip through memory.
     if ((SrcVT == MVT::v1i1 || SrcVT == MVT::v2i1 || SrcVT == MVT::v4i1) &&
diff --git a/llvm/test/CodeGen/RISCV/vector-tuple-zeroinitializer.ll b/llvm/test/CodeGen/RISCV/vector-tuple-zeroinitializer.ll
index 88e1315d560b07..73fd529a9fb311 100644
--- a/llvm/test/CodeGen/RISCV/vector-tuple-zeroinitializer.ll
+++ b/llvm/test/CodeGen/RISCV/vector-tuple-zeroinitializer.ll
@@ -1,11 +1,11 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
-; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -mattr=+v \
+; RUN: llc -mtriple=riscv32 -mattr=+v \
 ; RUN:   -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK
-; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+v \
+; RUN: llc -mtriple=riscv64 -mattr=+v \
 ; RUN:   -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK
 
-define target("riscv.vector.tuple", <vscale x 16 x i8>, 2) @test_tuple_zero0() {
-; CHECK-LABEL: test_tuple_zero0:
+define target("riscv.vector.tuple", <vscale x 16 x i8>, 2) @test_tuple_zero_power_of_2() {
+; CHECK-LABEL: test_tuple_zero_power_of_2:
 ; CHECK:       # %bb.0: # %entry
 ; CHECK-NEXT:    vsetvli a0, zero, e8, m2, ta, ma
 ; CHECK-NEXT:    vmv.v.i v8, 0
@@ -15,8 +15,20 @@ entry:
   ret target("riscv.vector.tuple", <vscale x 16 x i8>, 2) zeroinitializer
 }
 
-define target("riscv.vector.tuple", <vscale x 16 x i8>, 2) @test_tuple_zero1(<vscale x 4 x i32> %a) {
-; CHECK-LABEL: test_tuple_zero1:
+define target("riscv.vector.tuple", <vscale x 16 x i8>, 3) @test_tuple_zero_non_power_of_2() {
+; CHECK-LABEL: test_tuple_zero_non_power_of_2:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vsetvli a0, zero, e8, m2, ta, ma
+; CHECK-NEXT:    vmv.v.i v8, 0
+; CHECK-NEXT:    vmv.v.i v10, 0
+; CHECK-NEXT:    vmv.v.i v12, 0
+; CHECK-NEXT:    ret
+entry:
+  ret target("riscv.vector.tuple", <vscale x 16 x i8>, 3) zeroinitializer
+}
+
+define target("riscv.vector.tuple", <vscale x 16 x i8>, 2) @test_tuple_zero_insert1(<vscale x 4 x i32> %a) {
+; CHECK-LABEL: test_tuple_zero_insert1:
 ; CHECK:       # %bb.0: # %entry
 ; CHECK-NEXT:    vsetvli a0, zero, e8, m2, ta, ma
 ; CHECK-NEXT:    vmv.v.i v10, 0
@@ -26,8 +38,8 @@ entry:
   ret target("riscv.vector.tuple", <vscale x 16 x i8>, 2) %1
 }
 
-define target("riscv.vector.tuple", <vscale x 16 x i8>, 2) @test_tuple_zero2(<vscale x 4 x i32> %a) {
-; CHECK-LABEL: test_tuple_zero2:
+define target("riscv.vector.tuple", <vscale x 16 x i8>, 2) @test_tuple_zero_insert2(<vscale x 4 x i32> %a) {
+; CHECK-LABEL: test_tuple_zero_insert2:
 ; CHECK:       # %bb.0: # %entry
 ; CHECK-NEXT:    vsetvli a0, zero, e8, m2, ta, ma
 ; CHECK-NEXT:    vmv.v.i v6, 0

>From 5ffa3cb1dc3bc97390d45e285eccfa72385487d3 Mon Sep 17 00:00:00 2001
From: Brandon Wu <brandon.wu at sifive.com>
Date: Mon, 25 Nov 2024 22:19:06 -0800
Subject: [PATCH 4/4] fixup! [RISCV] Handle zeroinitializer of vector tuple
 Type

---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 59a438f361eef2..1e66245f41bfad 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -18055,14 +18055,12 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
     EVT VT = N->getValueType(0);
     EVT SrcVT = N0.getValueType();
     if (VT.isRISCVVectorTuple() && N0->getOpcode() == ISD::SPLAT_VECTOR) {
-      SDValue VL = DAG.getRegister(RISCV::X0, Subtarget.getXLenVT());
       unsigned NF = VT.getRISCVVectorTupleNumFields();
       unsigned NumScalElts = VT.getSizeInBits().getKnownMinValue() / (NF * 8);
       SDValue EltVal = DAG.getConstant(0, DL, Subtarget.getXLenVT());
       MVT ScalTy = MVT::getScalableVectorVT(MVT::getIntegerVT(8), NumScalElts);
 
-      SDValue Splat = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, ScalTy,
-                                  DAG.getUNDEF(ScalTy), EltVal, VL);
+      SDValue Splat = DAG.getNode(ISD::SPLAT_VECTOR, DL, ScalTy, EltVal);
 
       SDValue Result = DAG.getUNDEF(VT);
       for (unsigned i = 0; i < NF; ++i)



More information about the llvm-commits mailing list