[llvm] 9f49b77 - [NFC][AArch64] Extract MOVaddr* expansion model into common header (#183503)

via llvm-commits llvm-commits at lists.llvm.org
Wed May 13 05:41:40 PDT 2026


Author: Guy David
Date: 2026-05-13T15:41:35+03:00
New Revision: 9f49b779a34664220fb2895012aa50e8dbf19a6d

URL: https://github.com/llvm/llvm-project/commit/9f49b779a34664220fb2895012aa50e8dbf19a6d
DIFF: https://github.com/llvm/llvm-project/commit/9f49b779a34664220fb2895012aa50e8dbf19a6d.diff

LOG: [NFC][AArch64] Extract MOVaddr* expansion model into common header (#183503)

This makes the expansion logic reusable by getInstSizeInBytes in a
follow-up patch.

Added: 
    

Modified: 
    llvm/lib/Target/AArch64/AArch64ExpandImm.cpp
    llvm/lib/Target/AArch64/AArch64ExpandImm.h
    llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64ExpandImm.cpp b/llvm/lib/Target/AArch64/AArch64ExpandImm.cpp
index f44cb8a0628d7..04c217ca34f00 100644
--- a/llvm/lib/Target/AArch64/AArch64ExpandImm.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ExpandImm.cpp
@@ -720,3 +720,18 @@ void AArch64_IMM::expandMOVImm(uint64_t Imm, unsigned BitSize,
   // four-instruction sequence.
   expandMOVImmSimple(Imm, BitSize, OneChunks, ZeroChunks, Insn);
 }
+
+void AArch64_IMM::expandMOVAddr(unsigned Opcode, unsigned TargetFlags,
+                                bool IsTargetMachO,
+                                SmallVectorImpl<AddrInsnModel> &Insn) {
+  if (Opcode == AArch64::MOVaddrBA && IsTargetMachO) {
+    // Block address on Mach-O goes through a constant pool.
+    Insn.push_back({AArch64::ADRP});
+    Insn.push_back({AArch64::LDRXui});
+    return;
+  }
+  Insn.push_back({AArch64::ADRP});
+  if (TargetFlags & AArch64II::MO_TAGGED)
+    Insn.push_back({AArch64::MOVKXi});
+  Insn.push_back({AArch64::ADDXri});
+}

diff  --git a/llvm/lib/Target/AArch64/AArch64ExpandImm.h b/llvm/lib/Target/AArch64/AArch64ExpandImm.h
index 42c97d2c3e9b5..c3376520eb410 100644
--- a/llvm/lib/Target/AArch64/AArch64ExpandImm.h
+++ b/llvm/lib/Target/AArch64/AArch64ExpandImm.h
@@ -25,8 +25,15 @@ struct ImmInsnModel {
   uint64_t Op2;
 };
 
+struct AddrInsnModel {
+  unsigned Opcode;
+};
+
 void expandMOVImm(uint64_t Imm, unsigned BitSize,
-		  SmallVectorImpl<ImmInsnModel> &Insn);
+                  SmallVectorImpl<ImmInsnModel> &Insn);
+
+void expandMOVAddr(unsigned Opcode, unsigned TargetFlags, bool IsTargetMachO,
+                   SmallVectorImpl<AddrInsnModel> &Insn);
 
 } // end namespace AArch64_IMM
 

diff  --git a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
index 535f9e4fac8c5..5fa93da1544fc 100644
--- a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
@@ -1539,70 +1539,88 @@ bool AArch64ExpandPseudoImpl::expandMI(MachineBasicBlock &MBB,
     MI.eraseFromParent();
     return true;
   }
