Index: llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h =================================================================== --- llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h +++ llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h @@ -42,11 +42,18 @@ void setForceRelocs() { ForceRelocs = true; } + // Returns true if relocations will be forced for shouldForceRelocation by + // default. This will be true if relaxation is enabled or had previously + // been enabled. + bool willForceRelocations() const { + return ForceRelocs || STI.getFeatureBits()[RISCV::FeatureRelax]; + } + // Generate diff expression relocations if the relax feature is enabled or had // previously been enabled, otherwise it is safe for the assembler to // calculate these internally. bool requiresDiffExpressionRelocations() const override { - return STI.getFeatureBits()[RISCV::FeatureRelax] || ForceRelocs; + return willForceRelocations(); } // Return Size with extra Nop Bytes for alignment directive in code section. Index: llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp =================================================================== --- llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp +++ llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp @@ -11,9 +11,11 @@ // //===----------------------------------------------------------------------===// -#include "RISCV.h" #include "RISCVMCExpr.h" +#include "MCTargetDesc/RISCVAsmBackend.h" +#include "RISCV.h" #include "RISCVFixupKinds.h" +#include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCStreamer.h" @@ -87,6 +89,16 @@ // ( + ). The Fixup // is pcrel relative to the VK_RISCV_PCREL_LO fixup, so we need to add the // offset to the VK_RISCV_PCREL_HI Fixup from VK_RISCV_PCREL_LO to correct. + + // Don't try to evaluate if the fixup will be forced as a relocation (e.g. + // as linker relaxation is enabled). If we evaluated pcrel_lo in this case, + // the modified fixup will be converted into a relocation that no longer + // points to the pcrel_hi as the linker requires. + auto &RAB = + static_cast(Layout->getAssembler().getBackend()); + if (RAB.willForceRelocations()) + return false; + MCValue AUIPCLoc; if (!getSubExpr()->evaluateAsValue(AUIPCLoc, *Layout)) return false; Index: llvm/trunk/test/MC/RISCV/linker-relaxation.s =================================================================== --- llvm/trunk/test/MC/RISCV/linker-relaxation.s +++ llvm/trunk/test/MC/RISCV/linker-relaxation.s @@ -121,14 +121,10 @@ # RELAX-FIXUP: fixup A - offset: 0, value: %pcrel_hi(bar), kind: fixup_riscv_pcrel_hi20 # RELAX-FIXUP: fixup B - offset: 0, value: 0, kind: fixup_riscv_relax -# TODO/FIXME: The generated PCREL_LO relocations are incorrect. -# RISCVMCExpr::evaluatePCRelLo should not be evaluating the fixup when linker -# relaxation is enabled. - addi t1, t1, %pcrel_lo(2b) # NORELAX-RELOC-NOT: R_RISCV_PCREL_LO12_I # NORELAX-RELOC-NOT: R_RISCV_RELAX -# RELAX-RELOC: R_RISCV_PCREL_LO12_I bar 0x4 +# RELAX-RELOC: R_RISCV_PCREL_LO12_I .Ltmp1 0x0 # RELAX-RELOC: R_RISCV_RELAX - 0x0 # RELAX-FIXUP: fixup A - offset: 0, value: %pcrel_lo(.Ltmp1), kind: fixup_riscv_pcrel_lo12_i # RELAX-FIXUP: fixup B - offset: 0, value: 0, kind: fixup_riscv_relax @@ -136,7 +132,7 @@ sb t1, %pcrel_lo(2b)(a2) # NORELAX-RELOC-NOT: R_RISCV_PCREL_LO12_S # NORELAX-RELOC-NOT: R_RISCV_RELAX -# RELAX-RELOC: R_RISCV_PCREL_LO12_S bar 0x8 +# RELAX-RELOC: R_RISCV_PCREL_LO12_S .Ltmp1 0x0 # RELAX-RELOC: R_RISCV_RELAX - 0x0 # RELAX-FIXUP: fixup A - offset: 0, value: %pcrel_lo(.Ltmp1), kind: fixup_riscv_pcrel_lo12_s # RELAX-FIXUP: fixup B - offset: 0, value: 0, kind: fixup_riscv_relax Index: llvm/trunk/test/MC/RISCV/option-relax.s =================================================================== --- llvm/trunk/test/MC/RISCV/option-relax.s +++ llvm/trunk/test/MC/RISCV/option-relax.s @@ -64,3 +64,9 @@ jal zero, .L1 # CHECK-RELOC-NEXT: R_RISCV_BRANCH beq s1, s1, .L1 + +1: +# CHECK-RELOC-NEXT: R_RISCV_PCREL_HI20 .L1 +auipc t1, %pcrel_hi(.L1) +# CHECK-RELOC-NEXT: R_RISCV_PCREL_LO12_I .Ltmp0 +addi t1, t1, %pcrel_lo(1b)