[llvm] [AArch64][GISel] Do not bitcast nonpower2 element size G_CONCATs (PR #189911)

David Green via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 1 01:26:44 PDT 2026


https://github.com/davemgreen created https://github.com/llvm/llvm-project/pull/189911

This currently gets stuck in a loop, unable to make progress throught the
bitcast concat. Limit it to legal element sizes so that we always make progress
and at least fall back to SDAG as opposed to crashing or getting stuck.

>From dc0db92433f181e772b5f44e659a99ef67f6338c Mon Sep 17 00:00:00 2001
From: David Green <david.green at arm.com>
Date: Wed, 1 Apr 2026 09:26:32 +0100
Subject: [PATCH] [AArch64][GISel] Do not bitcast nonpower2 element size
 G_CONCATs

This currently gets stuck in a loop, unable to make progress throught the
bitcast concat. Limit it to legal element sizes so that we always make progress
and at least fall back to SDAG as opposed to crashing or getting stuck.
---
 .../Target/AArch64/GISel/AArch64LegalizerInfo.cpp  |  2 ++
 llvm/test/CodeGen/AArch64/dup.ll                   | 14 +++++++++++++-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index 61ba8960d526b..4e62c52940b8d 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -1262,6 +1262,8 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
           [=](const LegalityQuery &Query) {
             return Query.Types[0].isFixedVector() &&
                    Query.Types[1].isFixedVector() &&
+                   Query.Types[0].getScalarSizeInBits() >= 8 &&
+                   isPowerOf2_64(Query.Types[0].getScalarSizeInBits()) &&
                    Query.Types[0].getSizeInBits() <= 128 &&
                    Query.Types[1].getSizeInBits() <= 64;
           },
diff --git a/llvm/test/CodeGen/AArch64/dup.ll b/llvm/test/CodeGen/AArch64/dup.ll
index 9897a89dbfbd0..16748cf16cb19 100644
--- a/llvm/test/CodeGen/AArch64/dup.ll
+++ b/llvm/test/CodeGen/AArch64/dup.ll
@@ -1,6 +1,8 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
 ; RUN: llc -mtriple=aarch64-none-none-eabi -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SD
-; RUN: llc -mtriple=aarch64-none-none-eabi -verify-machineinstrs -global-isel %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GI
+; RUN: llc -mtriple=aarch64-none-none-eabi -verify-machineinstrs -global-isel -global-isel-abort=2 %s -o - 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI
+
+; CHECK-GI:       warning: Instruction selection used fallback path for v8i4_to_v16i8
 
 define <2 x i8> @dup_v2i8(i8 %a) {
 ; CHECK-SD-LABEL: dup_v2i8:
@@ -2720,3 +2722,13 @@ entry:
   %c = shufflevector <4 x fp128> %b, <4 x fp128> poison, <4 x i32> zeroinitializer
   ret <4 x fp128> %c
 }
+
+define <16 x i4> @v8i4_to_v16i8(<8 x i4> %a) {
+; CHECK-LABEL: v8i4_to_v16i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
+; CHECK-NEXT:    dup v0.16b, v0.b[0]
+; CHECK-NEXT:    ret
+  %r = shufflevector <8 x i4> %a, <8 x i4> poison, <16 x i32> zeroinitializer
+  ret <16 x i4> %r
+}



More information about the llvm-commits mailing list