From 3f5976c97dbfefb4669abcf968bd79a9a64c18e0 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Thu, 23 Jan 2020 02:05:46 +0000 Subject: [PATCH] [RISCV] Fix evaluating %pcrel_lo against global and weak symbols Summary: Previously, we would erroneously turn %pcrel_lo(label), where label has a %pcrel_hi against a weak symbol, into %pcrel_lo(label + offset), as evaluatePCRelLo would believe the target independent logic was going to fold it. Moreover, even if that were fixed, shouldForceRelocation lacks an MCAsmLayout and thus cannot evaluate the %pcrel_hi fixup to a value and check the symbol, so we would then erroneously constant-fold the %pcrel_lo whilst leaving the %pcrel_hi intact. After D72197, this same sequence also occurs for symbols with global binding, which is triggered in real-world code. Instead, as discussed in D71978, we introduce a new FKF_IsTarget flag to avoid these kinds of issues. All the resolution logic happens in one place, with no coordination required between RISCAsmBackend and RISCVMCExpr to ensure they implement the same logic twice. Although the implementation of %pcrel_hi can be left as target independent, we make it target dependent to ensure that they are handled identically to %pcrel_lo, otherwise we risk one of them being constant folded but the other being preserved. This also allows us to properly support fixup pairs where the instructions are in different fragments. Reviewers: asb, lenary, efriedma Reviewed By: efriedma Subscribers: arichardson, hiraditya, rbar, johnrusso, simoncook, sabuasal, niosHD, kito-cheng, shiva0217, MaskRay, zzheng, edward-jones, rogfer01, MartinMosbeck, brucehoult, the_o, rkruppe, PkmX, jocewei, psnobl, benna, Jim, s.egerton, pzheng, sameer.abuasal, apazos, luismarques, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D73211 --- llvm/include/llvm/MC/MCAsmBackend.h | 8 ++ llvm/include/llvm/MC/MCFixupKindInfo.h | 5 +- llvm/lib/MC/MCAssembler.cpp | 7 ++ .../Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp | 97 ++++++++++++++-------- .../Target/RISCV/MCTargetDesc/RISCVAsmBackend.h | 14 +++- llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp | 69 +-------------- llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h | 7 +- llvm/test/MC/RISCV/pcrel-fixups.s | 74 +++++++++++++++-- llvm/test/MC/RISCV/pcrel-lo12-invalid.s | 2 + llvm/test/MC/RISCV/rv32i-aliases-valid.s | 7 +- llvm/test/MC/RISCV/rv32i-valid.s | 7 +- llvm/test/MC/RISCV/rv64i-aliases-valid.s | 8 +- 12 files changed, 179 insertions(+), 126 deletions(-) diff --git a/llvm/include/llvm/MC/MCAsmBackend.h b/llvm/include/llvm/MC/MCAsmBackend.h index ed7d5c7..bf41420 100644 --- a/llvm/include/llvm/MC/MCAsmBackend.h +++ b/llvm/include/llvm/MC/MCAsmBackend.h @@ -108,6 +108,14 @@ public: return false; } + virtual bool evaluateTargetFixup(const MCAssembler &Asm, + const MCAsmLayout &Layout, + const MCFixup &Fixup, const MCFragment *DF, + const MCValue &Target, uint64_t &Value, + bool &WasForced) { + llvm_unreachable("Need to implement hook if target has custom fixups"); + } + /// Apply the \p Value for given \p Fixup into the provided data fragment, at /// the offset specified by the fixup and following the fixup kind as /// appropriate. Errors (such as an out of range fixup value) should be diff --git a/llvm/include/llvm/MC/MCFixupKindInfo.h b/llvm/include/llvm/MC/MCFixupKindInfo.h index 0ea3486..0d57441 100644 --- a/llvm/include/llvm/MC/MCFixupKindInfo.h +++ b/llvm/include/llvm/MC/MCFixupKindInfo.h @@ -19,7 +19,10 @@ struct MCFixupKindInfo { FKF_IsPCRel = (1 << 0), /// Should this fixup kind force a 4-byte aligned effective PC value? - FKF_IsAlignedDownTo32Bits = (1 << 1) + 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 diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp index b30137a..75ec279 100644 --- a/llvm/lib/MC/MCAssembler.cpp +++ b/llvm/lib/MC/MCAssembler.cpp @@ -217,6 +217,13 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout, } assert(getBackendPtr() && "Expected assembler backend"); + bool IsTarget = getBackendPtr()->getFixupKindInfo(Fixup.getKind()).Flags & + MCFixupKindInfo::FKF_IsTarget; + + if (IsTarget) + return getBackend().evaluateTargetFixup(*this, Layout, Fixup, DF, Target, + Value, WasForced); + bool IsPCRel = getBackendPtr()->getFixupKindInfo(Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsPCRel; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp index 5881a0a..373d0cc 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp @@ -9,6 +9,7 @@ #include "RISCVAsmBackend.h" #include "RISCVMCExpr.h" #include "llvm/ADT/APInt.h" +#include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDirectives.h" @@ -28,8 +29,6 @@ using namespace llvm; bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target) { - bool ShouldForce = false; - switch (Fixup.getTargetKind()) { default: break; @@ -44,40 +43,9 @@ bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm, case RISCV::fixup_riscv_tls_got_hi20: case RISCV::fixup_riscv_tls_gd_hi20: return true; - case RISCV::fixup_riscv_pcrel_lo12_i: - case RISCV::fixup_riscv_pcrel_lo12_s: - // For pcrel_lo12, force a relocation if the target of the corresponding - // pcrel_hi20 is not in the same fragment. - const MCFixup *T = cast(Fixup.getValue())->getPCRelHiFixup(); - if (!T) { - Asm.getContext().reportError(Fixup.getLoc(), - "could not find corresponding %pcrel_hi"); - return false; - } - - switch (T->getTargetKind()) { - default: - llvm_unreachable("Unexpected fixup kind for pcrel_lo12"); - break; - case RISCV::fixup_riscv_got_hi20: - case RISCV::fixup_riscv_tls_got_hi20: - case RISCV::fixup_riscv_tls_gd_hi20: - ShouldForce = true; - break; - case RISCV::fixup_riscv_pcrel_hi20: { - MCFragment *TFragment = T->getValue()->findAssociatedFragment(); - MCFragment *FixupFragment = Fixup.getValue()->findAssociatedFragment(); - assert(FixupFragment && "We should have a fragment for this fixup"); - ShouldForce = - !TFragment || TFragment->getParent() != FixupFragment->getParent(); - break; - } - } - break; } - return ShouldForce || STI.getFeatureBits()[RISCV::FeatureRelax] || - ForceRelocs; + return STI.getFeatureBits()[RISCV::FeatureRelax] || ForceRelocs; } bool RISCVAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, @@ -284,6 +252,67 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value, } } +bool RISCVAsmBackend::evaluateTargetFixup( + const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFixup &Fixup, + const MCFragment *DF, const MCValue &Target, uint64_t &Value, + bool &WasForced) { + const MCFixup *AUIPCFixup; + const MCFragment *AUIPCDF; + MCValue AUIPCTarget; + switch (Fixup.getTargetKind()) { + default: + llvm_unreachable("Unexpected fixup kind!"); + case RISCV::fixup_riscv_pcrel_hi20: + AUIPCFixup = &Fixup; + AUIPCDF = DF; + AUIPCTarget = Target; + break; + case RISCV::fixup_riscv_pcrel_lo12_i: + case RISCV::fixup_riscv_pcrel_lo12_s: { + AUIPCFixup = cast(Fixup.getValue())->getPCRelHiFixup(&AUIPCDF); + if (!AUIPCFixup) { + Asm.getContext().reportError(Fixup.getLoc(), + "could not find corresponding %pcrel_hi"); + return true; + } + + // MCAssembler::evaluateFixup will emit an error for this case when it sees + // the %pcrel_hi, so don't duplicate it when also seeing the %pcrel_lo. + const MCExpr *AUIPCExpr = AUIPCFixup->getValue(); + if (!AUIPCExpr->evaluateAsRelocatable(AUIPCTarget, &Layout, AUIPCFixup)) + return true; + break; + } + } + + if (!AUIPCTarget.getSymA() || AUIPCTarget.getSymB()) + return false; + + const MCSymbolRefExpr *A = AUIPCTarget.getSymA(); + const MCSymbol &SA = A->getSymbol(); + if (A->getKind() != MCSymbolRefExpr::VK_None || SA.isUndefined()) + return false; + + auto *Writer = Asm.getWriterPtr(); + if (!Writer) + return false; + + bool IsResolved = Writer->isSymbolRefDifferenceFullyResolvedImpl( + Asm, SA, *AUIPCDF, false, true); + if (!IsResolved) + return false; + + Value = Layout.getSymbolOffset(SA) + AUIPCTarget.getConstant(); + Value -= Layout.getFragmentOffset(AUIPCDF) + AUIPCFixup->getOffset(); + + if (shouldForceRelocation(Asm, *AUIPCFixup, AUIPCTarget)) { + WasForced = true; + return false; + } + + return true; +} + void RISCVAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, MutableArrayRef Data, uint64_t Value, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h index 254249c..1c3c587 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h @@ -65,6 +65,11 @@ public: const MCAsmLayout &Layout, MCAlignFragment &AF) override; + bool evaluateTargetFixup(const MCAssembler &Asm, const MCAsmLayout &Layout, + const MCFixup &Fixup, const MCFragment *DF, + const MCValue &Target, uint64_t &Value, + bool &WasForced) override; + void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, MutableArrayRef Data, uint64_t Value, bool IsResolved, @@ -101,9 +106,12 @@ public: { "fixup_riscv_hi20", 12, 20, 0 }, { "fixup_riscv_lo12_i", 20, 12, 0 }, { "fixup_riscv_lo12_s", 0, 32, 0 }, - { "fixup_riscv_pcrel_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_riscv_pcrel_lo12_i", 20, 12, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_riscv_pcrel_lo12_s", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_riscv_pcrel_hi20", 12, 20, + MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsTarget }, + { "fixup_riscv_pcrel_lo12_i", 20, 12, + MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsTarget }, + { "fixup_riscv_pcrel_lo12_s", 0, 32, + MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsTarget }, { "fixup_riscv_got_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_riscv_tprel_hi20", 12, 20, 0 }, { "fixup_riscv_tprel_lo12_i", 20, 12, 0 }, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp index 7aa9b5e..2a6f372 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp @@ -47,7 +47,7 @@ void RISCVMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const { OS << ')'; } -const MCFixup *RISCVMCExpr::getPCRelHiFixup() const { +const MCFixup *RISCVMCExpr::getPCRelHiFixup(const MCFragment **DFOut) const { MCValue AUIPCLoc; if (!getSubExpr()->evaluateAsRelocatable(AUIPCLoc, nullptr, nullptr)) return nullptr; @@ -81,6 +81,8 @@ const MCFixup *RISCVMCExpr::getPCRelHiFixup() const { case RISCV::fixup_riscv_tls_got_hi20: case RISCV::fixup_riscv_tls_gd_hi20: case RISCV::fixup_riscv_pcrel_hi20: + if (DFOut) + *DFOut = DF; return &F; } } @@ -88,74 +90,9 @@ const MCFixup *RISCVMCExpr::getPCRelHiFixup() const { return nullptr; } -bool RISCVMCExpr::evaluatePCRelLo(MCValue &Res, const MCAsmLayout *Layout, - const MCFixup *Fixup) const { - // VK_RISCV_PCREL_LO has to be handled specially. The MCExpr inside is - // actually the location of a auipc instruction with a VK_RISCV_PCREL_HI fixup - // pointing to the real target. We need to generate an MCValue in the form of - // ( + ). 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; - - const MCSymbolRefExpr *AUIPCSRE = AUIPCLoc.getSymA(); - // Don't try to evaluate %pcrel_hi/%pcrel_lo pairs that cross fragment - // boundries. - if (!AUIPCSRE || - findAssociatedFragment() != AUIPCSRE->findAssociatedFragment()) - return false; - - const MCSymbol *AUIPCSymbol = &AUIPCSRE->getSymbol(); - if (!AUIPCSymbol) - return false; - - const MCFixup *TargetFixup = getPCRelHiFixup(); - if (!TargetFixup) - return false; - - if ((unsigned)TargetFixup->getKind() != RISCV::fixup_riscv_pcrel_hi20) - return false; - - MCValue Target; - if (!TargetFixup->getValue()->evaluateAsValue(Target, *Layout)) - return false; - - if (!Target.getSymA() || !Target.getSymA()->getSymbol().isInSection()) - return false; - - if (&Target.getSymA()->getSymbol().getSection() != - findAssociatedFragment()->getParent()) - return false; - - // We must use TargetFixup rather than AUIPCSymbol here. They will almost - // always have the same offset, except for the case when AUIPCSymbol is at - // the end of a fragment and the fixup comes from offset 0 in the next - // fragment. - uint64_t AUIPCOffset = TargetFixup->getOffset(); - - Res = MCValue::get(Target.getSymA(), nullptr, - Target.getConstant() + (Fixup->getOffset() - AUIPCOffset)); - return true; -} - bool RISCVMCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const { - if (Kind == VK_RISCV_PCREL_LO && evaluatePCRelLo(Res, Layout, Fixup)) - return true; - if (!getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup)) return false; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h index 921df37..167e7d5 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h @@ -46,9 +46,6 @@ private: int64_t evaluateAsInt64(int64_t Value) const; - bool evaluatePCRelLo(MCValue &Res, const MCAsmLayout *Layout, - const MCFixup *Fixup) const; - explicit RISCVMCExpr(const MCExpr *Expr, VariantKind Kind) : Expr(Expr), Kind(Kind) {} @@ -61,11 +58,11 @@ public: const MCExpr *getSubExpr() const { return Expr; } /// Get the corresponding PC-relative HI fixup that a VK_RISCV_PCREL_LO - /// points to. + /// points to, and optionally the fragment containing it. /// /// \returns nullptr if this isn't a VK_RISCV_PCREL_LO pointing to a /// known PC-relative HI fixup. - const MCFixup *getPCRelHiFixup() const; + const MCFixup *getPCRelHiFixup(const MCFragment **DFOut) const; void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override; bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout, diff --git a/llvm/test/MC/RISCV/pcrel-fixups.s b/llvm/test/MC/RISCV/pcrel-fixups.s index 1025988..f4f9e2c5 100644 --- a/llvm/test/MC/RISCV/pcrel-fixups.s +++ b/llvm/test/MC/RISCV/pcrel-fixups.s @@ -12,11 +12,12 @@ # RUN: | FileCheck --check-prefix RELAX %s # Fixups for %pcrel_hi / %pcrel_lo can be evaluated within a section, -# regardless of the fragment containing the target address. +# regardless of the fragment containing the target address, provided symbol +# binding allows it. function: .Lpcrel_label1: - auipc a0, %pcrel_hi(other_function) + auipc a0, %pcrel_hi(local_function) addi a1, a0, %pcrel_lo(.Lpcrel_label1) # NORELAX: auipc a0, 0 # NORELAX-NOT: R_RISCV @@ -24,7 +25,7 @@ function: # NORELAX-NOT: R_RISCV # RELAX: auipc a0, 0 -# RELAX: R_RISCV_PCREL_HI20 other_function +# RELAX: R_RISCV_PCREL_HI20 local_function # RELAX: R_RISCV_RELAX *ABS* # RELAX: addi a1, a0, 0 # RELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label1 @@ -32,7 +33,7 @@ function: .p2align 2 # Cause a new fragment be emitted here .Lpcrel_label2: - auipc a0, %pcrel_hi(other_function) + auipc a0, %pcrel_hi(local_function) addi a1, a0, %pcrel_lo(.Lpcrel_label2) # NORELAX: auipc a0, 0 # NORELAX-NOT: R_RISCV @@ -40,13 +41,72 @@ function: # NORELAX-NOT: R_RISCV # RELAX: auipc a0, 0 -# RELAX: R_RISCV_PCREL_HI20 other_function +# RELAX: R_RISCV_PCREL_HI20 local_function # RELAX: R_RISCV_RELAX *ABS* # RELAX: addi a1, a0, 0 # RELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label2 # RELAX: R_RISCV_RELAX *ABS* - .type other_function,@function -other_function: + .type local_function,@function +local_function: ret +# Check we correctly evaluate when fixups are in different fragments + +.Lpcrel_label3: + auipc a0, %pcrel_hi(local_function) + .p2align 2 # Cause a new fragment be emitted here + addi a1, a0, %pcrel_lo(.Lpcrel_label3) +# NORELAX: auipc a0, 0 +# NORELAX-NOT: R_RISCV +# NORELAX: addi a1, a0, -4 +# NORELAX-NOT: R_RISCV + +# RELAX: auipc a0, 0 +# RELAX: R_RISCV_PCREL_HI20 local_function +# RELAX: R_RISCV_RELAX *ABS* +# RELAX: addi a1, a0, 0 +# RELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label3 +# RELAX: R_RISCV_RELAX *ABS* + +# Check handling of symbol binding. + +.Lpcrel_label4: + auipc a0, %pcrel_hi(global_function) + addi a1, a0, %pcrel_lo(.Lpcrel_label4) +# NORELAX: auipc a0, 0 +# NORELAX: R_RISCV_PCREL_HI20 global_function +# NORELAX: addi a1, a0, 0 +# NORELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label4 + +# RELAX: auipc a0, 0 +# RELAX: R_RISCV_PCREL_HI20 global_function +# RELAX: R_RISCV_RELAX *ABS* +# RELAX: addi a1, a0, 0 +# RELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label4 +# RELAX: R_RISCV_RELAX *ABS* + +.Lpcrel_label5: + auipc a0, %pcrel_hi(weak_function) + addi a1, a0, %pcrel_lo(.Lpcrel_label5) +# NORELAX: auipc a0, 0 +# NORELAX: R_RISCV_PCREL_HI20 weak_function +# NORELAX: addi a1, a0, 0 +# NORELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label5 + +# RELAX: auipc a0, 0 +# RELAX: R_RISCV_PCREL_HI20 weak_function +# RELAX: R_RISCV_RELAX *ABS* +# RELAX: addi a1, a0, 0 +# RELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label5 +# RELAX: R_RISCV_RELAX *ABS* + + .global global_function + .type global_function,@function +global_function: + ret + + .weak weak_function + .type weak_function,@function +weak_function: + ret diff --git a/llvm/test/MC/RISCV/pcrel-lo12-invalid.s b/llvm/test/MC/RISCV/pcrel-lo12-invalid.s index 7cf2494..74a1f2f 100644 --- a/llvm/test/MC/RISCV/pcrel-lo12-invalid.s +++ b/llvm/test/MC/RISCV/pcrel-lo12-invalid.s @@ -3,3 +3,5 @@ 1: addi a0, a0, %pcrel_lo(1b) # CHECK: :[[@LINE]]:3: error: could not find corresponding %pcrel_hi + addi a0, a0, %pcrel_lo(0x123456) # CHECK: :[[@LINE]]:3: error: could not find corresponding %pcrel_hi + addi a0, a0, %pcrel_lo(foo) # CHECK: :[[@LINE]]:3: error: could not find corresponding %pcrel_hi diff --git a/llvm/test/MC/RISCV/rv32i-aliases-valid.s b/llvm/test/MC/RISCV/rv32i-aliases-valid.s index d2e142e..5140fb2 100644 --- a/llvm/test/MC/RISCV/rv32i-aliases-valid.s +++ b/llvm/test/MC/RISCV/rv32i-aliases-valid.s @@ -14,6 +14,8 @@ # CHECK-ALIAS....Match the alias (tests instr. to alias mapping) # CHECK-EXPAND...Match canonical instr. unconditionally (tests alias expansion) +# Needed for testing valid %pcrel_lo expressions +.Lpcrel_hi0: auipc a0, %pcrel_hi(foo) # CHECK-INST: addi a0, zero, 0 # CHECK-ALIAS: mv a0, zero @@ -71,16 +73,13 @@ li x12, 0xFFFFFFFF # CHECK-EXPAND: addi a0, zero, 1110 li a0, %lo(0x123456) -# CHECK-OBJ-NOALIAS: addi a0, zero, 0 -# CHECK-OBJ: R_RISCV_PCREL_LO12 -li a0, %pcrel_lo(0x123456) # CHECK-OBJ-NOALIAS: addi a0, zero, 0 # CHECK-OBJ: R_RISCV_LO12 li a0, %lo(foo) # CHECK-OBJ-NOALIAS: addi a0, zero, 0 # CHECK-OBJ: R_RISCV_PCREL_LO12 -li a0, %pcrel_lo(foo) +li a0, %pcrel_lo(.Lpcrel_hi0) .equ CONST, 0x123456 # CHECK-EXPAND: lui a0, 291 diff --git a/llvm/test/MC/RISCV/rv32i-valid.s b/llvm/test/MC/RISCV/rv32i-valid.s index bbcfa5f..580f0f5 100644 --- a/llvm/test/MC/RISCV/rv32i-valid.s +++ b/llvm/test/MC/RISCV/rv32i-valid.s @@ -11,6 +11,9 @@ .equ CONST, 30 +# Needed for testing valid %pcrel_lo expressions +.Lpcrel_hi0: auipc a0, %pcrel_hi(foo) + # CHECK-ASM-AND-OBJ: lui a0, 2 # CHECK-ASM: encoding: [0x37,0x25,0x00,0x00] lui a0, 2 @@ -161,11 +164,11 @@ lw a0, 97(a2) # CHECK-OBJ: lbu s5, 0(s6) # CHECK-OBJ: R_RISCV_LO12 lbu s5, %lo(foo)(s6) -# CHECK-ASM: lhu t3, %pcrel_lo(foo)(t3) +# CHECK-ASM: lhu t3, %pcrel_lo(.Lpcrel_hi0)(t3) # CHECK-ASM: encoding: [0x03,0x5e,0bAAAA1110,A] # CHECK-OBJ: lhu t3, 0(t3) # CHECK-OBJ: R_RISCV_PCREL_LO12 -lhu t3, %pcrel_lo(foo)(t3) +lhu t3, %pcrel_lo(.Lpcrel_hi0)(t3) # CHECK-ASM-AND-OBJ: lb t0, 30(t1) # CHECK-ASM: encoding: [0x83,0x02,0xe3,0x01] lb t0, CONST(t1) diff --git a/llvm/test/MC/RISCV/rv64i-aliases-valid.s b/llvm/test/MC/RISCV/rv64i-aliases-valid.s index 551e46f..9f0ad24 100644 --- a/llvm/test/MC/RISCV/rv64i-aliases-valid.s +++ b/llvm/test/MC/RISCV/rv64i-aliases-valid.s @@ -17,6 +17,9 @@ # TODO ld # TODO sd +# Needed for testing valid %pcrel_lo expressions +.Lpcrel_hi0: auipc a0, %pcrel_hi(foo) + # CHECK-INST: addi a0, zero, 0 # CHECK-ALIAS: mv a0, zero li x10, 0 @@ -107,16 +110,13 @@ li t5, 0xFFFFFFFFFFFFFFFF # CHECK-EXPAND: addi a0, zero, 1110 li a0, %lo(0x123456) -# CHECK-OBJ-NOALIAS: addi a0, zero, 0 -# CHECK-OBJ: R_RISCV_PCREL_LO12 -li a0, %pcrel_lo(0x123456) # CHECK-OBJ-NOALIAS: addi a0, zero, 0 # CHECK-OBJ: R_RISCV_LO12 li a0, %lo(foo) # CHECK-OBJ-NOALIAS: addi a0, zero, 0 # CHECK-OBJ: R_RISCV_PCREL_LO12 -li a0, %pcrel_lo(foo) +li a0, %pcrel_lo(.Lpcrel_hi0) .equ CONST, 0x123456 # CHECK-EXPAND: lui a0, 291 -- 2.7.4