From ea3431598e552fdfb7cd69f92fecc661d64fa2b1 Mon Sep 17 00:00:00 2001 From: Simon Dardis Date: Thu, 18 Aug 2016 13:22:43 +0000 Subject: [PATCH] [mips] Correct tail call encoding for MIPSR6 r277708 enabled tails calls for MIPS but used the 'jr' instruction when the jump target was held in a register. For MIPSR6, 'jalr $zero, $reg' should have been used. Additionally, add missing patterns for external and global symbols for tail calls. Reviewers: dsanders, vkalintiris Differential Review: https://reviews.llvm.org/D23301 llvm-svn: 279064 --- llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td | 2 + llvm/lib/Target/Mips/MicroMipsInstrInfo.td | 23 +++--------- llvm/lib/Target/Mips/Mips32r6InstrInfo.td | 2 - llvm/lib/Target/Mips/Mips64InstrInfo.td | 2 +- llvm/lib/Target/Mips/Mips64r6InstrInfo.td | 4 -- llvm/lib/Target/Mips/MipsAsmPrinter.cpp | 13 +++++-- llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp | 2 +- llvm/lib/Target/Mips/MipsInstrInfo.cpp | 7 ++-- llvm/lib/Target/Mips/MipsInstrInfo.td | 17 ++++----- .../CodeGen/Mips/tailcall/tailcall-wrong-isa.ll | 43 ++++++++++++++++++++++ llvm/test/CodeGen/Mips/{ => tailcall}/tailcall.ll | 0 11 files changed, 74 insertions(+), 41 deletions(-) create mode 100644 llvm/test/CodeGen/Mips/tailcall/tailcall-wrong-isa.ll rename llvm/test/CodeGen/Mips/{ => tailcall}/tailcall.ll (100%) diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td index 2b636cf..6317897 100644 --- a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -1772,3 +1772,5 @@ let AddedComplexity = 41 in { def : LoadRegImmPat, FGR_64, ISA_MICROMIPS32R6; def : StoreRegImmPat, FGR_64, ISA_MICROMIPS32R6; } + +def TAILCALL_MMR6 : TailCall, ISA_MICROMIPS32R6; diff --git a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td index 8b9eb36..d7d2e5d 100644 --- a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td @@ -471,18 +471,6 @@ class JumpRegCMM16 : let isIndirectBranch = 1; } -let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1, - hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT] in { - class TailCall_MM : - PseudoSE<(outs), (ins calltarget:$target), [], II_J>, - PseudoInstExpansion<(JumpInst jmptarget_mm:$target)>; - - class TailCallReg_MM : - PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>, - PseudoInstExpansion<(JRInst ResRO:$rs)>; -} - // Break16 and Sdbbp16 class BrkSdbbp16MM : MicroMipsInst16<(outs), (ins uimm4:$code_), @@ -989,11 +977,7 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { def PREFX_MM : PrefetchIndexed<"prefx">, POOL32F_PREFX_FM_MM<0x15, 0x1A0>; } -let AdditionalPredicates = [InMicroMips] in { - def TAILCALL_MM : TailCall_MM, ISA_MIPS1_NOT_32R6_64R6; - def TAILCALLREG_MM : TailCallReg_MM, - ISA_MIPS1_NOT_32R6_64R6; -} +def TAILCALL_MM : TailCall, ISA_MIPS1_NOT_32R6_64R6; let DecoderNamespace = "MicroMips" in { def RDHWR_MM : MMRel, R6MMR6Rel, ReadHardware, @@ -1068,6 +1052,11 @@ let Predicates = [InMicroMips] in { (LW_MM addr:$addr)>; def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs), (SUBu_MM GPR32:$lhs, GPR32:$rhs)>; + + def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)), + (TAILCALL_MM tglobaladdr:$dst)>, ISA_MIPS1_NOT_32R6_64R6; + def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)), + (TAILCALL_MM texternalsym:$dst)>, ISA_MIPS1_NOT_32R6_64R6; } let AddedComplexity = 40 in { diff --git a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td index be239b0..f552f8d 100644 --- a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td @@ -848,8 +848,6 @@ let AdditionalPredicates = [NotInMicroMips] in { def SDC2_R6 : SDC2_R6_ENC, SDC2_R6_DESC, ISA_MIPS32R6; def SWC2_R6 : SWC2_R6_ENC, SWC2_R6_DESC, ISA_MIPS32R6; } -def TAILCALL_R6 : TailCall, ISA_MIPS32R6; -def TAILCALLREG_R6 : TailCallReg, GPR_32, ISA_MIPS32R6; //===----------------------------------------------------------------------===// // diff --git a/llvm/lib/Target/Mips/Mips64InstrInfo.td b/llvm/lib/Target/Mips/Mips64InstrInfo.td index c3d8754..62b1986 100644 --- a/llvm/lib/Target/Mips/Mips64InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td @@ -242,9 +242,9 @@ let isCodeGenOnly = 1 in { def BLEZ64 : CBranchZero<"blez", brtarget, setle, GPR64Opnd>, BGEZ_FM<6, 0>; def BLTZ64 : CBranchZero<"bltz", brtarget, setlt, GPR64Opnd>, BGEZ_FM<1, 0>; def JALR64Pseudo : JumpLinkRegPseudo; - def TAILCALLREG64 : TailCallReg, GPR_64, ISA_MIPS1_NOT_32R6_64R6; } +def TAILCALLREG64 : TailCallReg; def PseudoReturn64 : PseudoReturnBase; def PseudoIndirectBranch64 : PseudoIndirectBranchBase; diff --git a/llvm/lib/Target/Mips/Mips64r6InstrInfo.td b/llvm/lib/Target/Mips/Mips64r6InstrInfo.td index 0f36660..cc01400 100644 --- a/llvm/lib/Target/Mips/Mips64r6InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips64r6InstrInfo.td @@ -165,10 +165,6 @@ def BLTZC64 : BLTZC_ENC, BLTZC64_DESC, ISA_MIPS64R6, GPR_64; def BGEZC64 : BGEZC_ENC, BGEZC64_DESC, ISA_MIPS64R6, GPR_64; } -def TAILCALL64_R6 : TailCall, ISA_MIPS64R6; -def TAILCALLREG64_R6 : TailCallReg, GPR_64, - ISA_MIPS64R6; - //===----------------------------------------------------------------------===// // // Instruction Aliases diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp index 3136f50..7519c30 100644 --- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp @@ -98,6 +98,7 @@ bool MipsAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) { void MipsAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer, const MachineInstr *MI) { bool HasLinkReg = false; + bool InMicroMipsMode = Subtarget->inMicroMipsMode(); MCInst TmpInst0; if (Subtarget->hasMips64r6()) { @@ -106,8 +107,12 @@ void MipsAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer, HasLinkReg = true; } else if (Subtarget->hasMips32r6()) { // MIPS32r6 should use (JALR ZERO, $rs) - TmpInst0.setOpcode(Mips::JALR); - HasLinkReg = true; + if (InMicroMipsMode) + TmpInst0.setOpcode(Mips::JRC16_MMR6); + else { + TmpInst0.setOpcode(Mips::JALR); + HasLinkReg = true; + } } else if (Subtarget->inMicroMipsMode()) // microMIPS should use (JR_MM $rs) TmpInst0.setOpcode(Mips::JR_MM); @@ -185,7 +190,9 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) { if (I->getOpcode() == Mips::PseudoReturn || I->getOpcode() == Mips::PseudoReturn64 || I->getOpcode() == Mips::PseudoIndirectBranch || - I->getOpcode() == Mips::PseudoIndirectBranch64) { + I->getOpcode() == Mips::PseudoIndirectBranch64 || + I->getOpcode() == Mips::TAILCALLREG || + I->getOpcode() == Mips::TAILCALLREG64) { emitPseudoIndirectBranch(*OutStreamer, &*I); continue; } diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp index c473c6c..eb0d314 100644 --- a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp +++ b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp @@ -560,7 +560,7 @@ static int getEquivalentCallShort(int Opcode) { return Mips::JALRS16_MM; case Mips::TAILCALL_MM: llvm_unreachable("Attempting to shorten the TAILCALL_MM pseudo!"); - case Mips::TAILCALLREG_MM: + case Mips::TAILCALLREG: return Mips::JR16_MM; default: llvm_unreachable("Unexpected call instruction for microMIPS."); diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.cpp b/llvm/lib/Target/Mips/MipsInstrInfo.cpp index aedb8a4..35ddbf2 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.cpp +++ b/llvm/lib/Target/Mips/MipsInstrInfo.cpp @@ -282,7 +282,7 @@ unsigned MipsInstrInfo::getEquivalentCompactForm( case Mips::JR: case Mips::PseudoReturn: case Mips::PseudoIndirectBranch: - case Mips::TAILCALLREG_MM: + case Mips::TAILCALLREG: canUseShortMicroMipsCTI = true; break; } @@ -363,8 +363,7 @@ unsigned MipsInstrInfo::getEquivalentCompactForm( case Mips::JR: case Mips::PseudoReturn: case Mips::PseudoIndirectBranch: - case Mips::TAILCALLREG_MM: - case Mips::TAILCALLREG_R6: + case Mips::TAILCALLREG: if (canUseShortMicroMipsCTI) return Mips::JRC16_MM; return Mips::JIC; @@ -373,7 +372,7 @@ unsigned MipsInstrInfo::getEquivalentCompactForm( case Mips::JR64: case Mips::PseudoReturn64: case Mips::PseudoIndirectBranch64: - case Mips::TAILCALLREG64_R6: + case Mips::TAILCALLREG64: return Mips::JIC64; case Mips::JALR64Pseudo: return Mips::JIALC64; diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td index ff8a5fb..4dd8a5c 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsInstrInfo.td @@ -1370,14 +1370,12 @@ let isCall=1, hasDelaySlot=1, isCTI=1, Defs = [RA] in { let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1, hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT] in { - class TailCall : + class TailCall : PseudoSE<(outs), (ins calltarget:$target), [], II_J>, - PseudoInstExpansion<(JumpInst jmptarget:$target)>; + PseudoInstExpansion<(JumpInst Opnd:$target)>; - class TailCallReg : - PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>, - PseudoInstExpansion<(JRInst ResRO:$rs)>; + class TailCallReg : + MipsPseudo<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>; } class BAL_BR_Pseudo : @@ -1919,11 +1917,12 @@ def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd, 0>, BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6; def BAL_BR : BAL_BR_Pseudo; -let AdditionalPredicates = [NotInMicroMips] in { -def TAILCALL : TailCall, ISA_MIPS1_NOT_32R6_64R6; -def TAILCALLREG : TailCallReg, ISA_MIPS1_NOT_32R6_64R6, GPR_32; +let Predicates = [NotInMicroMips] in { + def TAILCALL : TailCall; } +def TAILCALLREG : TailCallReg; + // Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64 // then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA. class PseudoIndirectBranchBase : diff --git a/llvm/test/CodeGen/Mips/tailcall/tailcall-wrong-isa.ll b/llvm/test/CodeGen/Mips/tailcall/tailcall-wrong-isa.ll new file mode 100644 index 0000000..73a6fc9 --- /dev/null +++ b/llvm/test/CodeGen/Mips/tailcall/tailcall-wrong-isa.ll @@ -0,0 +1,43 @@ +; RUN: llc -filetype=obj -march=mipsel -relocation-model=pic -verify-machineinstrs < %s -o - \ +; RUN: | llvm-objdump -d - | FileCheck %s -check-prefix=PIC32 + +; RUN: llc -filetype=obj -march=mipsel -relocation-model=static -verify-machineinstrs < %s -o - \ +; RUN: | llvm-objdump -d - | FileCheck %s -check-prefix=STATIC32 + +; RUN: llc -filetype=obj -march=mips64el -mcpu=mips64 -verify-machineinstrs < %s -o - \ +; RUN: | llvm-objdump -d - | FileCheck %s -check-prefix=N64 + +; RUN: llc -filetype=obj -march=mipsel -relocation-model=pic -mattr=+micromips < %s -o - \ +; RUN: | llvm-objdump -d - | FileCheck %s -check-prefix=PIC32MM + +; RUN: llc -filetype=obj -march=mipsel -relocation-model=static -mattr=+micromips < %s -o - \ +; RUN: | llvm-objdump -d - | FileCheck %s -check-prefix=STATIC32MM + +; RUN: llc -filetype=obj -march=mipsel -relocation-model=pic -mcpu=mips32r6 < %s -o - \ +; RUN: | llvm-objdump -d - | FileCheck %s -check-prefix=PIC32R6 +; RUN: llc -filetype=obj -march=mipsel -relocation-model=static -mcpu=mips32r6 < %s -o - \ +; RUN: | llvm-objdump -d - | FileCheck %s -check-prefix=STATIC32R6 + +; RUN: llc -filetype=obj -march=mips64el -mcpu=mips64r6 < %s -o - \ +; RUN: | llvm-objdump -d - | FileCheck %s -check-prefix=N64R6 + +declare i8 @f2(i8) + +define i8 @f1(i8 signext %i) nounwind { + %a = tail call i8 @f2(i8 %i) + ret i8 %a +} + +; PIC32: {{[0-9]}}: 08 00 20 03 jr $25 +; STATIC32: {{[0-9]}}: 00 00 00 08 j 0 + +; N64: {{[0-9a-z]+}}: 08 00 20 03 jr $25 + +; PIC32MM: {{[0-9a-z]+}}: b9 45 jrc $25 +; STATIC32MM: {{[0-9]}}: 00 d4 00 00 j 0 + +; PIC32R6: {{[0-9]}}: 00 00 19 d8 jrc $25 +; STATIC32R6: {{[0-9]}}: 00 00 00 08 j 0 + +; N64R6: {{[0-9a-z]+}}: 09 00 20 03 jr $25 + diff --git a/llvm/test/CodeGen/Mips/tailcall.ll b/llvm/test/CodeGen/Mips/tailcall/tailcall.ll similarity index 100% rename from llvm/test/CodeGen/Mips/tailcall.ll rename to llvm/test/CodeGen/Mips/tailcall/tailcall.ll -- 2.7.4