-  case AArch64::MOVaddrBA: {
-    MachineFunction &MF = *MI.getParent()->getParent();
-    if (MF.getSubtarget<AArch64Subtarget>().isTargetMachO()) {
-      // blockaddress expressions have to come from a constant pool because the
-      // largest addend (and hence offset within a function) allowed for ADRP is
-      // only 8MB.
-      const BlockAddress *BA = MI.getOperand(1).getBlockAddress();
-      assert(MI.getOperand(1).getOffset() == 0 && "unexpected offset");
-
-      MachineConstantPool *MCP = MF.getConstantPool();
-      unsigned CPIdx = MCP->getConstantPoolIndex(BA, Align(8));
-
-      Register DstReg = MI.getOperand(0).getReg();
-      auto MIB1 =
-          BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::ADRP), DstReg)
-              .addConstantPoolIndex(CPIdx, 0, AArch64II::MO_PAGE);
-      auto MIB2 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
-                          TII->get(AArch64::LDRXui), DstReg)
-                      .addUse(DstReg)
-                      .addConstantPoolIndex(
-                          CPIdx, 0, AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
-      transferImpOps(MI, MIB1, MIB2);
-      MI.eraseFromParent();
-      return true;
-    }
-  }
-    [[fallthrough]];
+  case AArch64::MOVaddrBA:
   case AArch64::MOVaddr:
   case AArch64::MOVaddrJT:
   case AArch64::MOVaddrCP:
   case AArch64::MOVaddrTLS:
   case AArch64::MOVaddrEXT: {
-    // Expand into ADRP + ADD.
+    MachineFunction &MF = *MI.getParent()->getParent();
     Register DstReg = MI.getOperand(0).getReg();
     assert(DstReg != AArch64::XZR);
-    MachineInstrBuilder MIB1 =
-        BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::ADRP), DstReg)
-            .add(MI.getOperand(1));
-
-    if (MI.getOperand(1).getTargetFlags() & AArch64II::MO_TAGGED) {
-      // MO_TAGGED on the page indicates a tagged address. Set the tag now.
-      // We do so by creating a MOVK that sets bits 48-63 of the register to
-      // (global address + 0x100000000 - PC) >> 48. This assumes that we're in
-      // the small code model so we can assume a binary size of <= 4GB, which
-      // makes the untagged PC relative offset positive. The binary must also be
-      // loaded into address range [0, 2^48). Both of these properties need to
-      // be ensured at runtime when using tagged addresses.
-      auto Tag = MI.getOperand(1);
-      Tag.setTargetFlags(AArch64II::MO_PREL | AArch64II::MO_G3);
-      Tag.setOffset(0x100000000);
-      BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::MOVKXi), DstReg)
-          .addReg(DstReg)
-          .add(Tag)
-          .addImm(48);
+
+    bool IsTargetMachO = MF.getSubtarget<AArch64Subtarget>().isTargetMachO();
+    SmallVector<AArch64_IMM::AddrInsnModel, 3> Insn;
+    AArch64_IMM::expandMOVAddr(
+        MI.getOpcode(), MI.getOperand(1).getTargetFlags(), IsTargetMachO, Insn);
+
+    // Compute the constant pool index, if any.
+    std::optional<unsigned> CPIdx;
+    if (Opcode == AArch64::MOVaddrBA && IsTargetMachO) {
+      // blockaddress expressions have to come from a constant pool because the
+      // largest addend (and hence offset within a function) allowed for ADRP is
+      // only 8MB.
+      const BlockAddress *BA = MI.getOperand(1).getBlockAddress();
+      assert(MI.getOperand(1).getOffset() == 0 && "unexpected offset");
+      MachineConstantPool *MCP = MF.getConstantPool();
+      CPIdx = MCP->getConstantPoolIndex(BA, Align(8));
     }
 
-    MachineInstrBuilder MIB2 =
-        BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::ADDXri))
-            .add(MI.getOperand(0))
-            .addReg(DstReg)
-            .add(MI.getOperand(2))
-            .addImm(0);
+    MachineInstrBuilder FirstMIB;
+    MachineInstrBuilder LastMIB;
+    for (const auto &I : Insn) {
+      MachineInstrBuilder MIB;
+      switch (I.Opcode) {
+      case AArch64::ADRP:
+        MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::ADRP),
+                      DstReg);
+        if (CPIdx)
+          MIB.addConstantPoolIndex(*CPIdx, 0, AArch64II::MO_PAGE);
+        else
+          MIB.add(MI.getOperand(1));
+        break;
+      case AArch64::LDRXui:
+        MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::LDRXui),
+                      DstReg)
+                  .addUse(DstReg)
+                  .addConstantPoolIndex(
+                      *CPIdx, 0, AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
+        break;
+      case AArch64::MOVKXi: {
+        // MO_TAGGED on the page indicates a tagged address. Set the tag now.
+        // We do so by creating a MOVK that sets bits 48-63 of the register to
+        // (global address + 0x100000000 - PC) >> 48. This assumes that we're in
+        // the small code model so we can assume a binary size of <= 4GB, which
+        // makes the untagged PC relative offset positive. The binary must also
+        // be loaded into address range [0, 2^48). Both of these properties need
+        // to be ensured at runtime when using tagged addresses.
+        auto Tag = MI.getOperand(1);
+        Tag.setTargetFlags(AArch64II::MO_PREL | AArch64II::MO_G3);
+        Tag.setOffset(0x100000000);
+        MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::MOVKXi),
+                      DstReg)
+                  .addReg(DstReg)
+                  .add(Tag)
+                  .addImm(48);
+        break;
+      }
+      case AArch64::ADDXri:
+        MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::ADDXri))
+                  .add(MI.getOperand(0))
+                  .addReg(DstReg)
+                  .add(MI.getOperand(2))
+                  .addImm(0);
+        break;
+      default:
+        llvm_unreachable("unexpected opcode in MOVaddr expansion");
+      }
+
+      if (!FirstMIB.getInstr())
+        FirstMIB = MIB;
+      LastMIB = MIB;
+    }
 
-    transferImpOps(MI, MIB1, MIB2);
+    transferImpOps(MI, FirstMIB, LastMIB);
     MI.eraseFromParent();
     return true;
   }


        


More information about the llvm-commits mailing list