forked from OSchip/llvm-project
[RISCV][MC] Find matching pcrel_hi fixup in more cases.
If a symbol points to the end of a fragment, instead of searching for fixups in that fragment, search in the next fragment. Fixes spurious assembler error with subtarget change next to "la" pseudo-instruction, or expanded equivalent. Alternate proposal to fix the problem discussed in https://reviews.llvm.org/D58759. Testcase by Ana Pazos. Differential Revision: https://reviews.llvm.org/D58943 llvm-svn: 355946
This commit is contained in:
parent
b6bfcfc847
commit
74b6aae4e8
|
@ -49,14 +49,22 @@ const MCFixup *RISCVMCExpr::getPCRelHiFixup() const {
|
|||
if (!AUIPCSRE)
|
||||
return nullptr;
|
||||
|
||||
const auto *DF =
|
||||
dyn_cast_or_null<MCDataFragment>(AUIPCSRE->findAssociatedFragment());
|
||||
const MCSymbol *AUIPCSymbol = &AUIPCSRE->getSymbol();
|
||||
const auto *DF = dyn_cast_or_null<MCDataFragment>(AUIPCSymbol->getFragment());
|
||||
|
||||
if (!DF)
|
||||
return nullptr;
|
||||
|
||||
const MCSymbol *AUIPCSymbol = &AUIPCSRE->getSymbol();
|
||||
uint64_t Offset = AUIPCSymbol->getOffset();
|
||||
if (DF->getContents().size() == Offset) {
|
||||
DF = dyn_cast_or_null<MCDataFragment>(DF->getNextNode());
|
||||
if (!DF)
|
||||
return nullptr;
|
||||
Offset = 0;
|
||||
}
|
||||
|
||||
for (const MCFixup &F : DF->getFixups()) {
|
||||
if (F.getOffset() != AUIPCSymbol->getOffset())
|
||||
if (F.getOffset() != Offset)
|
||||
continue;
|
||||
|
||||
switch ((unsigned)F.getKind()) {
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
# RUN: llvm-mc %s -triple=riscv32 | FileCheck -check-prefix=ASM %s
|
||||
# RUN: llvm-mc %s -triple=riscv64 | FileCheck -check-prefix=ASM %s
|
||||
# RUN: llvm-mc -filetype=obj -triple riscv32 < %s \
|
||||
# RUN: | llvm-objdump -d -riscv-no-aliases - | FileCheck -check-prefix=DISASM %s
|
||||
# RUN: llvm-mc -filetype=obj -triple riscv64 < %s \
|
||||
# RUN: | llvm-objdump -d -riscv-no-aliases - | FileCheck -check-prefix=DISASM %s
|
||||
|
||||
# Checks change of options does not cause error: could not find corresponding %pcrel_hi
|
||||
# when assembling pseudoinstruction and its extended form.
|
||||
|
||||
.option push
|
||||
.option norelax
|
||||
la a0, a_symbol
|
||||
.option pop
|
||||
la a1, another_symbol
|
||||
|
||||
# ASM: .Lpcrel_hi0:
|
||||
# ASM: auipc a0, %pcrel_hi(a_symbol)
|
||||
# ASM: addi a0, a0, %pcrel_lo(.Lpcrel_hi0)
|
||||
# ASM: .Lpcrel_hi1:
|
||||
# ASM: auipc a1, %pcrel_hi(another_symbol)
|
||||
# ASM: addi a1, a1, %pcrel_lo(.Lpcrel_hi1)
|
||||
|
||||
# DISASM: .Lpcrel_hi0:
|
||||
# DISASM: auipc a0, 0
|
||||
# DISASM: addi a0, a0, 0
|
||||
# DISASM:.Lpcrel_hi1:
|
||||
# DISASM: auipc a1, 0
|
||||
# DISASM: addi a1, a1, 0
|
||||
|
||||
.option push
|
||||
.option norelax
|
||||
1:auipc a0, %pcrel_hi(a_symbol)
|
||||
addi a0, a0, %pcrel_lo(1b)
|
||||
.option pop
|
||||
2:auipc a1, %pcrel_hi(another_symbol)
|
||||
addi a1, a1, %pcrel_lo(2b)
|
||||
|
||||
# ASM: .Ltmp0:
|
||||
# ASM: auipc a0, %pcrel_hi(a_symbol)
|
||||
# ASM: addi a0, a0, %pcrel_lo(.Ltmp0)
|
||||
# ASM: .Ltmp1:
|
||||
# ASM: auipc a1, %pcrel_hi(another_symbol)
|
||||
# ASM: addi a1, a1, %pcrel_lo(.Ltmp1)
|
||||
|
||||
# DISASM: .Ltmp0:
|
||||
# DISASM: auipc a0, 0
|
||||
# DISASM: addi a0, a0, 0
|
||||
# DISASM: .Ltmp1:
|
||||
# DISASM: auipc a1, 0
|
||||
# DISASM: addi a1, a1, 0
|
Loading…
Reference in New Issue