Skip to content

Commit 58efc9a

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 02b8ee2 commit 58efc9a

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
@@ -6434,6 +6434,9 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
64346434
return getNode(ISD::VECREDUCE_AND, DL, VT, N1);
64356435
break;
64366436
case ISD::SPLAT_VECTOR:
6437+
// RISC-V vector tuple type is not a vector type.
6438+
if (VT.isRISCVVectorTuple())
6439+
break;
64376440
assert(VT.isVector() && "Wrong return type!");
64386441
// FIXME: Hexagon uses i32 scalar for a floating point zero vector so allow
64396442
// that for now.

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

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

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

19011908
// 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
@@ -898,7 +898,8 @@ static TargetTypeInfo getTargetTypeInfo(const TargetExtType *Ty) {
898898
RISCV::RVVBitsPerBlock / 8) *
899899
Ty->getIntParameter(0);
900900
return TargetTypeInfo(
901-
ScalableVectorType::get(Type::getInt8Ty(C), TotalNumElts));
901+
ScalableVectorType::get(Type::getInt8Ty(C), TotalNumElts),
902+
TargetExtType::HasZeroInit);
902903
}
903904

904905
// DirectX resources

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,25 @@ void RISCVDAGToDAGISel::PreprocessISelDAG() {
6565
VT.isInteger() ? RISCVISD::VMV_V_X_VL : RISCVISD::VFMV_V_F_VL;
6666
SDLoc DL(N);
6767
SDValue VL = CurDAG->getRegister(RISCV::X0, Subtarget->getXLenVT());
68+
69+
if (VT.isRISCVVectorTuple()) {
70+
unsigned NF = VT.getRISCVVectorTupleNumFields();
71+
unsigned NumScalElts = VT.getSizeInBits() / (NF * 8);
72+
SDValue EltVal = CurDAG->getConstant(0, DL, Subtarget->getXLenVT());
73+
MVT ScalTy =
74+
MVT::getScalableVectorVT(MVT::getIntegerVT(8), NumScalElts);
75+
76+
SDValue Splat = CurDAG->getNode(RISCVISD::VMV_V_X_VL, DL, ScalTy,
77+
CurDAG->getUNDEF(ScalTy), EltVal, VL);
78+
79+
Result = CurDAG->getUNDEF(VT);
80+
for (unsigned i = 0; i < NF; ++i)
81+
Result = CurDAG->getNode(RISCVISD::TUPLE_INSERT, DL, VT, Result,
82+
Splat, CurDAG->getVectorIdxConstant(i, DL));
83+
84+
break;
85+
}
86+
6887
SDValue Src = N->getOperand(0);
6988
if (VT.isInteger())
7089
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)