[llvm] [AArch64][GlobalISel] Add combine for build_vector(unmerge, unmerge, undef, undef) (PR #165539)

David Green via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 5 10:04:38 PST 2025


================
@@ -3463,6 +3464,89 @@ static bool isConstValidTrue(const TargetLowering &TLI, unsigned ScalarSizeBits,
          isConstTrueVal(TLI, Cst, IsVector, IsFP);
 }
 
+// This pattern aims to match the following shape to avoid extra mov
+// instructions
+// G_BUILD_VECTOR(
+//   G_UNMERGE_VALUES(src, 0)
+//   G_UNMERGE_VALUES(src, 1)
+//   G_IMPLICIT_DEF
+//   G_IMPLICIT_DEF
+// )
+// ->
+// G_CONCAT_VECTORS(
+//   src,
+//   undef
+// )
+bool CombinerHelper::matchCombineBuildUnmerge(MachineInstr &MI,
+                                              MachineRegisterInfo &MRI,
+                                              Register &UnmergeSrc) const {
+  assert(MI.getOpcode() == TargetOpcode::G_BUILD_VECTOR);
+
+  unsigned BuildUseCount = MI.getNumOperands() - 1;
+
+  if (BuildUseCount % 2 != 0)
+    return false;
+
+  unsigned NumUnmerge = BuildUseCount / 2;
+
+  // Check the first operand is an unmerge
+  auto *MaybeUnmerge = getDefIgnoringCopies(MI.getOperand(1).getReg(), MRI);
+  if (MaybeUnmerge->getOpcode() != TargetOpcode::G_UNMERGE_VALUES)
+    return false;
+
+  LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
+  LLT UnmergeSrcTy = MRI.getType(
+      MaybeUnmerge->getOperand(MaybeUnmerge->getNumOperands() - 1).getReg());
+
+  // Ensure we only generate legal instructions post-legalizer
+  if (!IsPreLegalize && !isLegal({TargetOpcode::G_CONCAT_VECTORS,
+                                  {DstTy, UnmergeSrcTy, UnmergeSrcTy}}))
----------------
davemgreen wrote:

I think just `{DstTy, UnmergeSrcTy}`, as all the other operands types need to be the same.

https://github.com/llvm/llvm-project/pull/165539


More information about the llvm-commits mailing list