From 64fc9075a6e826690ac4e4f77ebc6cd4a04298ee Mon Sep 17 00:00:00 2001 From: Ryan Cowan Date: Wed, 19 Nov 2025 10:48:41 +0000 Subject: [PATCH 1/2] [AArch64][GlobalISel] Check unmergeSrc is a vector in matchCombineBuildUnmerge --- llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp | 3 +++ llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) 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..2ffdae7d51704 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp @@ -1243,7 +1243,9 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) .bitcastIf( [=](const LegalityQuery &Query) { return Query.Types[0].getSizeInBits() <= 128 && - Query.Types[1].getSizeInBits() <= 64; + Query.Types[1].getSizeInBits() <= 64 && + !Query.Types[0].isScalableVector() && + !Query.Types[1].isScalableVector(); }, [=](const LegalityQuery &Query) { const LLT DstTy = Query.Types[0]; From 8b151a836bc2dc5a2058c603d34efeb5fbcb0b83 Mon Sep 17 00:00:00 2001 From: Ryan Cowan Date: Wed, 19 Nov 2025 12:00:52 +0000 Subject: [PATCH 2/2] Change the order of the scalable vector checks & add some specific tests --- .../AArch64/GISel/AArch64LegalizerInfo.cpp | 8 +-- .../GlobalISel/combine-unmerge-undef.mir | 72 +++++++++++++++++++ 2 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/combine-unmerge-undef.mir diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp index 2ffdae7d51704..0dd680f9a58d9 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp @@ -1242,10 +1242,10 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) .legalFor({{v16s8, v8s8}, {v8s16, v4s16}, {v4s32, v2s32}}) .bitcastIf( [=](const LegalityQuery &Query) { - return Query.Types[0].getSizeInBits() <= 128 && - Query.Types[1].getSizeInBits() <= 64 && - !Query.Types[0].isScalableVector() && - !Query.Types[1].isScalableVector(); + return Query.Types[0].isFixedVector() && + Query.Types[1].isFixedVector() && + Query.Types[0].getSizeInBits() <= 128 && + Query.Types[1].getSizeInBits() <= 64; }, [=](const LegalityQuery &Query) { const LLT DstTy = Query.Types[0]; 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