[llvm] [AArch64][GlobalISel] Improve lowering of vector fp16 fptrunc and fpext (PR #163398)

Ryan Cowan via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 29 03:57:53 PDT 2025


================
@@ -133,6 +137,97 @@ bool isZeroExtended(Register R, MachineRegisterInfo &MRI) {
   return MRI.getVRegDef(R)->getOpcode() == TargetOpcode::G_ZEXT;
 }
 
+// This patten 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(
+//   G_BUILD_VECTOR(
+//     G_IMPLICIT_DEF
+//     G_IMPLICIT_DEF
+//   )
+//   src
+// )
+bool matchCombineBuildUnmerge(MachineInstr &MI, MachineRegisterInfo &MRI,
+                              SmallVectorImpl<Register> &UnmergeSrc,
+                              SmallVectorImpl<Register> &UndefinedValues) {
+  assert(MI.getOpcode() == TargetOpcode::G_BUILD_VECTOR);
+
+  UndefinedValues.clear();
+  UnmergeSrc.clear();
+
+  std::set<int> KnownRegs;
+
+  for (auto Use : MI.all_uses()) {
+    auto *Def = getDefIgnoringCopies(Use.getReg(), MRI);
+
+    if (!Def) {
+      UndefinedValues.clear();
+      UnmergeSrc.clear();
+      return false;
+    }
+
+    auto Opcode = Def->getOpcode();
+
+    switch (Opcode) {
+    default:
+      return false;
+    case TargetOpcode::G_IMPLICIT_DEF:
+      UndefinedValues.push_back(Use.getReg());
+      break;
+    case TargetOpcode::G_UNMERGE_VALUES:
+      // We only want to match G_UNMERGE_VALUES <2 x Ty>
+      // s16 is troublesome as <2 x s16> is generally not legal
----------------
HolyMolyCowMan wrote:

I opted for checking that `EltCount * EltSize = 64` to avoid defining the types but happy to change to using the types if preferable. 

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


More information about the llvm-commits mailing list