[llvm] cb96eba - [IR][Legalization] Split illegal deinterleave and interleave vectors
Caroline Concatto via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 1 00:30:50 PST 2023
Author: Caroline Concatto
Date: 2023-03-01T08:30:16Z
New Revision: cb96eba27cd18ecf8041bf1b9a5c7e197f7a2749
URL: https://github.com/llvm/llvm-project/commit/cb96eba27cd18ecf8041bf1b9a5c7e197f7a2749
DIFF: https://github.com/llvm/llvm-project/commit/cb96eba27cd18ecf8041bf1b9a5c7e197f7a2749.diff
LOG: [IR][Legalization] Split illegal deinterleave and interleave vectors
To make legalization easier, the operands and outputs have the same size for
these ISD Nodes. When legalizing the results in SplitVectorResult the operands
are legalized to the same size as the outputs.
The ISD Node has two output/results, therefore the legalizing functions update
both results/outputs.
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D144744
Added:
Modified:
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
llvm/test/CodeGen/AArch64/sve-vector-deinterleave.ll
llvm/test/CodeGen/AArch64/sve-vector-interleave.ll
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 63a3061cb1b77..d05884365c960 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -22391,7 +22391,7 @@ static SDValue combineConcatVectorOfScalars(SDNode *N, SelectionDAG &DAG) {
EVT OpVT = N->getOperand(0).getValueType();
// If the operands are legal vectors, leave them alone.
- if (TLI.isTypeLegal(OpVT))
+ if (TLI.isTypeLegal(OpVT) || OpVT.isScalableVector())
return SDValue();
SDLoc DL(N);
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index b97e44a013196..1c71ade5b66cc 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -875,6 +875,8 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
void SplitVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N, SDValue &Lo,
SDValue &Hi);
void SplitVecRes_VECTOR_SPLICE(SDNode *N, SDValue &Lo, SDValue &Hi);
+ void SplitVecRes_VECTOR_DEINTERLEAVE(SDNode *N);
+ void SplitVecRes_VECTOR_INTERLEAVE(SDNode *N);
void SplitVecRes_VAARG(SDNode *N, SDValue &Lo, SDValue &Hi);
void SplitVecRes_FP_TO_XINT_SAT(SDNode *N, SDValue &Lo, SDValue &Hi);
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 630f5b859f370..46795fd8b627e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -1000,6 +1000,12 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
case ISD::VECTOR_SPLICE:
SplitVecRes_VECTOR_SPLICE(N, Lo, Hi);
break;
+ case ISD::VECTOR_DEINTERLEAVE:
+ SplitVecRes_VECTOR_DEINTERLEAVE(N);
+ return;
+ case ISD::VECTOR_INTERLEAVE:
+ SplitVecRes_VECTOR_INTERLEAVE(N);
+ return;
case ISD::VAARG:
SplitVecRes_VAARG(N, Lo, Hi);
break;
@@ -2768,6 +2774,37 @@ void DAGTypeLegalizer::SplitVecRes_VECTOR_SPLICE(SDNode *N, SDValue &Lo,
DAG.getVectorIdxConstant(LoVT.getVectorMinNumElements(), DL));
}
+void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(SDNode *N) {
+
+ SDValue Op0Lo, Op0Hi, Op1Lo, Op1Hi;
+ GetSplitVector(N->getOperand(0), Op0Lo, Op0Hi);
+ GetSplitVector(N->getOperand(1), Op1Lo, Op1Hi);
+ EVT VT = Op0Lo.getValueType();
+ SDLoc DL(N);
+ SDValue ResLo = DAG.getNode(ISD::VECTOR_DEINTERLEAVE, DL,
+ DAG.getVTList(VT, VT), Op0Lo, Op0Hi);
+ SDValue ResHi = DAG.getNode(ISD::VECTOR_DEINTERLEAVE, DL,
+ DAG.getVTList(VT, VT), Op1Lo, Op1Hi);
+
+ SetSplitVector(SDValue(N, 0), ResLo.getValue(0), ResHi.getValue(0));
+ SetSplitVector(SDValue(N, 1), ResLo.getValue(1), ResHi.getValue(1));
+}
+
+void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(SDNode *N) {
+ SDValue Op0Lo, Op0Hi, Op1Lo, Op1Hi;
+ GetSplitVector(N->getOperand(0), Op0Lo, Op0Hi);
+ GetSplitVector(N->getOperand(1), Op1Lo, Op1Hi);
+ EVT VT = Op0Lo.getValueType();
+ SDLoc DL(N);
+ SDValue Res[] = {DAG.getNode(ISD::VECTOR_INTERLEAVE, DL,
+ DAG.getVTList(VT, VT), Op0Lo, Op1Lo),
+ DAG.getNode(ISD::VECTOR_INTERLEAVE, DL,
+ DAG.getVTList(VT, VT), Op0Hi, Op1Hi)};
+
+ SetSplitVector(SDValue(N, 0), Res[0].getValue(0), Res[0].getValue(1));
+ SetSplitVector(SDValue(N, 1), Res[1].getValue(0), Res[1].getValue(1));
+}
+
//===----------------------------------------------------------------------===//
// Operand Vector Splitting
//===----------------------------------------------------------------------===//
diff --git a/llvm/test/CodeGen/AArch64/sve-vector-deinterleave.ll b/llvm/test/CodeGen/AArch64/sve-vector-deinterleave.ll
index 8a1a862fb3fce..5fc84a261e1cb 100644
--- a/llvm/test/CodeGen/AArch64/sve-vector-deinterleave.ll
+++ b/llvm/test/CodeGen/AArch64/sve-vector-deinterleave.ll
@@ -165,6 +165,47 @@ define {<vscale x 2 x i1>, <vscale x 2 x i1>} @vector_deinterleave_nxv2i1_nxv4i1
}
+; Split illegal types
+
+define {<vscale x 4 x i64>, <vscale x 4 x i64>} @vector_deinterleave_nxv4i64_nxv8i64(<vscale x 8 x i64> %vec) {
+; CHECK-LABEL: vector_deinterleave_nxv4i64_nxv8i64:
+; CHECK: // %bb.0:
+; CHECK-NEXT: uzp1 z4.d, z2.d, z3.d
+; CHECK-NEXT: uzp1 z5.d, z0.d, z1.d
+; CHECK-NEXT: uzp2 z6.d, z0.d, z1.d
+; CHECK-NEXT: uzp2 z3.d, z2.d, z3.d
+; CHECK-NEXT: mov z0.d, z5.d
+; CHECK-NEXT: mov z1.d, z4.d
+; CHECK-NEXT: mov z2.d, z6.d
+; CHECK-NEXT: ret
+%retval = call {<vscale x 4 x i64>, <vscale x 4 x i64>} @llvm.experimental.vector.deinterleave2.nxv8i64(<vscale x 8 x i64> %vec)
+ret {<vscale x 4 x i64>, <vscale x 4 x i64>} %retval
+}
+
+define {<vscale x 8 x i64>, <vscale x 8 x i64>} @vector_deinterleave_nxv8i64_nxv16i64(<vscale x 16 x i64> %vec) {
+; CHECK-LABEL: vector_deinterleave_nxv8i64_nxv16i64:
+; CHECK: // %bb.0:
+; CHECK-NEXT: uzp1 z24.d, z4.d, z5.d
+; CHECK-NEXT: uzp1 z25.d, z2.d, z3.d
+; CHECK-NEXT: uzp1 z26.d, z0.d, z1.d
+; CHECK-NEXT: uzp1 z27.d, z6.d, z7.d
+; CHECK-NEXT: uzp2 z28.d, z0.d, z1.d
+; CHECK-NEXT: uzp2 z29.d, z2.d, z3.d
+; CHECK-NEXT: uzp2 z30.d, z4.d, z5.d
+; CHECK-NEXT: uzp2 z7.d, z6.d, z7.d
+; CHECK-NEXT: mov z0.d, z26.d
+; CHECK-NEXT: mov z1.d, z25.d
+; CHECK-NEXT: mov z2.d, z24.d
+; CHECK-NEXT: mov z3.d, z27.d
+; CHECK-NEXT: mov z4.d, z28.d
+; CHECK-NEXT: mov z5.d, z29.d
+; CHECK-NEXT: mov z6.d, z30.d
+; CHECK-NEXT: ret
+%retval = call {<vscale x 8 x i64>, <vscale x 8 x i64>} @llvm.experimental.vector.deinterleave2.nxv16i64(<vscale x 16 x i64> %vec)
+ret {<vscale x 8 x i64>, <vscale x 8 x i64>} %retval
+}
+
+
; Floating declarations
declare {<vscale x 2 x half>,<vscale x 2 x half>} @llvm.experimental.vector.deinterleave2.nxv4f16(<vscale x 4 x half>)
declare {<vscale x 4 x half>, <vscale x 4 x half>} @llvm.experimental.vector.deinterleave2.nxv8f16(<vscale x 8 x half>)
@@ -184,3 +225,7 @@ declare {<vscale x 16 x i1>, <vscale x 16 x i1>} @llvm.experimental.vector.deint
declare {<vscale x 8 x i1>, <vscale x 8 x i1>} @llvm.experimental.vector.deinterleave2.nxv16i1(<vscale x 16 x i1>)
declare {<vscale x 4 x i1>, <vscale x 4 x i1>} @llvm.experimental.vector.deinterleave2.nxv8i1(<vscale x 8 x i1>)
declare {<vscale x 2 x i1>, <vscale x 2 x i1>} @llvm.experimental.vector.deinterleave2.nxv4i1(<vscale x 4 x i1>)
+
+; Illegal size type
+declare {<vscale x 4 x i64>, <vscale x 4 x i64>} @llvm.experimental.vector.deinterleave2.nxv8i64(<vscale x 8 x i64>)
+declare {<vscale x 8 x i64>, <vscale x 8 x i64>} @llvm.experimental.vector.deinterleave2.nxv16i64(<vscale x 16 x i64>)
diff --git a/llvm/test/CodeGen/AArch64/sve-vector-interleave.ll b/llvm/test/CodeGen/AArch64/sve-vector-interleave.ll
index 05587206d860d..ee1dc4a3fcd6f 100644
--- a/llvm/test/CodeGen/AArch64/sve-vector-interleave.ll
+++ b/llvm/test/CodeGen/AArch64/sve-vector-interleave.ll
@@ -159,6 +159,35 @@ define <vscale x 4 x i1> @interleave2_nxv4i1(<vscale x 2 x i1> %vec0, <vscale x
ret <vscale x 4 x i1> %retval
}
+; Split illegal type size
+
+define <vscale x 16 x i32> @interleave2_nxv16i32(<vscale x 8 x i32> %vec0, <vscale x 8 x i32> %vec1) {
+; CHECK-LABEL: interleave2_nxv16i32:
+; CHECK: // %bb.0:
+; CHECK-NEXT: zip1 z4.s, z0.s, z2.s
+; CHECK-NEXT: zip2 z5.s, z0.s, z2.s
+; CHECK-NEXT: zip1 z2.s, z1.s, z3.s
+; CHECK-NEXT: zip2 z3.s, z1.s, z3.s
+; CHECK-NEXT: mov z0.d, z4.d
+; CHECK-NEXT: mov z1.d, z5.d
+; CHECK-NEXT: ret
+ %retval = call <vscale x 16 x i32>@llvm.experimental.vector.interleave2.nxv16i32(<vscale x 8 x i32> %vec0, <vscale x 8 x i32> %vec1)
+ ret <vscale x 16 x i32> %retval
+}
+
+define <vscale x 8 x i64> @interleave2_nxv8i64(<vscale x 4 x i64> %vec0, <vscale x 4 x i64> %vec1) {
+; CHECK-LABEL: interleave2_nxv8i64:
+; CHECK: // %bb.0:
+; CHECK-NEXT: zip1 z4.d, z0.d, z2.d
+; CHECK-NEXT: zip2 z5.d, z0.d, z2.d
+; CHECK-NEXT: zip1 z2.d, z1.d, z3.d
+; CHECK-NEXT: zip2 z3.d, z1.d, z3.d
+; CHECK-NEXT: mov z0.d, z4.d
+; CHECK-NEXT: mov z1.d, z5.d
+; CHECK-NEXT: ret
+ %retval = call <vscale x 8 x i64> @llvm.experimental.vector.interleave2.nxv8i64(<vscale x 4 x i64> %vec0, <vscale x 4 x i64> %vec1)
+ ret <vscale x 8 x i64> %retval
+}
; Float declarations
declare <vscale x 4 x half> @llvm.experimental.vector.interleave2.nxv4f16(<vscale x 2 x half>, <vscale x 2 x half>)
@@ -179,3 +208,7 @@ declare <vscale x 32 x i1> @llvm.experimental.vector.interleave2.nxv32i1(<vscale
declare <vscale x 16 x i1> @llvm.experimental.vector.interleave2.nxv16i1(<vscale x 8 x i1>, <vscale x 8 x i1>)
declare <vscale x 8 x i1> @llvm.experimental.vector.interleave2.nxv8i1(<vscale x 4 x i1>, <vscale x 4 x i1>)
declare <vscale x 4 x i1> @llvm.experimental.vector.interleave2.nxv4i1(<vscale x 2 x i1>, <vscale x 2 x i1>)
+
+; Illegal type size
+declare <vscale x 16 x i32> @llvm.experimental.vector.interleave2.nxv16i32(<vscale x 8 x i32>, <vscale x 8 x i32>)
+declare <vscale x 8 x i64> @llvm.experimental.vector.interleave2.nxv8i64(<vscale x 4 x i64>, <vscale x 4 x i64>)
More information about the llvm-commits
mailing list