[llvm] 58e6d02 - [AArch64][GlobalISel] Check unmergeSrc is a vector in matchCombineBuildUnmerge (#168692)

via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 19 04:30:57 PST 2025


Author: Ryan Cowan
Date: 2025-11-19T12:30:51Z
New Revision: 58e6d02aa28ba48ee37f1b59ad006dfeb45d1dd3

URL: https://github.com/llvm/llvm-project/commit/58e6d02aa28ba48ee37f1b59ad006dfeb45d1dd3
DIFF: https://github.com/llvm/llvm-project/commit/58e6d02aa28ba48ee37f1b59ad006dfeb45d1dd3.diff

LOG: [AArch64][GlobalISel] Check unmergeSrc is a vector in matchCombineBuildUnmerge (#168692)

This aims to fix the crash in #168495, my combine rule was
missing a check that the source vector was in fact a vector. This then
caused the legality check to fail in this example as the concat was
trying to concat a non vector.

I have also gated the bitcast of the concat to only work on non-scalable
vectors as the mutation calls `getNumElements` which crashes when called
on a scalable vector.

Fixes #168495

Added: 
    llvm/test/CodeGen/AArch64/GlobalISel/combine-unmerge-undef.mir

Modified: 
    llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
    llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 45a08347b1ec2..f0fbe0135353f 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -3499,6 +3499,9 @@ bool CombinerHelper::matchCombineBuildUnmerge(MachineInstr &MI,
   LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
   LLT UnmergeSrcTy = MRI.getType(UnmergeSrc);
 
+  if (!UnmergeSrcTy.isVector())
+    return false;
+
   // Ensure we only generate legal instructions post-legalizer
   if (!IsPreLegalize &&
       !isLegal({TargetOpcode::G_CONCAT_VECTORS, {DstTy, UnmergeSrcTy}}))

diff  --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index fdf69b04bf676..0dd680f9a58d9 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -1242,7 +1242,9 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
       .legalFor({{v16s8, v8s8}, {v8s16, v4s16}, {v4s32, v2s32}})
       .bitcastIf(
           [=](const LegalityQuery &Query) {
-            return Query.Types[0].getSizeInBits() <= 128 &&
+            return Query.Types[0].isFixedVector() &&
+                   Query.Types[1].isFixedVector() &&
+                   Query.Types[0].getSizeInBits() <= 128 &&
                    Query.Types[1].getSizeInBits() <= 64;
           },
           [=](const LegalityQuery &Query) {

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-unmerge-undef.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-unmerge-undef.mir
new file mode 100644
index 0000000000000..fe1986e44051b
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-unmerge-undef.mir
@@ -0,0 +1,72 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -o - -mtriple=aarch64 -run-pass=aarch64-postlegalizer-combiner -verify-machineinstrs %s | FileCheck %s
+---
+name:            non-vector-src
+legalized:       true
+body:             |
+  bb.0:
+    liveins: $w0
+
+    ; CHECK-LABEL: name: non-vector-src
+    ; CHECK: liveins: $w0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+    ; CHECK-NEXT: [[UV:%[0-9]+]]:_(s8), [[UV1:%[0-9]+]]:_(s8), [[UV2:%[0-9]+]]:_(s8), [[UV3:%[0-9]+]]:_(s8) = G_UNMERGE_VALUES [[COPY]](s32)
+    ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s8) = G_IMPLICIT_DEF
+    ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<8 x s8>) = G_BUILD_VECTOR [[UV]](s8), [[UV1]](s8), [[DEF]](s8), [[DEF]](s8), [[DEF]](s8), [[DEF]](s8), [[DEF]](s8), [[DEF]](s8)
+    ; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(<8 x s8>) = G_IMPLICIT_DEF
+    ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<8 x s8>) = G_SHUFFLE_VECTOR [[BUILD_VECTOR]](<8 x s8>), [[DEF1]], shufflemask(1, 0, 1, 0, undef, undef, undef, undef)
+    ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(<8 x s16>) = G_ANYEXT [[SHUF]](<8 x s8>)
+    ; CHECK-NEXT: [[UV4:%[0-9]+]]:_(<4 x s16>), [[UV5:%[0-9]+]]:_(<4 x s16>) = G_UNMERGE_VALUES [[ANYEXT]](<8 x s16>)
+    ; CHECK-NEXT: $d0 = COPY [[UV4]](<4 x s16>)
+    ; CHECK-NEXT: RET_ReallyLR implicit $d0
+    %1:_(s32) = COPY $w0
+    %30:_(s8), %31:_(s8), %32:_(s8), %33:_(s8) = G_UNMERGE_VALUES %1(s32)
+    %14:_(s8) = G_IMPLICIT_DEF
+    %15:_(<8 x s8>) = G_BUILD_VECTOR %30(s8), %31(s8), %14(s8), %14(s8), %14(s8), %14(s8), %14(s8), %14(s8)
+    %20:_(<8 x s8>) = G_BUILD_VECTOR %14(s8), %14(s8), %14(s8), %14(s8), %14(s8), %14(s8), %14(s8), %14(s8)
+    %21:_(<8 x s8>) = G_SHUFFLE_VECTOR %15(<8 x s8>), %20, shufflemask(1, 0, 1, 0, undef, undef, undef, undef)
+    %41:_(<8 x s16>) = G_ANYEXT %21(<8 x s8>)
+    %50:_(<4 x s16>), %51:_(<4 x s16>) = G_UNMERGE_VALUES %41(<8 x s16>)
+    $d0 = COPY %50(<4 x s16>)
+    RET_ReallyLR implicit $d0
+...
+---
+name:            v2-src
+legalized:       true
+body:             |
+  bb.0:
+    liveins: $q0
+
+    ; CHECK-LABEL: name: v2-src
+    ; CHECK: liveins: $q0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $x0
+    ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
+    ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<4 x s32>) = G_CONCAT_VECTORS [[COPY]](<2 x s32>), [[DEF]](<2 x s32>)
+    ; CHECK-NEXT: RET_ReallyLR implicit [[CONCAT_VECTORS]](<4 x s32>)
+    %1:_(<2 x s32>) = COPY $x0
+    %30:_(s32), %31:_(s32) = G_UNMERGE_VALUES %1(<2 x s32>)
+    %14:_(s32) = G_IMPLICIT_DEF
+    %15:_(<4 x s32>) = G_BUILD_VECTOR %30(s32), %31(s32), %14(s32), %14(s32)
+    RET_ReallyLR implicit %15
+...
+---
+name:            v4-src
+legalized:       true
+body:             |
+  bb.0:
+    liveins: $q0
+
+    ; CHECK-LABEL: name: v4-src
+    ; CHECK: liveins: $q0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s16>) = COPY $x0
+    ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<4 x s16>) = G_IMPLICIT_DEF
+    ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<8 x s16>) = G_CONCAT_VECTORS [[COPY]](<4 x s16>), [[DEF]](<4 x s16>)
+    ; CHECK-NEXT: RET_ReallyLR implicit [[CONCAT_VECTORS]](<8 x s16>)
+    %1:_(<4 x s16>) = COPY $x0
+    %30:_(s16), %31:_(s16), %32:_(s16), %33:_(s16) = G_UNMERGE_VALUES %1(<4 x s16>)
+    %14:_(s16) = G_IMPLICIT_DEF
+    %15:_(<8 x s16>) = G_BUILD_VECTOR %30(s16), %31(s16), %32(s16), %33(s16), %14(s16), %14(s16), %14(s16), %14(s16)
+    RET_ReallyLR implicit %15


        


More information about the llvm-commits mailing list