Skip to content

Commit 2f91e98

Browse files
authored
[RISCV] Mark symbols used in inline asm for relocations as referenced (llvm#104925)
Commit 5cd8d53 taught RISCVMergeBaseOffset to handle inline asm, however there is at least one case uncovered for integrated as. In the example below compiler generates pcrel relocation (mcmodel=medany) ``` volatile double double_val = 1.0; void foo() { asm volatile("fld f0, %0 \n\t" : : "m"(double_val) : "memory"); } ``` And fails with the folliwng error ``` error: could not find corresponding %pcrel_hi | "fld f0, %0 \n\t" <inline asm>:1:2: note: instantiated into assembly here | fld f0, %pcrel_lo(.Lpcrel_hi0)(a0) ``` After transformations MachineFunction contains inline asm instructions with '.Lpcrel_hi0' symbol that is not defined in inline asm, but referenced. ``` ... = AUIPC ...(riscv-pcrel-hi) @double_val, pre-instr-symbol <mcsymbol .Lpcrel_hi0> INLINEASM &"fld f0, $0 \0A\09" ... target-flags(riscv-pcrel-lo) <mcsymbol .Lpcrel_hi0> ``` So, when AsmParser processes 'fld', it has to create a new symbol as '.Lpcrel_hi0' already exists but not known to be referenced in inline asm. AsmParser avoids conflicts by renaming referenced by 'fld' symbol with '.Lpcrel_hi00' name which does not exist. Resulting erroneous asm ``` .Lpcrel_hi0: auipc a0, %pcrel_hi(double_val) #APP fld ft0, %pcrel_lo(.Lpcrel_hi00)(a0) ``` This change adds symbols used in memory operands to the list of referenced ones. Godbolt link: https://godbolt.org/z/aqrrsWKoK -- on the left you can find incorrect labels for the integrated-as and on the right an error when compiling to the binary object.
1 parent 3be955a commit 2f91e98

File tree

2 files changed

+399
-798
lines changed

2 files changed

+399
-798
lines changed

llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,15 @@ bool RISCVAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
396396
OS << MCO.getImm();
397397
else if (Offset.isGlobal() || Offset.isBlockAddress() || Offset.isMCSymbol())
398398
OS << *MCO.getExpr();
399+
400+
if (Offset.isMCSymbol())
401+
MMI->getContext().registerInlineAsmLabel(Offset.getMCSymbol());
402+
if (Offset.isBlockAddress()) {
403+
const BlockAddress *BA = Offset.getBlockAddress();
404+
MCSymbol *Sym = GetBlockAddressSymbol(BA);
405+
MMI->getContext().registerInlineAsmLabel(Sym);
406+
}
407+
399408
OS << "(" << RISCVInstPrinter::getRegisterName(AddrReg.getReg()) << ")";
400409
return false;
401410
}

0 commit comments

Comments
 (0)