[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
Thu Oct 30 09:41:13 PDT 2025


================
@@ -133,6 +134,123 @@ bool isZeroExtended(Register R, MachineRegisterInfo &MRI) {
   return MRI.getVRegDef(R)->getOpcode() == TargetOpcode::G_ZEXT;
 }
 
+// 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 matchCombineBuildUnmerge(MachineInstr &MI, MachineRegisterInfo &MRI,
+                              Register &UnmergeSrc) {
+  assert(MI.getOpcode() == TargetOpcode::G_BUILD_VECTOR);
+
+  unsigned UnmergeUseCount = 0;
+  unsigned UndefInstrCount = 0;
+
+  unsigned UnmergeEltCount = 0;
+  unsigned UnmergeEltSize = 0;
+
+  unsigned BuildOperandCount = MI.getNumOperands();
+  bool EncounteredUndef = false;
+
+  Register UnmergeSrcTemp;
+  MachineInstr *UnmergeInstr;
+
+  std::set<int> KnownRegs;
----------------
davemgreen wrote:

I'm not sure this is ever incorrect, but could it be simpler?
 - First check the first operand is a G_UNMERGE_VALUES.
 - Loop over the others in the first half (like you have for OperandIndex loop), checking the getDefIgnoringCopies is the same instruction and the operand num is the right registerr.
 - Loop over the rest, checking for implicit_def.

It should help simplify some of these variables and sets.

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


More information about the llvm-commits mailing list