[llvm] Fixes [AArch64] Assertion `EltCnt.isKnownEven() && "Cannot halve vector with odd number of elements."' failed. (PR #166528)
Shakil Ahmed via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 5 07:15:20 PST 2025
https://github.com/ahmedshakill updated https://github.com/llvm/llvm-project/pull/166528
>From 5042eb48c7354a023460115dfca511a91d00670d Mon Sep 17 00:00:00 2001
From: ahmedshakill <shakil.000024 at gmail.com>
Date: Wed, 5 Nov 2025 16:27:07 +0600
Subject: [PATCH 1/2] only attempt to halve known-even element count
---
llvm/include/llvm/CodeGen/BasicTTIImpl.h | 5 +++++
.../VectorCombine/AArch64/sve-interleave-splat.ll | 11 +++++++++++
2 files changed, 16 insertions(+)
create mode 100644 llvm/test/Transforms/VectorCombine/AArch64/sve-interleave-splat.ll
diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
index 221d8f1e2f673..0fd278aacf681 100644
--- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
@@ -1333,6 +1333,11 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
TargetLowering::TypeSplitVector;
if ((SplitSrc || SplitDst) && SrcVTy->getElementCount().isVector() &&
DstVTy->getElementCount().isVector()) {
+ auto SrcEltCnt = SrcVTy->getElementCount();
+ auto DstEltCnt = DstVTy->getElementCount();
+ if (!SrcEltCnt.isKnownEven() || !DstEltCnt.isKnownEven()) {
+ return InstructionCost::getInvalid();
+ }
Type *SplitDstTy = VectorType::getHalfElementsVectorType(DstVTy);
Type *SplitSrcTy = VectorType::getHalfElementsVectorType(SrcVTy);
const T *TTI = thisT();
diff --git a/llvm/test/Transforms/VectorCombine/AArch64/sve-interleave-splat.ll b/llvm/test/Transforms/VectorCombine/AArch64/sve-interleave-splat.ll
new file mode 100644
index 0000000000000..9a47800514b49
--- /dev/null
+++ b/llvm/test/Transforms/VectorCombine/AArch64/sve-interleave-splat.ll
@@ -0,0 +1,11 @@
+; RUN: opt -mtriple=aarch64-unknown-linux-gnu -passes=vector-combine %s -S -o - | FileCheck %s
+
+target triple = "aarch64-unknown-linux-gnu"
+
+define <vscale x 4 x i16> @interleave2_same_const_splat_nxv4i16() {
+;CHECK-LABEL: @interleave2_same_const_splat_nxv4i16(
+;CHECK: call <vscale x 4 x i16> @llvm.vector.interleave2
+;CHECK: ret <vscale x 4 x i16> %retval
+ %retval = call <vscale x 4 x i16> @llvm.vector.interleave2.nxv4i16(<vscale x 2 x i16> splat(i16 3), <vscale x 2 x i16> splat(i16 3))
+ ret <vscale x 4 x i16> %retval
+}
>From fd60a00597afbe5b94c55a412872cdc2c513d720 Mon Sep 17 00:00:00 2001
From: ahmedshakill <shakil.000024 at gmail.com>
Date: Wed, 5 Nov 2025 21:14:50 +0600
Subject: [PATCH 2/2] update known-even condition and test
---
llvm/include/llvm/CodeGen/BasicTTIImpl.h | 9 ++-------
.../VectorCombine/AArch64/sve-interleave-splat.ll | 5 ++---
2 files changed, 4 insertions(+), 10 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
index 0fd278aacf681..f58525754d7a5 100644
--- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
@@ -1331,13 +1331,8 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
bool SplitDst =
TLI->getTypeAction(Dst->getContext(), TLI->getValueType(DL, Dst)) ==
TargetLowering::TypeSplitVector;
- if ((SplitSrc || SplitDst) && SrcVTy->getElementCount().isVector() &&
- DstVTy->getElementCount().isVector()) {
- auto SrcEltCnt = SrcVTy->getElementCount();
- auto DstEltCnt = DstVTy->getElementCount();
- if (!SrcEltCnt.isKnownEven() || !DstEltCnt.isKnownEven()) {
- return InstructionCost::getInvalid();
- }
+ if ((SplitSrc || SplitDst) && SrcVTy->getElementCount().isKnownEven() &&
+ DstVTy->getElementCount().isKnownEven()) {
Type *SplitDstTy = VectorType::getHalfElementsVectorType(DstVTy);
Type *SplitSrcTy = VectorType::getHalfElementsVectorType(SrcVTy);
const T *TTI = thisT();
diff --git a/llvm/test/Transforms/VectorCombine/AArch64/sve-interleave-splat.ll b/llvm/test/Transforms/VectorCombine/AArch64/sve-interleave-splat.ll
index 9a47800514b49..e641930fc80a2 100644
--- a/llvm/test/Transforms/VectorCombine/AArch64/sve-interleave-splat.ll
+++ b/llvm/test/Transforms/VectorCombine/AArch64/sve-interleave-splat.ll
@@ -1,11 +1,10 @@
-; RUN: opt -mtriple=aarch64-unknown-linux-gnu -passes=vector-combine %s -S -o - | FileCheck %s
+; RUN: opt -mtriple=aarch64-unknown-linux-gnu -mattr=+sve -passes=vector-combine %s -S -o - | FileCheck %s
target triple = "aarch64-unknown-linux-gnu"
define <vscale x 4 x i16> @interleave2_same_const_splat_nxv4i16() {
;CHECK-LABEL: @interleave2_same_const_splat_nxv4i16(
-;CHECK: call <vscale x 4 x i16> @llvm.vector.interleave2
-;CHECK: ret <vscale x 4 x i16> %retval
+;CHECK: ret <vscale x 4 x i16> bitcast (<vscale x 2 x i32> splat (i32 196611) to <vscale x 4 x i16>)
%retval = call <vscale x 4 x i16> @llvm.vector.interleave2.nxv4i16(<vscale x 2 x i16> splat(i16 3), <vscale x 2 x i16> splat(i16 3))
ret <vscale x 4 x i16> %retval
}
More information about the llvm-commits
mailing list