1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 20:23:11 +01:00

[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
This commit is contained in:
James Clarke 2020-01-23 02:05:46 +00:00
parent bba5d4f164
commit cab1120454
12 changed files with 179 additions and 126 deletions

View File

@ -108,6 +108,14 @@ public:
return false; 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 /// 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 /// the offset specified by the fixup and following the fixup kind as
/// appropriate. Errors (such as an out of range fixup value) should be /// appropriate. Errors (such as an out of range fixup value) should be

View File

@ -19,7 +19,10 @@ struct MCFixupKindInfo {
FKF_IsPCRel = (1 << 0), FKF_IsPCRel = (1 << 0),
/// Should this fixup kind force a 4-byte aligned effective PC value? /// 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 /// A target specific name for the fixup kind. The names will be unique for

View File

@ -217,6 +217,13 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout,
} }
assert(getBackendPtr() && "Expected assembler backend"); 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 & bool IsPCRel = getBackendPtr()->getFixupKindInfo(Fixup.getKind()).Flags &
MCFixupKindInfo::FKF_IsPCRel; MCFixupKindInfo::FKF_IsPCRel;

View File

@ -9,6 +9,7 @@
#include "RISCVAsmBackend.h" #include "RISCVAsmBackend.h"
#include "RISCVMCExpr.h" #include "RISCVMCExpr.h"
#include "llvm/ADT/APInt.h" #include "llvm/ADT/APInt.h"
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h" #include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCDirectives.h"
@ -28,8 +29,6 @@ using namespace llvm;
bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm, bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
const MCFixup &Fixup, const MCFixup &Fixup,
const MCValue &Target) { const MCValue &Target) {
bool ShouldForce = false;
switch (Fixup.getTargetKind()) { switch (Fixup.getTargetKind()) {
default: default:
break; break;
@ -44,40 +43,9 @@ bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
case RISCV::fixup_riscv_tls_got_hi20: case RISCV::fixup_riscv_tls_got_hi20:
case RISCV::fixup_riscv_tls_gd_hi20: case RISCV::fixup_riscv_tls_gd_hi20:
return true; 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<RISCVMCExpr>(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] || return STI.getFeatureBits()[RISCV::FeatureRelax] || ForceRelocs;
ForceRelocs;
} }
bool RISCVAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, 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<RISCVMCExpr>(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, void RISCVAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target, const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value, MutableArrayRef<char> Data, uint64_t Value,

View File

@ -65,6 +65,11 @@ public:
const MCAsmLayout &Layout, const MCAsmLayout &Layout,
MCAlignFragment &AF) override; 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, void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target, MutableArrayRef<char> Data, const MCValue &Target, MutableArrayRef<char> Data,
uint64_t Value, bool IsResolved, uint64_t Value, bool IsResolved,
@ -101,9 +106,12 @@ public:
{ "fixup_riscv_hi20", 12, 20, 0 }, { "fixup_riscv_hi20", 12, 20, 0 },
{ "fixup_riscv_lo12_i", 20, 12, 0 }, { "fixup_riscv_lo12_i", 20, 12, 0 },
{ "fixup_riscv_lo12_s", 0, 32, 0 }, { "fixup_riscv_lo12_s", 0, 32, 0 },
{ "fixup_riscv_pcrel_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_riscv_pcrel_hi20", 12, 20,
{ "fixup_riscv_pcrel_lo12_i", 20, 12, MCFixupKindInfo::FKF_IsPCRel }, MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsTarget },
{ "fixup_riscv_pcrel_lo12_s", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, { "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_got_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_riscv_tprel_hi20", 12, 20, 0 }, { "fixup_riscv_tprel_hi20", 12, 20, 0 },
{ "fixup_riscv_tprel_lo12_i", 20, 12, 0 }, { "fixup_riscv_tprel_lo12_i", 20, 12, 0 },

View File

@ -47,7 +47,7 @@ void RISCVMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
OS << ')'; OS << ')';
} }
const MCFixup *RISCVMCExpr::getPCRelHiFixup() const { const MCFixup *RISCVMCExpr::getPCRelHiFixup(const MCFragment **DFOut) const {
MCValue AUIPCLoc; MCValue AUIPCLoc;
if (!getSubExpr()->evaluateAsRelocatable(AUIPCLoc, nullptr, nullptr)) if (!getSubExpr()->evaluateAsRelocatable(AUIPCLoc, nullptr, nullptr))
return nullptr; return nullptr;
@ -81,6 +81,8 @@ const MCFixup *RISCVMCExpr::getPCRelHiFixup() const {
case RISCV::fixup_riscv_tls_got_hi20: case RISCV::fixup_riscv_tls_got_hi20:
case RISCV::fixup_riscv_tls_gd_hi20: case RISCV::fixup_riscv_tls_gd_hi20:
case RISCV::fixup_riscv_pcrel_hi20: case RISCV::fixup_riscv_pcrel_hi20:
if (DFOut)
*DFOut = DF;
return &F; return &F;
} }
} }
@ -88,74 +90,9 @@ const MCFixup *RISCVMCExpr::getPCRelHiFixup() const {
return nullptr; 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
// (<real target> + <offset from this fixup to the auipc fixup>). 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<RISCVAsmBackend &>(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, bool RISCVMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout, const MCAsmLayout *Layout,
const MCFixup *Fixup) const { const MCFixup *Fixup) const {
if (Kind == VK_RISCV_PCREL_LO && evaluatePCRelLo(Res, Layout, Fixup))
return true;
if (!getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup)) if (!getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup))
return false; return false;

