diff --git a/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp b/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp --- a/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp @@ -20,6 +20,7 @@ #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/MC/MCContext.h" +#include "llvm/Support/CodeGen.h" using namespace llvm; @@ -74,6 +75,9 @@ bool expandLoadAddressTLSGD(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, MachineBasicBlock::iterator &NextMBBI); + bool expandFunctionCALL(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + MachineBasicBlock::iterator &NextMBBI); }; char LoongArchPreRAExpandPseudo::ID = 0; @@ -116,6 +120,8 @@ return expandLoadAddressTLSLD(MBB, MBBI, NextMBBI); case LoongArch::PseudoLA_TLS_GD: return expandLoadAddressTLSGD(MBB, MBBI, NextMBBI); + case LoongArch::PseudoCALL: + return expandFunctionCALL(MBB, MBBI, NextMBBI); } return false; } @@ -239,6 +245,32 @@ SecondOpcode, LoongArchII::MO_GOT_PC_LO); } +bool LoongArchPreRAExpandPseudo::expandFunctionCALL( + MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, + MachineBasicBlock::iterator &NextMBBI) { + MachineFunction *MF = MBB.getParent(); + MachineInstr &MI = *MBBI; + DebugLoc DL = MI.getDebugLoc(); + const MachineOperand &Func = MI.getOperand(0); + MachineInstrBuilder CALL; + + // TODO: CodeModel::Medium + switch (MF->getTarget().getCodeModel()) { + default: + report_fatal_error("Unsupported code model"); + break; + case CodeModel::Small: // Default CodeModel. + CALL = BuildMI(MBB, MBBI, DL, TII->get(LoongArch::BL)).add(Func); + break; + } + + // Transfer implicit operands. + CALL.copyImplicitOps(MI); + + MI.eraseFromParent(); + return true; +} + } // end namespace INITIALIZE_PASS(LoongArchPreRAExpandPseudo, "loongarch-prera-expand-pseudo", diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td --- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td @@ -927,9 +927,7 @@ (PseudoBRIND GPR:$rj, simm16_lsl2:$imm16)>; let isCall = 1, Defs = [R1] in -def PseudoCALL : Pseudo<(outs), (ins simm26_bl:$func)> { - let AsmString = "bl\t$func"; -} +def PseudoCALL : Pseudo<(outs), (ins simm26_bl:$func)>; def : Pat<(loongarch_call tglobaladdr:$func), (PseudoCALL tglobaladdr:$func)>; def : Pat<(loongarch_call texternalsym:$func), (PseudoCALL texternalsym:$func)>; diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp --- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp +++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp @@ -43,10 +43,6 @@ SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const override; - void expandFunctionCall(const MCInst &MI, raw_ostream &OS, - SmallVectorImpl &Fixups, - const MCSubtargetInfo &STI) const; - /// TableGen'erated function for getting the binary encoding for an /// instruction. uint64_t getBinaryCodeForInstr(const MCInst &MI, @@ -277,17 +273,6 @@ return 0; } -void LoongArchMCCodeEmitter::expandFunctionCall( - const MCInst &MI, raw_ostream &OS, SmallVectorImpl &Fixups, - const MCSubtargetInfo &STI) const { - MCOperand Func = MI.getOperand(0); - MCInst TmpInst = Func.isExpr() - ? MCInstBuilder(LoongArch::BL).addExpr(Func.getExpr()) - : MCInstBuilder(LoongArch::BL).addImm(Func.getImm()); - uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); - support::endian::write(OS, Binary, support::little); -} - void LoongArchMCCodeEmitter::encodeInstruction( const MCInst &MI, raw_ostream &OS, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const { @@ -295,9 +280,6 @@ // Get byte count of instruction. unsigned Size = Desc.getSize(); - if (MI.getOpcode() == LoongArch::PseudoCALL) - return expandFunctionCall(MI, OS, Fixups, STI); - switch (Size) { default: llvm_unreachable("Unhandled encodeInstruction length!"); diff --git a/llvm/test/CodeGen/LoongArch/expand-call.ll b/llvm/test/CodeGen/LoongArch/expand-call.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/LoongArch/expand-call.ll @@ -0,0 +1,16 @@ +; RUN: llc --mtriple=loongarch64 --stop-before loongarch-prera-expand-pseudo \ +; RUN: --verify-machineinstrs < %s | FileCheck %s --check-prefix=NOEXPAND +; RUN: llc --mtriple=loongarch64 --stop-after loongarch-prera-expand-pseudo \ +; RUN: --verify-machineinstrs < %s | FileCheck %s --check-prefix=EXPAND + +declare void @callee() + +define void @caller() nounwind { +; NOEXPAND-LABEL: name: caller +; NOEXPAND: PseudoCALL target-flags{{.*}}callee +; +; EXPAND-LABEL: name: caller +; EXPAND: BL target-flags{{.*}}callee + call void @callee() + ret void +}