[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 02:29:52 PDT 2025
================
@@ -133,6 +134,99 @@ 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(
+// undef
+// src
+// )
+bool matchCombineBuildUnmerge(MachineInstr &MI, MachineRegisterInfo &MRI,
+ Register &UnmergeSrc) {
+ assert(MI.getOpcode() == TargetOpcode::G_BUILD_VECTOR);
+
+ unsigned UnmergeInstrCount = 0;
+ unsigned UndefInstrCount = 0;
+
+ unsigned UnmergeEltCount = 0;
+ unsigned UnmergeEltSize = 0;
+
+ Register UnmergeSrcTemp;
+
+ std::set<int> KnownRegs;
+
+ for (auto Use : MI.all_uses()) {
+ auto *Def = getDefIgnoringCopies(Use.getReg(), MRI);
+
+ if (!Def) {
+ return false;
+ }
+
+ unsigned Opcode = Def->getOpcode();
+
+ switch (Opcode) {
+ default:
+ return false;
+ case TargetOpcode::G_IMPLICIT_DEF:
+ ++UndefInstrCount;
+ break;
+ case TargetOpcode::G_UNMERGE_VALUES:
----------------
davemgreen wrote:
What would happen if we had this?
```
// G_BUILD_VECTOR(
// G_UNMERGE_VALUES(src, 0)
// G_IMPLICIT_DEF
// G_UNMERGE_VALUES(src, 1)
// G_IMPLICIT_DEF
// )
```
or
```
// G_BUILD_VECTOR(
// G_UNMERGE_VALUES(src, 1)
// G_UNMERGE_VALUES(src, 0)
// G_IMPLICIT_DEF
// G_IMPLICIT_DEF
// )
```
I believe it needs to check that the first operand is an unmerge from def 0, the remaining n/2-1 operands are the same unmerge from the correct def number, and the remaining n2/defs are undef.
https://github.com/llvm/llvm-project/pull/165539
More information about the llvm-commits
mailing list