[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