Skip to content

Commit 87dd7c3

Browse files
committed
[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.
1 parent 635c344 commit 87dd7c3

File tree

5 files changed

+71
-1
lines changed

5 files changed

+71
-1
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6288,6 +6288,9 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
62886288
return getNode(ISD::VECREDUCE_AND, DL, VT, N1);
62896289
break;
62906290
case ISD::SPLAT_VECTOR:
6291+
// RISC-V vector tuple type is not a vector type.
6292+
if (VT.isRISCVVectorTuple())
6293+
break;
62916294
assert(VT.isVector() && "Wrong return type!");
62926295
// FIXME: Hexagon uses i32 scalar for a floating point zero vector so allow
62936296
// that for now.

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1900,6 +1900,13 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) {
19001900
DAG.getConstant(0, getCurSDLoc(), MVT::nxv16i1));
19011901
}
19021902

1903+
if (VT.isRISCVVectorTuple()) {
1904+
assert(C->isNullValue() && "Can only zero this target type!");
1905+
return NodeMap[V] = DAG.getNode(
1906+
ISD::SPLAT_VECTOR, getCurSDLoc(), VT,
1907+
DAG.getConstant(0, getCurSDLoc(), MVT::getIntegerVT(8)));
1908+
}
1909+
19031910
VectorType *VecTy = cast<VectorType>(V->getType());
19041911

19051912
// Now that we know the number and type of the elements, get that number of

llvm/lib/IR/Type.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -880,7 +880,8 @@ static TargetTypeInfo getTargetTypeInfo(const TargetExtType *Ty) {
880880
RISCV::RVVBitsPerBlock / 8) *
881881
Ty->getIntParameter(0);
882882
return TargetTypeInfo(
883-
ScalableVectorType::get(Type::getInt8Ty(C), TotalNumElts));
883+
ScalableVectorType::get(Type::getInt8Ty(C), TotalNumElts),
884+
TargetExtType::HasZeroInit);
884885
}
885886

886887
// DirectX resources

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,25 @@ void RISCVDAGToDAGISel::PreprocessISelDAG() {
6666
VT.isInteger() ? RISCVISD::VMV_V_X_VL : RISCVISD::VFMV_V_F_VL;
6767
SDLoc DL(N);
6868
SDValue VL = CurDAG->getRegister(RISCV::X0, Subtarget->getXLenVT());
69+
70+
if (VT.isRISCVVectorTuple()) {
71+
unsigned NF = VT.getRISCVVectorTupleNumFields();
72+
unsigned NumScalElts = VT.getSizeInBits() / (NF * 8);
73+
SDValue EltVal = CurDAG->getConstant(0, DL, Subtarget->getXLenVT());
74+
MVT ScalTy =
75+
MVT::getScalableVectorVT(MVT::getIntegerVT(8), NumScalElts);
76+
77+
SDValue Splat = CurDAG->getNode(RISCVISD::VMV_V_X_VL, DL, ScalTy,
78+
CurDAG->getUNDEF(ScalTy), EltVal, VL);
79+
80+
Result = CurDAG->getUNDEF(VT);
81+
for (unsigned i = 0; i < NF; ++i)
82+
Result = CurDAG->getNode(RISCVISD::TUPLE_INSERT, DL, VT, Result,
83+
Splat, CurDAG->getVectorIdxConstant(i, DL));
84+
85+
break;
86+
}
87+
6988
SDValue Src = N->getOperand(0);
7089
if (VT.isInteger())
7190
Src = CurDAG->getNode(ISD::ANY_EXTEND, DL, Subtarget->getXLenVT(),
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -mattr=+v \
3+
; RUN: -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK
4+
; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+v \
5+
; RUN: -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK
6+
7+
define target("riscv.vector.tuple", <vscale x 16 x i8>, 2) @test_tuple_zero0() {
8+
; CHECK-LABEL: test_tuple_zero0:
9+
; CHECK: # %bb.0: # %entry
10+
; CHECK-NEXT: vsetvli a0, zero, e8, m2, ta, ma
11+
; CHECK-NEXT: vmv.v.i v8, 0
12+
; CHECK-NEXT: vmv.v.i v10, 0
13+
; CHECK-NEXT: ret
14+
entry:
15+
ret target("riscv.vector.tuple", <vscale x 16 x i8>, 2) zeroinitializer
16+
}
17+
18+
define target("riscv.vector.tuple", <vscale x 16 x i8>, 2) @test_tuple_zero1(<vscale x 4 x i32> %a) {
19+
; CHECK-LABEL: test_tuple_zero1:
20+
; CHECK: # %bb.0: # %entry
21+
; CHECK-NEXT: vsetvli a0, zero, e8, m2, ta, ma
22+
; CHECK-NEXT: vmv.v.i v10, 0
23+
; CHECK-NEXT: ret
24+
entry:
25+
%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)
26+
ret target("riscv.vector.tuple", <vscale x 16 x i8>, 2) %1
27+
}
28+
29+
define target("riscv.vector.tuple", <vscale x 16 x i8>, 2) @test_tuple_zero2(<vscale x 4 x i32> %a) {
30+
; CHECK-LABEL: test_tuple_zero2:
31+
; CHECK: # %bb.0: # %entry
32+
; CHECK-NEXT: vsetvli a0, zero, e8, m2, ta, ma
33+
; CHECK-NEXT: vmv.v.i v6, 0
34+
; CHECK-NEXT: vmv2r.v v10, v8
35+
; CHECK-NEXT: vmv2r.v v8, v6
36+
; CHECK-NEXT: ret
37+
entry:
38+
%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)
39+
ret target("riscv.vector.tuple", <vscale x 16 x i8>, 2) %1
40+
}

0 commit comments

Comments
 (0)