[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:
Eli Friedman 2019-03-12 18:14:16 +00:00
parent b6bfcfc847
commit 74b6aae4e8
2 changed files with 63 additions and 4 deletions

View File

@ -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()) {

View File

@ -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