View File

@ -46,9 +46,6 @@ private:
int64_t evaluateAsInt64(int64_t Value) const; 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) explicit RISCVMCExpr(const MCExpr *Expr, VariantKind Kind)
: Expr(Expr), Kind(Kind) {} : Expr(Expr), Kind(Kind) {}
@ -61,11 +58,11 @@ public:
const MCExpr *getSubExpr() const { return Expr; } const MCExpr *getSubExpr() const { return Expr; }
/// Get the corresponding PC-relative HI fixup that a VK_RISCV_PCREL_LO /// 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 /// \returns nullptr if this isn't a VK_RISCV_PCREL_LO pointing to a
/// known PC-relative HI fixup. /// 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; void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout, bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout,

View File

@ -12,11 +12,12 @@
# RUN: | FileCheck --check-prefix RELAX %s # RUN: | FileCheck --check-prefix RELAX %s
# Fixups for %pcrel_hi / %pcrel_lo can be evaluated within a section, # 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: function:
.Lpcrel_label1: .Lpcrel_label1:
auipc a0, %pcrel_hi(other_function) auipc a0, %pcrel_hi(local_function)
addi a1, a0, %pcrel_lo(.Lpcrel_label1) addi a1, a0, %pcrel_lo(.Lpcrel_label1)
# NORELAX: auipc a0, 0 # NORELAX: auipc a0, 0
# NORELAX-NOT: R_RISCV # NORELAX-NOT: R_RISCV
@ -24,7 +25,7 @@ function:
# NORELAX-NOT: R_RISCV # NORELAX-NOT: R_RISCV
# RELAX: auipc a0, 0 # RELAX: auipc a0, 0
# RELAX: R_RISCV_PCREL_HI20 other_function # RELAX: R_RISCV_PCREL_HI20 local_function
# RELAX: R_RISCV_RELAX *ABS* # RELAX: R_RISCV_RELAX *ABS*
# RELAX: addi a1, a0, 0 # RELAX: addi a1, a0, 0
# RELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label1 # RELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label1
@ -32,7 +33,7 @@ function:
.p2align 2 # Cause a new fragment be emitted here .p2align 2 # Cause a new fragment be emitted here
.Lpcrel_label2: .Lpcrel_label2:
auipc a0, %pcrel_hi(other_function) auipc a0, %pcrel_hi(local_function)
addi a1, a0, %pcrel_lo(.Lpcrel_label2) addi a1, a0, %pcrel_lo(.Lpcrel_label2)
# NORELAX: auipc a0, 0 # NORELAX: auipc a0, 0
# NORELAX-NOT: R_RISCV # NORELAX-NOT: R_RISCV
@ -40,13 +41,72 @@ function:
# NORELAX-NOT: R_RISCV # NORELAX-NOT: R_RISCV
# RELAX: auipc a0, 0 # RELAX: auipc a0, 0
# RELAX: R_RISCV_PCREL_HI20 other_function # RELAX: R_RISCV_PCREL_HI20 local_function
# RELAX: R_RISCV_RELAX *ABS* # RELAX: R_RISCV_RELAX *ABS*
# RELAX: addi a1, a0, 0 # RELAX: addi a1, a0, 0
# RELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label2 # RELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label2
# RELAX: R_RISCV_RELAX *ABS* # RELAX: R_RISCV_RELAX *ABS*
.type other_function,@function .type local_function,@function
other_function: local_function:
ret 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

