diff --git a/llvm/include/llvm/MC/MCInstPrinter.h b/llvm/include/llvm/MC/MCInstPrinter.h --- a/llvm/include/llvm/MC/MCInstPrinter.h +++ b/llvm/include/llvm/MC/MCInstPrinter.h @@ -106,6 +106,12 @@ virtual void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &OS) = 0; + virtual void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, + const MCSubtargetInfo &STI, raw_ostream &OS, + bool HasRel) { + printInst(MI, Address, Annot, STI, OS); + } + /// Return the name of the specified opcode enum (e.g. "MOV32ri") or /// empty if we can't resolve it. StringRef getOpcodeName(unsigned Opcode) const; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h @@ -28,6 +28,9 @@ void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &O) override; + void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, + const MCSubtargetInfo &STI, raw_ostream &O, + bool HasRel) override; void printRegName(raw_ostream &O, MCRegister Reg) const override; void printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp @@ -61,7 +61,7 @@ void RISCVInstPrinter::printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, - raw_ostream &O) { + raw_ostream &O, bool HasRel) { bool Res = false; const MCInst *NewMI = MI; MCInst UncompressedMI; @@ -69,11 +69,25 @@ Res = RISCVRVC::uncompress(UncompressedMI, *MI, STI); if (Res) NewMI = const_cast(&UncompressedMI); + if (MI->getOpcode() == RISCV::ADDI) { + auto Rs = MI->getOperand(1); + if (Rs.getReg() != RISCV::X0) { // neither a "nop" nor a "li". + auto Imm = MI->getOperand(2); + if (Imm.isImm() && Imm.getImm() == 0 && HasRel) + NoAliases = true; // don't print the "addi" of a "la" as "mv". + } + } if (!PrintAliases || NoAliases || !printAliasInstr(NewMI, Address, STI, O)) printInstruction(NewMI, Address, STI, O); printAnnotation(O, Annot); } +void RISCVInstPrinter::printInst(const MCInst *MI, uint64_t Address, + StringRef Annot, const MCSubtargetInfo &STI, + raw_ostream &O) { + printInst(MI, Address, Annot, STI, O, false); +} + void RISCVInstPrinter::printRegName(raw_ostream &O, MCRegister Reg) const { O << getRegisterName(Reg); } diff --git a/llvm/test/MC/RISCV/rvi-aliases-valid.s b/llvm/test/MC/RISCV/rvi-aliases-valid.s --- a/llvm/test/MC/RISCV/rvi-aliases-valid.s +++ b/llvm/test/MC/RISCV/rvi-aliases-valid.s @@ -294,3 +294,9 @@ # CHECK-S-OBJ-NOALIAS: ecall # CHECK-S-OBJ: ecall scall + +.option relax +1: auipc t1, %pcrel_hi(1b) +# CHECK-OBJ-NOALIAS: addi t1, t1, 0 +# CHECK-OBJ: addi t1, t1, 0 + addi t1, t1, %pcrel_lo(1b) diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -528,7 +528,12 @@ // instruction. uint64_t Addr = Address.Address + (STI.getTargetTriple().isX86() ? Bytes.size() : 0); - IP.printInst(MI, Addr, "", STI, OS); + auto is_rel = [=](RelocationRef Rel) { return Rel.getOffset() == Addr; }; + // TODO: if people agree with the overall approach of this patch then the + // search for a relocation will be optimized to avoid duplicate work. + bool HasRel = + std::find_if(Rels->begin(), Rels->end(), is_rel) != Rels->end(); + IP.printInst(MI, Addr, "", STI, OS, HasRel); } else OS << "\t"; }