@@ -104,9 +104,8 @@ MCFixupKindInfo RISCVAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
104104 return Infos[Kind - FirstTargetFixupKind];
105105}
106106
107- // If linker relaxation is enabled, or the relax option had previously been
108- // enabled, always emit relocations even if the fixup can be resolved. This is
109- // necessary for correctness as offsets may change during relaxation.
107+ // If linker relaxation is enabled, emit relocation to mark the instruction as
108+ // shrinkable by the linker.
110109bool RISCVAsmBackend::shouldForceRelocation (const MCAssembler &Asm,
111110 const MCFixup &Fixup,
112111 const MCValue &Target,
@@ -124,7 +123,7 @@ bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
124123 break ;
125124 }
126125
127- return STI->hasFeature (RISCV::FeatureRelax) || ForceRelocs ;
126+ return STI->hasFeature (RISCV::FeatureRelax);
128127}
129128
130129bool RISCVAsmBackend::fixupNeedsRelaxationAdvanced (const MCAssembler &,
@@ -570,6 +569,18 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
570569 }
571570}
572571
572+ bool RISCVAsmBackend::isPCRelFixupResolved (const MCAssembler &Asm,
573+ const MCSymbol *SymA,
574+ const MCFragment &F) {
575+ if (!PCRelTemp)
576+ PCRelTemp = Asm.getContext ().createTempSymbol ();
577+ PCRelTemp->setFragment (const_cast <MCFragment *>(&F));
578+ MCValue Res;
579+ MCExpr::evaluateSymbolicAdd (&Asm, false , MCValue::get (SymA),
580+ MCValue::get (nullptr , PCRelTemp), Res);
581+ return !Res.getSubSym ();
582+ }
583+
573584bool RISCVAsmBackend::evaluateTargetFixup (
574585 const MCAssembler &Asm, const MCFixup &Fixup, const MCFragment *DF,
575586 const MCValue &Target, const MCSubtargetInfo *STI, uint64_t &Value) {
@@ -613,7 +624,9 @@ bool RISCVAsmBackend::evaluateTargetFixup(
613624 Value = Asm.getSymbolOffset (SA) + AUIPCTarget.getConstant ();
614625 Value -= Asm.getFragmentOffset (*AUIPCDF) + AUIPCFixup->getOffset ();
615626
616- return AUIPCFixup->getTargetKind () == RISCV::fixup_riscv_pcrel_hi20;
627+ if (AUIPCFixup->getTargetKind () != RISCV::fixup_riscv_pcrel_hi20)
628+ return false ;
629+ return isPCRelFixupResolved (Asm, AUIPCTarget.getAddSym (), *AUIPCDF);
617630}
618631
619632bool RISCVAsmBackend::addReloc (MCAssembler &Asm, const MCFragment &F,
@@ -659,11 +672,14 @@ bool RISCVAsmBackend::addReloc(MCAssembler &Asm, const MCFragment &F,
659672 return false ;
660673 }
661674
675+ if (IsResolved &&
676+ (getFixupKindInfo (Fixup.getKind ()).Flags & MCFixupKindInfo::FKF_IsPCRel))
677+ IsResolved = isPCRelFixupResolved (Asm, Target.getAddSym (), F);
662678 IsResolved = MCAsmBackend::addReloc (Asm, F, Fixup, Target, FixedValue,
663679 IsResolved, STI);
664680 // If linker relaxation is enabled and supported by the current relocation,
665681 // append a RELAX relocation.
666- if (Fixup.needsRelax ()) {
682+ if (!IsResolved && Fixup.needsRelax ()) {
667683 auto FA = MCFixup::create (Fixup.getOffset (), nullptr , ELF::R_RISCV_RELAX);
668684 Asm.getWriter ().recordRelocation (Asm, &F, FA, MCValue::get (nullptr ),
669685 FixedValueA);
0 commit comments