View File

@ -3,3 +3,5 @@
1: 1:
addi a0, a0, %pcrel_lo(1b) # CHECK: :[[@LINE]]:3: error: could not find corresponding %pcrel_hi 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

View File

@ -14,6 +14,8 @@
# CHECK-ALIAS....Match the alias (tests instr. to alias mapping) # CHECK-ALIAS....Match the alias (tests instr. to alias mapping)
# CHECK-EXPAND...Match canonical instr. unconditionally (tests alias expansion) # 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-INST: addi a0, zero, 0
# CHECK-ALIAS: mv a0, zero # CHECK-ALIAS: mv a0, zero
@ -71,16 +73,13 @@ li x12, 0xFFFFFFFF
# CHECK-EXPAND: addi a0, zero, 1110 # CHECK-EXPAND: addi a0, zero, 1110
li a0, %lo(0x123456) 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-NOALIAS: addi a0, zero, 0
# CHECK-OBJ: R_RISCV_LO12 # CHECK-OBJ: R_RISCV_LO12
li a0, %lo(foo) li a0, %lo(foo)
# CHECK-OBJ-NOALIAS: addi a0, zero, 0 # CHECK-OBJ-NOALIAS: addi a0, zero, 0
# CHECK-OBJ: R_RISCV_PCREL_LO12 # CHECK-OBJ: R_RISCV_PCREL_LO12
li a0, %pcrel_lo(foo) li a0, %pcrel_lo(.Lpcrel_hi0)
.equ CONST, 0x123456 .equ CONST, 0x123456
# CHECK-EXPAND: lui a0, 291 # CHECK-EXPAND: lui a0, 291

View File

@ -11,6 +11,9 @@
.equ CONST, 30 .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-AND-OBJ: lui a0, 2
# CHECK-ASM: encoding: [0x37,0x25,0x00,0x00] # CHECK-ASM: encoding: [0x37,0x25,0x00,0x00]
lui a0, 2 lui a0, 2
@ -161,11 +164,11 @@ lw a0, 97(a2)
# CHECK-OBJ: lbu s5, 0(s6) # CHECK-OBJ: lbu s5, 0(s6)
# CHECK-OBJ: R_RISCV_LO12 # CHECK-OBJ: R_RISCV_LO12
lbu s5, %lo(foo)(s6) 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-ASM: encoding: [0x03,0x5e,0bAAAA1110,A]
# CHECK-OBJ: lhu t3, 0(t3) # CHECK-OBJ: lhu t3, 0(t3)
# CHECK-OBJ: R_RISCV_PCREL_LO12 # 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-AND-OBJ: lb t0, 30(t1)
# CHECK-ASM: encoding: [0x83,0x02,0xe3,0x01] # CHECK-ASM: encoding: [0x83,0x02,0xe3,0x01]
lb t0, CONST(t1) lb t0, CONST(t1)

View File

@ -17,6 +17,9 @@
# TODO ld # TODO ld
# TODO sd # TODO sd
# Needed for testing valid %pcrel_lo expressions
.Lpcrel_hi0: auipc a0, %pcrel_hi(foo)
# CHECK-INST: addi a0, zero, 0 # CHECK-INST: addi a0, zero, 0
# CHECK-ALIAS: mv a0, zero # CHECK-ALIAS: mv a0, zero
li x10, 0 li x10, 0
@ -107,16 +110,13 @@ li t5, 0xFFFFFFFFFFFFFFFF
# CHECK-EXPAND: addi a0, zero, 1110 # CHECK-EXPAND: addi a0, zero, 1110
li a0, %lo(0x123456) 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-NOALIAS: addi a0, zero, 0
# CHECK-OBJ: R_RISCV_LO12 # CHECK-OBJ: R_RISCV_LO12
li a0, %lo(foo) li a0, %lo(foo)
# CHECK-OBJ-NOALIAS: addi a0, zero, 0 # CHECK-OBJ-NOALIAS: addi a0, zero, 0
# CHECK-OBJ: R_RISCV_PCREL_LO12 # CHECK-OBJ: R_RISCV_PCREL_LO12
li a0, %pcrel_lo(foo) li a0, %pcrel_lo(.Lpcrel_hi0)
.equ CONST, 0x123456 .equ CONST, 0x123456
# CHECK-EXPAND: lui a0, 291 # CHECK-EXPAND: lui a0, 291