[llvm] [Arch64] Add widening for vector interleave (2/n) (PR #209490)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 14 08:53:27 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v
Author: Kamlesh Kumar (kamleshbhalui)
<details>
<summary>Changes</summary>
Stacked on https://github.com/llvm/llvm-project/pull/207439
---
Patch is 51.72 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/209490.diff
14 Files Affected:
- (modified) llvm/include/llvm/CodeGen/TargetLowering.h (+6)
- (modified) llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h (+1)
- (modified) llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp (+40)
- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (+32-22)
- (modified) llvm/lib/Target/AArch64/AArch64ISelLowering.h (+4)
- (modified) llvm/lib/Target/RISCV/RISCVISelLowering.h (+4)
- (modified) llvm/test/CodeGen/AArch64/complex-deinterleaving-reductions.ll (+28-22)
- (modified) llvm/test/CodeGen/AArch64/complex-deinterleaving-splat.ll (+25-20)
- (modified) llvm/test/CodeGen/AArch64/fixed-vector-deinterleave.ll (+133-29)
- (modified) llvm/test/CodeGen/AArch64/fixed-vector-interleave.ll (+82-40)
- (modified) llvm/test/CodeGen/AArch64/fixed_masked_deinterleaved_loads.ll (+11-17)
- (modified) llvm/test/CodeGen/AArch64/fixed_masked_interleaved_stores.ll (+9-15)
- (modified) llvm/test/CodeGen/RISCV/rvv/fixed-vectors-deinterleave-load.ll (+6-14)
- (modified) llvm/test/CodeGen/RISCV/rvv/vector-deinterleave-fixed.ll (+66-131)
``````````diff
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index f7f14fed05393..d171fc0a26a13 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -3306,6 +3306,12 @@ class LLVM_ABI TargetLoweringBase {
/// Default to be the minimum interleave factor: 2.
virtual unsigned getMaxSupportedInterleaveFactor() const { return 2; }
+ /// Return true if target supports interleave intrinsics.
+ virtual bool isInterleaveIntrinsicSupported(unsigned /*Factor*/,
+ EVT VT) const {
+ return VT.isScalableVector();
+ }
+
/// Lower an interleaved load to target specific intrinsics. Return
/// true on success.
///
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index d4d56a9563f71..5a7df7c1b73c6 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -1079,6 +1079,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
SDValue WidenVecRes_VECTOR_REVERSE(SDNode *N);
SDValue WidenVecRes_GET_ACTIVE_LANE_MASK(SDNode *N);
void WidenVecRes_VECTOR_DEINTERLEAVE(SDNode *N);
+ void WidenVecRes_VECTOR_INTERLEAVE(SDNode *N);
SDValue WidenVecRes_Ternary(SDNode *N);
SDValue WidenVecRes_Binary(SDNode *N);
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 3ac1ca367abc8..4742894ff59b0 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -5331,6 +5331,9 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
case ISD::VECTOR_DEINTERLEAVE:
WidenVecRes_VECTOR_DEINTERLEAVE(N);
break;
+ case ISD::VECTOR_INTERLEAVE:
+ WidenVecRes_VECTOR_INTERLEAVE(N);
+ break;
case ISD::ADD: case ISD::VP_ADD:
case ISD::AND: case ISD::VP_AND:
@@ -7523,6 +7526,43 @@ void DAGTypeLegalizer::WidenVecRes_VECTOR_DEINTERLEAVE(SDNode *N) {
SetWidenedVector(SDValue(N, Idx), NewRes.getValue(Idx));
}
+void DAGTypeLegalizer::WidenVecRes_VECTOR_INTERLEAVE(SDNode *N) {
+ EVT VT = N->getValueType(0);
+ EVT EltVT = VT.getVectorElementType();
+ ElementCount OrigEC = VT.getVectorElementCount();
+ unsigned Factor = N->getNumOperands();
+ SDLoc DL(N);
+
+ EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
+ ElementCount WidenEC = WidenVT.getVectorElementCount();
+
+ SmallVector<SDValue, 8> WidenOps(Factor);
+ for (unsigned Idx = 0U; Idx < Factor; ++Idx)
+ WidenOps[Idx] = GetWidenedVector(N->getOperand(Idx));
+
+ SmallVector<EVT, 8> WidenVTs(Factor, WidenVT);
+ SDValue Interleaved =
+ DAG.getNode(ISD::VECTOR_INTERLEAVE, DL, WidenVTs, WidenOps);
+
+ EVT PackedWidenVT = EVT::getVectorVT(*DAG.getContext(), EltVT,
+ WidenEC.multiplyCoefficientBy(Factor));
+ SmallVector<SDValue, 8> Slices(Factor);
+ for (unsigned Idx = 0; Idx != Factor; ++Idx)
+ Slices[Idx] = Interleaved.getValue(Idx);
+
+ SDValue Packed =
+ DAG.getNode(ISD::CONCAT_VECTORS, DL, PackedWidenVT, Slices);
+
+ for (unsigned Idx = 0U; Idx < Factor; ++Idx) {
+ SDValue Narrow = DAG.getExtractSubvector(
+ DL, VT, Packed,
+ OrigEC.multiplyCoefficientBy(Idx).getKnownMinValue());
+ SDValue Wide =
+ DAG.getInsertSubvector(DL, DAG.getUNDEF(WidenVT), Narrow, /*Idx=*/0U);
+ SetWidenedVector(SDValue(N, Idx), Wide);
+ }
+}
+
SDValue DAGTypeLegalizer::WidenVecRes_SETCC(SDNode *N) {
assert(N->getValueType(0).isVector() &&
N->getOperand(0).getValueType().isVector() &&
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 27a6cf37807b5..43542dd3a371d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -13029,34 +13029,44 @@ void SelectionDAGBuilder::visitVectorReverse(const CallInst &I) {
void SelectionDAGBuilder::visitVectorDeinterleave(const CallInst &I,
unsigned Factor) {
auto DL = getCurSDLoc();
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
SDValue InVec = getValue(I.getOperand(0));
+ EVT InVT = InVec.getValueType();
SmallVector<EVT, 4> ValueVTs;
- ComputeValueVTs(DAG.getTargetLoweringInfo(), DAG.getDataLayout(), I.getType(),
- ValueVTs);
+ ComputeValueVTs(TLI, DAG.getDataLayout(), I.getType(), ValueVTs);
EVT OutVT = ValueVTs[0];
unsigned OutNumElts = OutVT.getVectorMinNumElements();
- SmallVector<SDValue, 4> SubVecs(Factor);
- for (unsigned i = 0; i != Factor; ++i) {
- assert(ValueVTs[i] == OutVT && "Expected VTs to be the same");
- SubVecs[i] = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, OutVT, InVec,
- DAG.getVectorIdxConstant(OutNumElts * i, DL));
- }
-
- // Use VECTOR_SHUFFLE for fixed-length vectors with factor of 2 to benefit
- // from existing legalisation and combines.
- if (OutVT.isFixedLengthVector() && Factor == 2) {
- SDValue Even = DAG.getVectorShuffle(OutVT, DL, SubVecs[0], SubVecs[1],
- createStrideMask(0, 2, OutNumElts));
- SDValue Odd = DAG.getVectorShuffle(OutVT, DL, SubVecs[0], SubVecs[1],
- createStrideMask(1, 2, OutNumElts));
- SDValue Res = DAG.getMergeValues({Even, Odd}, getCurSDLoc());
- setValue(&I, Res);
+ // Use VECTOR_SHUFFLE for fixed-length vectors that the target does not lower
+ // natively.
+ if (!TLI.isInterleaveIntrinsicSupported(Factor, InVT)) {
+ unsigned WideNumElts = InVT.getVectorNumElements();
+
+ SmallVector<SDValue, 8> Results;
+ Results.reserve(Factor);
+ for (unsigned I = 0; I != Factor; ++I) {
+ SmallVector<int, 16> Mask(WideNumElts, -1);
+ for (unsigned J = 0; J != OutNumElts; ++J)
+ Mask[J] = I + J * Factor;
+ SDValue Shuffle =
+ DAG.getVectorShuffle(InVT, DL, InVec, DAG.getUNDEF(InVT), Mask);
+ Results.push_back(DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, OutVT, Shuffle,
+ DAG.getVectorIdxConstant(0, DL)));
+ }
+
+ setValue(&I, DAG.getMergeValues(Results, DL));
return;
}
+ SmallVector<SDValue, 4> SubVecs(Factor);
+ for (unsigned I = 0; I != Factor; ++I) {
+ assert(ValueVTs[I] == OutVT && "Expected VTs to be the same");
+ SubVecs[I] = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, OutVT, InVec,
+ DAG.getVectorIdxConstant(OutNumElts * I, DL));
+ }
+
SDValue Res = DAG.getNode(ISD::VECTOR_DEINTERLEAVE, DL,
DAG.getVTList(ValueVTs), SubVecs);
setValue(&I, Res);
@@ -13076,13 +13086,13 @@ void SelectionDAGBuilder::visitVectorInterleave(const CallInst &I,
"Expected VTs to be the same");
}
- // Use VECTOR_SHUFFLE for fixed-length vectors with factor of 2 to benefit
- // from existing legalisation and combines.
- if (OutVT.isFixedLengthVector() && Factor == 2) {
+ // Use VECTOR_SHUFFLE for fixed-length vectors that the target does not lower
+ // natively.
+ if (!TLI.isInterleaveIntrinsicSupported(Factor, OutVT)) {
unsigned NumElts = InVT.getVectorMinNumElements();
SDValue V = DAG.getNode(ISD::CONCAT_VECTORS, DL, OutVT, InVecs);
setValue(&I, DAG.getVectorShuffle(OutVT, DL, V, DAG.getUNDEF(OutVT),
- createInterleaveMask(NumElts, 2)));
+ createInterleaveMask(NumElts, Factor)));
return;
}
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index 69013d4010122..b67aa4c966181 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -232,6 +232,10 @@ class AArch64TargetLowering : public TargetLowering {
unsigned getMaxSupportedInterleaveFactor() const override { return 4; }
+ bool isInterleaveIntrinsicSupported(unsigned Factor, EVT VT) const override {
+ return VT.isScalableVector() || Factor == 3 || Factor % 2 == 0;
+ }
+
bool lowerInterleavedLoad(Instruction *Load, Value *Mask,
ArrayRef<ShuffleVectorInst *> Shuffles,
ArrayRef<unsigned> Indices, unsigned Factor,
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h
index 4e7912ed815dd..792b8a03b755f 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -432,6 +432,10 @@ class RISCVTargetLowering : public TargetLowering {
unsigned getMaxSupportedInterleaveFactor() const override { return 8; }
+ bool isInterleaveIntrinsicSupported(unsigned Factor, EVT VT) const override {
+ return VT.isScalableVector() || Factor > 2;
+ }
+
bool fallBackToDAGISel(const Instruction &Inst) const override;
bool lowerInterleavedLoad(Instruction *Load, Value *Mask,
diff --git a/llvm/test/CodeGen/AArch64/complex-deinterleaving-reductions.ll b/llvm/test/CodeGen/AArch64/complex-deinterleaving-reductions.ll
index 355adec955e4b..3e3e3389c146d 100644
--- a/llvm/test/CodeGen/AArch64/complex-deinterleaving-reductions.ll
+++ b/llvm/test/CodeGen/AArch64/complex-deinterleaving-reductions.ll
@@ -31,8 +31,8 @@ define dso_local %"struct.std::complex" @complex_mul_v2f64(ptr %a, ptr %b) {
; CHECK-NEXT: fcmla v0.2d, v4.2d, v2.2d, #90
; CHECK-NEXT: b.ne .LBB0_1
; CHECK-NEXT: // %bb.2: // %middle.block
-; CHECK-NEXT: zip2 v2.2d, v1.2d, v0.2d
-; CHECK-NEXT: zip1 v0.2d, v1.2d, v0.2d
+; CHECK-NEXT: uzp2 v2.2d, v1.2d, v0.2d
+; CHECK-NEXT: uzp1 v0.2d, v1.2d, v0.2d
; CHECK-NEXT: faddp d0, v0.2d
; CHECK-NEXT: faddp d1, v2.2d
; CHECK-NEXT: ret
@@ -80,10 +80,13 @@ middle.block: ; preds = %vector.body
define %"struct.std::complex" @complex_mul_nonzero_init_v2f64(ptr %a, ptr %b) {
; CHECK-LABEL: complex_mul_nonzero_init_v2f64:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: movi v0.2d, #0000000000000000
; CHECK-NEXT: adrp x8, .LCPI1_0
+; CHECK-NEXT: adrp x9, .LCPI1_1
; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI1_0]
+; CHECK-NEXT: ldr q2, [x9, :lo12:.LCPI1_1]
; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: zip2 v0.2d, v2.2d, v1.2d
+; CHECK-NEXT: zip1 v1.2d, v2.2d, v1.2d
; CHECK-NEXT: .LBB1_1: // %vector.body
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
; CHECK-NEXT: add x9, x0, x8
@@ -98,8 +101,8 @@ define %"struct.std::complex" @complex_mul_nonzero_init_v2f64(ptr %a, ptr %b) {
; CHECK-NEXT: fcmla v0.2d, v4.2d, v2.2d, #90
; CHECK-NEXT: b.ne .LBB1_1
; CHECK-NEXT: // %bb.2: // %middle.block
-; CHECK-NEXT: zip2 v2.2d, v1.2d, v0.2d
-; CHECK-NEXT: zip1 v0.2d, v1.2d, v0.2d
+; CHECK-NEXT: uzp2 v2.2d, v1.2d, v0.2d
+; CHECK-NEXT: uzp1 v0.2d, v1.2d, v0.2d
; CHECK-NEXT: faddp d0, v0.2d
; CHECK-NEXT: faddp d1, v2.2d
; CHECK-NEXT: ret
@@ -143,14 +146,17 @@ middle.block: ; preds = %vector.body
define %"struct.std::complex" @complex_mul_v2f64_unrolled(ptr %a, ptr %b) {
; CHECK-LABEL: complex_mul_v2f64_unrolled:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: movi v0.2d, #0000000000000000
-; CHECK-NEXT: movi v1.2d, #0000000000000000
; CHECK-NEXT: adrp x8, .LCPI2_0
+; CHECK-NEXT: adrp x9, .LCPI2_1
; CHECK-NEXT: movi v3.2d, #0000000000000000
-; CHECK-NEXT: ldr q2, [x8, :lo12:.LCPI2_0]
+; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI2_0]
+; CHECK-NEXT: ldr q2, [x9, :lo12:.LCPI2_1]
; CHECK-NEXT: add x8, x0, #32
; CHECK-NEXT: add x9, x1, #32
; CHECK-NEXT: mov x10, #-100 // =0xffffffffffffff9c
+; CHECK-NEXT: zip2 v0.2d, v2.2d, v1.2d
+; CHECK-NEXT: zip1 v1.2d, v2.2d, v1.2d
+; CHECK-NEXT: movi v2.2d, #0000000000000000
; CHECK-NEXT: .LBB2_1: // %vector.body
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
; CHECK-NEXT: ldp q5, q4, [x8, #-32]
@@ -158,24 +164,24 @@ define %"struct.std::complex" @complex_mul_v2f64_unrolled(ptr %a, ptr %b) {
; CHECK-NEXT: ldp q7, q6, [x9, #-32]
; CHECK-NEXT: ldp q17, q16, [x8], #64
; CHECK-NEXT: ldp q19, q18, [x9], #64
-; CHECK-NEXT: fcmla v2.2d, v7.2d, v5.2d, #0
-; CHECK-NEXT: fcmla v1.2d, v6.2d, v4.2d, #0
-; CHECK-NEXT: fcmla v0.2d, v19.2d, v17.2d, #0
-; CHECK-NEXT: fcmla v3.2d, v18.2d, v16.2d, #0
-; CHECK-NEXT: fcmla v2.2d, v7.2d, v5.2d, #90
-; CHECK-NEXT: fcmla v1.2d, v6.2d, v4.2d, #90
-; CHECK-NEXT: fcmla v0.2d, v19.2d, v17.2d, #90
-; CHECK-NEXT: fcmla v3.2d, v18.2d, v16.2d, #90
+; CHECK-NEXT: fcmla v1.2d, v7.2d, v5.2d, #0
+; CHECK-NEXT: fcmla v0.2d, v6.2d, v4.2d, #0
+; CHECK-NEXT: fcmla v3.2d, v19.2d, v17.2d, #0
+; CHECK-NEXT: fcmla v2.2d, v18.2d, v16.2d, #0
+; CHECK-NEXT: fcmla v1.2d, v7.2d, v5.2d, #90
+; CHECK-NEXT: fcmla v0.2d, v6.2d, v4.2d, #90
+; CHECK-NEXT: fcmla v3.2d, v19.2d, v17.2d, #90
+; CHECK-NEXT: fcmla v2.2d, v18.2d, v16.2d, #90
; CHECK-NEXT: b.ne .LBB2_1
; CHECK-NEXT: // %bb.2: // %middle.block
-; CHECK-NEXT: zip2 v4.2d, v0.2d, v3.2d
-; CHECK-NEXT: zip1 v0.2d, v0.2d, v3.2d
-; CHECK-NEXT: zip2 v3.2d, v2.2d, v1.2d
-; CHECK-NEXT: zip1 v1.2d, v2.2d, v1.2d
-; CHECK-NEXT: fadd v0.2d, v0.2d, v1.2d
+; CHECK-NEXT: uzp2 v4.2d, v3.2d, v2.2d
+; CHECK-NEXT: uzp1 v2.2d, v3.2d, v2.2d
+; CHECK-NEXT: uzp2 v3.2d, v1.2d, v0.2d
+; CHECK-NEXT: uzp1 v0.2d, v1.2d, v0.2d
; CHECK-NEXT: fadd v1.2d, v4.2d, v3.2d
-; CHECK-NEXT: faddp d0, v0.2d
+; CHECK-NEXT: fadd v0.2d, v2.2d, v0.2d
; CHECK-NEXT: faddp d1, v1.2d
+; CHECK-NEXT: faddp d0, v0.2d
; CHECK-NEXT: ret
entry:
%scevgep = getelementptr i8, ptr %a, i64 32
diff --git a/llvm/test/CodeGen/AArch64/complex-deinterleaving-splat.ll b/llvm/test/CodeGen/AArch64/complex-deinterleaving-splat.ll
index ad9240b0922bd..f8c7a25f47185 100644
--- a/llvm/test/CodeGen/AArch64/complex-deinterleaving-splat.ll
+++ b/llvm/test/CodeGen/AArch64/complex-deinterleaving-splat.ll
@@ -9,21 +9,23 @@ target triple = "aarch64"
define <4 x double> @complex_mul_const(<4 x double> %a, <4 x double> %b) {
; CHECK-LABEL: complex_mul_const:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: movi v6.2d, #0000000000000000
-; CHECK-NEXT: movi v5.2d, #0000000000000000
-; CHECK-NEXT: adrp x8, .LCPI0_0
; CHECK-NEXT: movi v4.2d, #0000000000000000
-; CHECK-NEXT: fcmla v6.2d, v1.2d, v3.2d, #0
-; CHECK-NEXT: fcmla v5.2d, v0.2d, v2.2d, #0
-; CHECK-NEXT: fcmla v6.2d, v1.2d, v3.2d, #90
-; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI0_0]
-; CHECK-NEXT: fcmla v5.2d, v0.2d, v2.2d, #90
+; CHECK-NEXT: movi v5.2d, #0000000000000000
+; CHECK-NEXT: fmov v6.2d, #3.00000000
+; CHECK-NEXT: fmov v7.2d, #11.00000000
+; CHECK-NEXT: fcmla v4.2d, v0.2d, v2.2d, #0
+; CHECK-NEXT: fcmla v5.2d, v1.2d, v3.2d, #0
+; CHECK-NEXT: fcmla v4.2d, v0.2d, v2.2d, #90
+; CHECK-NEXT: movi v2.2d, #0000000000000000
+; CHECK-NEXT: fcmla v5.2d, v1.2d, v3.2d, #90
+; CHECK-NEXT: zip2 v1.2d, v7.2d, v6.2d
+; CHECK-NEXT: zip1 v3.2d, v7.2d, v6.2d
; CHECK-NEXT: movi v0.2d, #0000000000000000
-; CHECK-NEXT: fcmla v4.2d, v6.2d, v1.2d, #0
-; CHECK-NEXT: fcmla v0.2d, v5.2d, v1.2d, #0
-; CHECK-NEXT: fcmla v4.2d, v6.2d, v1.2d, #90
-; CHECK-NEXT: fcmla v0.2d, v5.2d, v1.2d, #90
-; CHECK-NEXT: mov v1.16b, v4.16b
+; CHECK-NEXT: fcmla v2.2d, v5.2d, v1.2d, #0
+; CHECK-NEXT: fcmla v0.2d, v4.2d, v3.2d, #0
+; CHECK-NEXT: fcmla v2.2d, v5.2d, v1.2d, #90
+; CHECK-NEXT: fcmla v0.2d, v4.2d, v3.2d, #90
+; CHECK-NEXT: mov v1.16b, v2.16b
; CHECK-NEXT: ret
entry:
%strided.vec = shufflevector <4 x double> %a, <4 x double> poison, <2 x i32> <i32 0, i32 2>
@@ -56,18 +58,21 @@ define <4 x double> @complex_mul_non_const(<4 x double> %a, <4 x double> %b, [2
; CHECK-NEXT: movi v6.2d, #0000000000000000
; CHECK-NEXT: // kill: def $d5 killed $d5 def $q5
; CHECK-NEXT: // kill: def $d4 killed $d4 def $q4
-; CHECK-NEXT: mov v4.d[1], v5.d[0]
-; CHECK-NEXT: movi v5.2d, #0000000000000000
+; CHECK-NEXT: dup v5.2d, v5.d[0]
+; CHECK-NEXT: dup v4.2d, v4.d[0]
; CHECK-NEXT: fcmla v7.2d, v1.2d, v3.2d, #0
; CHECK-NEXT: fcmla v6.2d, v0.2d, v2.2d, #0
+; CHECK-NEXT: zip2 v16.2d, v4.2d, v5.2d
+; CHECK-NEXT: zip1 v5.2d, v4.2d, v5.2d
+; CHECK-NEXT: movi v4.2d, #0000000000000000
; CHECK-NEXT: fcmla v7.2d, v1.2d, v3.2d, #90
; CHECK-NEXT: fcmla v6.2d, v0.2d, v2.2d, #90
; CHECK-NEXT: movi v0.2d, #0000000000000000
-; CHECK-NEXT: fcmla v5.2d, v7.2d, v4.2d, #0
-; CHECK-NEXT: fcmla v0.2d, v6.2d, v4.2d, #0
-; CHECK-NEXT: fcmla v5.2d, v7.2d, v4.2d, #90
-; CHECK-NEXT: fcmla v0.2d, v6.2d, v4.2d, #90
-; CHECK-NEXT: mov v1.16b, v5.16b
+; CHECK-NEXT: fcmla v4.2d, v7.2d, v16.2d, #0
+; CHECK-NEXT: fcmla v0.2d, v6.2d, v5.2d, #0
+; CHECK-NEXT: fcmla v4.2d, v7.2d, v16.2d, #90
+; CHECK-NEXT: fcmla v0.2d, v6.2d, v5.2d, #90
+; CHECK-NEXT: mov v1.16b, v4.16b
; CHECK-NEXT: ret
entry:
%c.coerce.fca.1.extract = extractvalue [2 x double] %c, 1
diff --git a/llvm/test/CodeGen/AArch64/fixed-vector-deinterleave.ll b/llvm/test/CodeGen/AArch64/fixed-vector-deinterleave.ll
index 8c48cc609c75a..2420164619be0 100644
--- a/llvm/test/CodeGen/AArch64/fixed-vector-deinterleave.ll
+++ b/llvm/test/CodeGen/AArch64/fixed-vector-deinterleave.ll
@@ -3,21 +3,12 @@
; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel -global-isel-abort=0 %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GI
define {<2 x half>, <2 x half>} @vector_deinterleave_v2f16_v4f16(<4 x half> %vec) {
-; CHECK-SD-LABEL: vector_deinterleave_v2f16_v4f16:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q0
-; CHECK-SD-NEXT: dup v1.2s, v0.s[1]
-; CHECK-SD-NEXT: zip1 v2.4h, v0.4h, v1.4h
-; CHECK-SD-NEXT: trn2 v1.4h, v0.4h, v1.4h
-; CHECK-SD-NEXT: fmov d0, d2
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: vector_deinterleave_v2f16_v4f16:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: uzp1 v2.4h, v0.4h, v0.4h
-; CHECK-GI-NEXT: uzp2 v1.4h, v0.4h, v0.4h
-; CHECK-GI-NEXT: fmov d0, d2
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: vector_deinterleave_v2f16_v4f16:
+; CHECK: // %bb.0:
+; CHECK-NEXT: uzp1 v2.4h, v0.4h, v0.4h
+; CHECK-NEXT: uzp2 v1.4h, v0.4h, v0.4h
+; CHECK-NEXT: fmov d0, d2
+; CHECK-NEXT: ret
%retval = call {<2 x half>, <2 x half>} @llvm.vector.deinterleave2.v4f16(<4 x half> %vec)
ret {<2 x half>, <2 x half>} %retval
}
@@ -49,8 +40,8 @@ define {<2 x float>, <2 x float>} @vector_deinterleave_v2f32_v4f32(<4 x float> %
; CHECK-SD-LABEL: vector_deinterleave_v2f32_v4f32:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: mov d1, v0.d[1]
-; CHECK-SD-NEXT: zip1 v2.2s, v0.2s, v1.2s
-; CHECK-SD-NEXT: zip2 v1.2s, v0.2s, v1.2s
+; CHECK-SD-NEXT: uzp1 v2.2s, v0.2s, v1.2s
+; CHECK-SD-NEXT: uzp2 v1.2s, v0.2s, v1.2s
; CHECK-SD-NEXT: fmov d0, d2
; CHECK-SD-NEXT: ret
;
@@ -77,12 +68,19 @@ ret {<4 x float>, <4 x float>} %retval
}
define {<2 x double>, <2 x double>} @vector_deinterleave_v2f64_v4f64(<4 x double> %vec) {
-; CHECK-LABEL: vector_deinterleave_v2f64_v4f64:
-; CHECK: // %bb.0:
-; CHECK-NEXT: zip1 v2.2d, v0.2d, v1.2d
-; CHECK-NEXT: zip2 v1.2d, v0.2d, v1.2d
-; CHECK-NEXT: mov v0.16b, v2.16b
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: vector_deinterleave_v2f64_v4f64:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: uzp1 v2.2d, v0.2d, v1.2d
+; CHECK-SD-NEXT: uzp2 v1.2d, v0.2d, v1.2d
+; CHECK-SD-NEXT: mov v0.16b, v2.16b
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: vector_deinterleave_v2f64_v4f64:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: zip1 v2.2d, v0.2d, v1.2d
+; CHECK-GI-NEXT: zip2 v1.2d, v0.2d, v1.2d
+; CHECK-GI-NEXT: mov v0.16b, v2.16b
+; CHECK-GI-NEXT: ret
%retval = call {<2 x double>, <2 x double>} @llvm.vector.deinterleave2.v4f64(<4 x double> %vec)
ret {<2 x double>, <2 x double>} %retval
}
@@ -123,12 +121,19 @@ define {<4 x i32>, <4 x i32>} @vector_deinterleave_v4i32_v8i32(<8 x i32> %vec) {
}
define {<2 x i64>, <2 x i64>} @vector_deinterleave_v2i64_v4i64(<4 x i64> %vec) {
-; CHECK-LABEL: vector_deinterleave_v2i64_v4i64:
-; CHECK: // %bb.0:
-; CHECK-NEXT: zip1 v2.2d, v0.2d, v1.2d
-; CHECK-NEXT: zip2 v...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/209490
More information about the llvm-commits
mailing list