[llvm] 152c9d5 - MC: Sink FKF_IsAlignedDownTo32Bits to needed targets

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 5 11:11:11 PDT 2025


Author: Fangrui Song
Date: 2025-07-05T11:11:07-07:00
New Revision: 152c9d577c41ac45a85bc555b56a3c4a2046ec5b

URL: https://github.com/llvm/llvm-project/commit/152c9d577c41ac45a85bc555b56a3c4a2046ec5b
DIFF: https://github.com/llvm/llvm-project/commit/152c9d577c41ac45a85bc555b56a3c4a2046ec5b.diff

LOG: MC: Sink FKF_IsAlignedDownTo32Bits to needed targets

Utilize the generalized MCAsmBackend::evaluateFixup hook. This reduces
overhead for other targets (e.g., x86).

Now MCAsmBackend::getFixupKindInfo is only used by MCAsmStreamer
-show-encoding in the generic code.

Added: 
    

Modified: 
    llvm/include/llvm/MC/MCAsmBackend.h
    llvm/lib/MC/MCAssembler.cpp
    llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
    llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
    llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp
    llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
    llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/MC/MCAsmBackend.h b/llvm/include/llvm/MC/MCAsmBackend.h
index fae7fba8e8274..bfec916c9bf3a 100644
--- a/llvm/include/llvm/MC/MCAsmBackend.h
+++ b/llvm/include/llvm/MC/MCAsmBackend.h
@@ -41,14 +41,6 @@ class raw_ostream;
 
 /// Target independent information on a fixup kind.
 struct MCFixupKindInfo {
-  enum FixupKindFlags {
-    /// Should this fixup kind force a 4-byte aligned effective PC value?
-    FKF_IsAlignedDownTo32Bits = (1 << 1),
-
-    /// Should this fixup be evaluated in a target dependent manner?
-    FKF_IsTarget = (1 << 2),
-  };
-
   /// A target specific name for the fixup kind. The names will be unique for
   /// distinct kinds on any given target.
   const char *Name;
@@ -134,8 +126,8 @@ class LLVM_ABI MCAsmBackend {
   // Evaluate a fixup, returning std::nullopt to use default handling for
   // `Value` and `IsResolved`. Otherwise, returns `IsResolved` with the
   // expectation that the hook updates `Value`.
-  virtual std::optional<bool> evaluateFixup(MCFixup &Fixup, MCValue &Target,
-                                            uint64_t &Value) {
+  virtual std::optional<bool> evaluateFixup(const MCFragment &, MCFixup &,
+                                            MCValue &, uint64_t &) {
     return {};
   }
 

diff  --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index e02fcb1e77f92..ae41abd650f7a 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -161,38 +161,26 @@ bool MCAssembler::evaluateFixup(const MCFragment &F, MCFixup &Fixup,
     return true;
   }
 
-  unsigned FixupFlags = getBackend().getFixupKindInfo(Fixup.getKind()).Flags;
   bool IsResolved = false;
-  if (auto State = getBackend().evaluateFixup(Fixup, Target, Value)) {
+  if (auto State = getBackend().evaluateFixup(F, Fixup, Target, Value)) {
     IsResolved = *State;
   } else {
     const MCSymbol *Add = Target.getAddSym();
     const MCSymbol *Sub = Target.getSubSym();
-    Value = Target.getConstant();
+    Value += Target.getConstant();
     if (Add && Add->isDefined())
       Value += getSymbolOffset(*Add);
     if (Sub && Sub->isDefined())
       Value -= getSymbolOffset(*Sub);
 
-    bool ShouldAlignPC =
-        FixupFlags & MCFixupKindInfo::FKF_IsAlignedDownTo32Bits;
     if (Fixup.isPCRel()) {
-      uint64_t Offset = getFragmentOffset(F) + Fixup.getOffset();
-
-      // A number of ARM fixups in Thumb mode require that the effective PC
-      // address be determined as the 32-bit aligned version of the actual
-      // offset.
-      if (ShouldAlignPC)
-        Offset &= ~0x3;
-      Value -= Offset;
-
+      Value -= getFragmentOffset(F) + Fixup.getOffset();
       if (Add && !Sub && !Add->isUndefined() && !Add->isAbsolute()) {
         IsResolved = getWriter().isSymbolRefDifferenceFullyResolvedImpl(
             *Add, F, false, true);
       }
     } else {
       IsResolved = Target.isAbsolute();
-      assert(!ShouldAlignPC && "FKF_IsAlignedDownTo32Bits must be PC-relative");
     }
   }
 

diff  --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index d360be8aa1759..ca6d59d63b625 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -71,19 +71,16 @@ MCFixupKindInfo ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
       //
       // Name                      Offset (bits) Size (bits)     Flags
       {"fixup_arm_ldst_pcrel_12", 0, 32, 0},
-      {"fixup_t2_ldst_pcrel_12", 0, 32,
-       MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+      {"fixup_t2_ldst_pcrel_12", 0, 32, 0},
       {"fixup_arm_pcrel_10_unscaled", 0, 32, 0},
       {"fixup_arm_pcrel_10", 0, 32, 0},
-      {"fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+      {"fixup_t2_pcrel_10", 0, 32, 0},
       {"fixup_arm_pcrel_9", 0, 32, 0},
-      {"fixup_t2_pcrel_9", 0, 32, MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+      {"fixup_t2_pcrel_9", 0, 32, 0},
       {"fixup_arm_ldst_abs_12", 0, 32, 0},
-      {"fixup_thumb_adr_pcrel_10", 0, 8,
-       MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+      {"fixup_thumb_adr_pcrel_10", 0, 8, 0},
       {"fixup_arm_adr_pcrel_12", 0, 32, 0},
-      {"fixup_t2_adr_pcrel_12", 0, 32,
-       MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+      {"fixup_t2_adr_pcrel_12", 0, 32, 0},
       {"fixup_arm_condbranch", 0, 24, 0},
       {"fixup_arm_uncondbranch", 0, 24, 0},
       {"fixup_t2_condbranch", 0, 32, 0},
@@ -93,10 +90,9 @@ MCFixupKindInfo ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
       {"fixup_arm_condbl", 0, 24, 0},
       {"fixup_arm_blx", 0, 24, 0},
       {"fixup_arm_thumb_bl", 0, 32, 0},
-      {"fixup_arm_thumb_blx", 0, 32,
-       MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+      {"fixup_arm_thumb_blx", 0, 32, 0},
       {"fixup_arm_thumb_cb", 0, 16, 0},
-      {"fixup_arm_thumb_cp", 0, 8, MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+      {"fixup_arm_thumb_cp", 0, 8, 0},
       {"fixup_arm_thumb_bcc", 0, 8, 0},
       // movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16
       // - 19.
@@ -124,19 +120,16 @@ MCFixupKindInfo ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
       //
       // Name                      Offset (bits) Size (bits)     Flags
       {"fixup_arm_ldst_pcrel_12", 0, 32, 0},
-      {"fixup_t2_ldst_pcrel_12", 0, 32,
-       MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+      {"fixup_t2_ldst_pcrel_12", 0, 32, 0},
       {"fixup_arm_pcrel_10_unscaled", 0, 32, 0},
       {"fixup_arm_pcrel_10", 0, 32, 0},
-      {"fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+      {"fixup_t2_pcrel_10", 0, 32, 0},
       {"fixup_arm_pcrel_9", 0, 32, 0},
-      {"fixup_t2_pcrel_9", 0, 32, MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+      {"fixup_t2_pcrel_9", 0, 32, 0},
       {"fixup_arm_ldst_abs_12", 0, 32, 0},
-      {"fixup_thumb_adr_pcrel_10", 8, 8,
-       MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+      {"fixup_thumb_adr_pcrel_10", 8, 8, 0},
       {"fixup_arm_adr_pcrel_12", 0, 32, 0},
-      {"fixup_t2_adr_pcrel_12", 0, 32,
-       MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+      {"fixup_t2_adr_pcrel_12", 0, 32, 0},
       {"fixup_arm_condbranch", 8, 24, 0},
       {"fixup_arm_uncondbranch", 8, 24, 0},
       {"fixup_t2_condbranch", 0, 32, 0},
@@ -146,10 +139,9 @@ MCFixupKindInfo ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
       {"fixup_arm_condbl", 8, 24, 0},
       {"fixup_arm_blx", 8, 24, 0},
       {"fixup_arm_thumb_bl", 0, 32, 0},
-      {"fixup_arm_thumb_blx", 0, 32,
-       MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+      {"fixup_arm_thumb_blx", 0, 32, 0},
       {"fixup_arm_thumb_cb", 0, 16, 0},
-      {"fixup_arm_thumb_cp", 8, 8, MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+      {"fixup_arm_thumb_cp", 8, 8, 0},
       {"fixup_arm_thumb_bcc", 8, 8, 0},
       // movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16
       // - 19.
@@ -1106,6 +1098,25 @@ static unsigned getFixupKindContainerSizeBytes(unsigned Kind) {
   }
 }
 
+std::optional<bool> ARMAsmBackend::evaluateFixup(const MCFragment &F,
+                                                 MCFixup &Fixup, MCValue &,
+                                                 uint64_t &Value) {
+  // For a few PC-relative fixups in Thumb mode, offsets need to be aligned
+  // down. We compensate here because the default handler's `Value` decrement
+  // doesn't account for this alignment.
+  switch (Fixup.getTargetKind()) {
+  case ARM::fixup_t2_ldst_pcrel_12:
+  case ARM::fixup_t2_pcrel_10:
+  case ARM::fixup_t2_pcrel_9:
+  case ARM::fixup_thumb_adr_pcrel_10:
+  case ARM::fixup_t2_adr_pcrel_12:
+  case ARM::fixup_arm_thumb_blx:
+  case ARM::fixup_arm_thumb_cp:
+    Value = (Asm->getFragmentOffset(F) + Fixup.getOffset()) % 4;
+  }
+  return {};
+}
+
 void ARMAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
                                const MCValue &Target,
                                MutableArrayRef<char> Data, uint64_t Value,

diff  --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
index fce97c4291c51..52279a3b6936f 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
@@ -37,6 +37,8 @@ class ARMAsmBackend : public MCAsmBackend {
                             bool IsResolved, MCContext &Ctx,
                             const MCSubtargetInfo *STI) const;
 
+  std::optional<bool> evaluateFixup(const MCFragment &, MCFixup &, MCValue &,
+                                    uint64_t &) override;
   void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target,
                   MutableArrayRef<char> Data, uint64_t Value,
                   bool IsResolved) override;

diff  --git a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp
index 735d222c074fc..37c17e2ce5005 100644
--- a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp
+++ b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp
@@ -34,11 +34,9 @@ MCFixupKindInfo CSKYAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
       {CSKY::Fixups::fixup_csky_pcrel_imm16_scale2,
        {"fixup_csky_pcrel_imm16_scale2", 0, 32, 0}},
       {CSKY::Fixups::fixup_csky_pcrel_uimm16_scale4,
-       {"fixup_csky_pcrel_uimm16_scale4", 0, 32,
-        MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}},
+       {"fixup_csky_pcrel_uimm16_scale4", 0, 32, 0}},
       {CSKY::Fixups::fixup_csky_pcrel_uimm8_scale4,
-       {"fixup_csky_pcrel_uimm8_scale4", 0, 32,
-        MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}},
+       {"fixup_csky_pcrel_uimm8_scale4", 0, 32, 0}},
       {CSKY::Fixups::fixup_csky_pcrel_imm26_scale2,
        {"fixup_csky_pcrel_imm26_scale2", 0, 32, 0}},
       {CSKY::Fixups::fixup_csky_pcrel_imm18_scale2,
@@ -54,8 +52,7 @@ MCFixupKindInfo CSKYAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
       {CSKY::Fixups::fixup_csky_pcrel_imm10_scale2,
        {"fixup_csky_pcrel_imm10_scale2", 0, 16, 0}},
       {CSKY::Fixups::fixup_csky_pcrel_uimm7_scale4,
-       {"fixup_csky_pcrel_uimm7_scale4", 0, 16,
-        MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}},
+       {"fixup_csky_pcrel_uimm7_scale4", 0, 16, 0}},
       {CSKY::Fixups::fixup_csky_doffset_imm18,
        {"fixup_csky_doffset_imm18", 0, 18, 0}},
       {CSKY::Fixups::fixup_csky_doffset_imm18_scale2,
@@ -184,6 +181,21 @@ bool CSKYAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup,
   }
 }
 
+std::optional<bool> CSKYAsmBackend::evaluateFixup(const MCFragment &F,
+                                                  MCFixup &Fixup, MCValue &,
+                                                  uint64_t &Value) {
+  // For a few PC-relative fixups, offsets need to be aligned down. We
+  // compensate here because the default handler's `Value` decrement doesn't
+  // account for this alignment.
+  switch (Fixup.getTargetKind()) {
+  case CSKY::fixup_csky_pcrel_uimm16_scale4:
+  case CSKY::fixup_csky_pcrel_uimm8_scale4:
+  case CSKY::fixup_csky_pcrel_uimm7_scale4:
+    Value = (Asm->getFragmentOffset(F) + Fixup.getOffset()) % 4;
+  }
+  return {};
+}
+
 void CSKYAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
                                 const MCValue &Target,
                                 MutableArrayRef<char> Data, uint64_t Value,

diff  --git a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h
index c0eff853d87bd..142c667a6175e 100644
--- a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h
+++ b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h
@@ -22,6 +22,8 @@ class CSKYAsmBackend : public MCAsmBackend {
   CSKYAsmBackend(const MCSubtargetInfo &STI, const MCTargetOptions &OP)
       : MCAsmBackend(llvm::endianness::little) {}
 
+  std::optional<bool> evaluateFixup(const MCFragment &, MCFixup &, MCValue &,
+                                    uint64_t &) override;
   void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target,
                   MutableArrayRef<char> Data, uint64_t Value,
                   bool IsResolved) override;

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index ce0d030031cdb..1b7c2a934c497 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -655,7 +655,8 @@ static const MCFixup *getPCRelHiFixup(const MCSpecifierExpr &Expr,
   return nullptr;
 }
 
-std::optional<bool> RISCVAsmBackend::evaluateFixup(MCFixup &Fixup,
+std::optional<bool> RISCVAsmBackend::evaluateFixup(const MCFragment &,
+                                                   MCFixup &Fixup,
                                                    MCValue &Target,
                                                    uint64_t &Value) {
   const MCFixup *AUIPCFixup;

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
index 292cacdbd45af..6f75fcae8c5c0 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
@@ -47,9 +47,8 @@ class RISCVAsmBackend : public MCAsmBackend {
   bool shouldInsertFixupForCodeAlign(MCAssembler &Asm,
                                      MCAlignFragment &AF) override;
 
-  std::optional<bool> evaluateFixup(MCFixup &Fixup, MCValue &Target,
-                                    uint64_t &Value) override;
-
+  std::optional<bool> evaluateFixup(const MCFragment &, MCFixup &, MCValue &,
+                                    uint64_t &) override;
   bool addReloc(const MCFragment &, const MCFixup &, const MCValue &,
                 uint64_t &FixedValue, bool IsResolved);
 

diff  --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp
index 54861b7a0ad65..a2a418312f5de 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp
@@ -16,6 +16,7 @@
 #include "llvm/MC/MCInst.h"
 #include "llvm/MC/MCObjectWriter.h"
 #include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCValue.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace llvm;
@@ -34,6 +35,8 @@ class XtensaAsmBackend : public MCAsmBackend {
         IsLittleEndian(isLE) {}
 
   MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override;
+  std::optional<bool> evaluateFixup(const MCFragment &, MCFixup &, MCValue &,
+                                    uint64_t &) override;
   void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target,
                   MutableArrayRef<char> Data, uint64_t Value,
                   bool IsResolved) override;
@@ -57,10 +60,8 @@ MCFixupKindInfo XtensaAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
       {"fixup_xtensa_branch_8", 16, 8, 0},
       {"fixup_xtensa_branch_12", 12, 12, 0},
       {"fixup_xtensa_jump_18", 6, 18, 0},
-      {"fixup_xtensa_call_18", 6, 18,
-       MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
-      {"fixup_xtensa_l32r_16", 8, 16,
-       MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+      {"fixup_xtensa_call_18", 6, 18, 0},
+      {"fixup_xtensa_l32r_16", 8, 16, 0},
       {"fixup_xtensa_loop_8", 16, 8, 0},
   };
 
@@ -142,6 +143,20 @@ static unsigned getSize(unsigned Kind) {
   }
 }
 
+std::optional<bool> XtensaAsmBackend::evaluateFixup(const MCFragment &F,
+                                                    MCFixup &Fixup, MCValue &,
+                                                    uint64_t &Value) {
+  // For a few PC-relative fixups, offsets need to be aligned down. We
+  // compensate here because the default handler's `Value` decrement doesn't
+  // account for this alignment.
+  switch (Fixup.getTargetKind()) {
+  case Xtensa::fixup_xtensa_call_18:
+  case Xtensa::fixup_xtensa_l32r_16:
+    Value = (Asm->getFragmentOffset(F) + Fixup.getOffset()) % 4;
+  }
+  return {};
+}
+
 void XtensaAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
                                   const MCValue &Target,
                                   MutableArrayRef<char> Data, uint64_t Value,


        


More information about the llvm-commits mailing list