Index: lib/Target/Mips/Mips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips32r6InstrInfo.td +++ lib/Target/Mips/Mips32r6InstrInfo.td @@ -412,10 +412,11 @@ dag InOperandList = (ins GPROpnd:$rt, opnd:$offset); string AsmString = !strconcat(opstr, "\t$rt, $offset"); list Pattern = []; - bit isTerminator = 1; bit hasDelaySlot = 0; InstrItinClass Itinerary = itin; bit isCTI = 1; + bit isBranch = 1; + bit isIndirectBranch = 1; } class JIALC_DESC : JMP_IDX_COMPACT_DESC_BASE<"jialc", calloffset16, @@ -427,6 +428,7 @@ class JIC_DESC : JMP_IDX_COMPACT_DESC_BASE<"jic", jmpoffset16, GPR32Opnd, II_JIALC> { bit isBarrier = 1; + bit isTerminator = 1; list Defs = [AT]; } Index: lib/Target/Mips/Mips64r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64r6InstrInfo.td +++ lib/Target/Mips/Mips64r6InstrInfo.td @@ -76,6 +76,18 @@ class SELEQZ64_DESC : SELEQNE_Z_DESC_BASE<"seleqz", GPR64Opnd>; class SELNEZ64_DESC : SELEQNE_Z_DESC_BASE<"selnez", GPR64Opnd>; +class JIALC64_DESC : JMP_IDX_COMPACT_DESC_BASE<"jialc", calloffset16, + GPR64Opnd> { + bit isCall = 1; + list Defs = [RA]; +} + +class JIC64_DESC : JMP_IDX_COMPACT_DESC_BASE<"jic", jmpoffset16, GPR64Opnd> { + bit isBarrier = 1; + bit isTerminator = 1; + list Defs = [AT]; +} + //===----------------------------------------------------------------------===// // // Instruction Definitions @@ -107,7 +119,10 @@ def SELEQZ64 : SELEQZ_ENC, SELEQZ64_DESC, ISA_MIPS32R6, GPR_64; def SELNEZ64 : SELNEZ_ENC, SELNEZ64_DESC, ISA_MIPS32R6, GPR_64; } - +let isCodeGenOnly = 1 in { +def JIALC64 : JIALC_ENC, JIALC64_DESC, ISA_MIPS64R6; +def JIC64 : JIC_ENC, JIC64_DESC, ISA_MIPS64R6; +} //===----------------------------------------------------------------------===// // // Instruction Aliases Index: lib/Target/Mips/MipsDelaySlotFiller.cpp =================================================================== --- lib/Target/Mips/MipsDelaySlotFiller.cpp +++ lib/Target/Mips/MipsDelaySlotFiller.cpp @@ -200,9 +200,6 @@ Iter replaceWithCompactBranch(MachineBasicBlock &MBB, Iter Branch, DebugLoc DL); - Iter replaceWithCompactJump(MachineBasicBlock &MBB, - Iter Jump, DebugLoc DL); - /// This function checks if it is valid to move Candidate to the delay slot /// and returns true if it isn't. It also updates memory and register /// dependence information. @@ -517,24 +514,6 @@ return Branch; } -// Replace Jumps with the compact jump instruction. -Iter Filler::replaceWithCompactJump(MachineBasicBlock &MBB, - Iter Jump, DebugLoc DL) { - const MipsInstrInfo *TII = - MBB.getParent()->getSubtarget().getInstrInfo(); - - const MCInstrDesc &NewDesc = TII->get(Mips::JRC16_MM); - MachineInstrBuilder MIB = BuildMI(MBB, Jump, DL, NewDesc); - - MIB.addReg(Jump->getOperand(0).getReg()); - - Iter tmpIter = Jump; - Jump = std::prev(Jump); - MBB.erase(tmpIter); - - return Jump; -} - // For given opcode returns opcode of corresponding instruction with short // delay slot. static int getEquivalentCallShort(int Opcode) { @@ -593,31 +572,21 @@ // corresponding instruction with short delay slot. DSI->setDesc(TII->get(getEquivalentCallShort(DSI->getOpcode()))); } - continue; } } - // If instruction is BEQ or BNE with one ZERO register, then instead of - // adding NOP replace this instruction with the corresponding compact - // branch instruction, i.e. BEQZC or BNEZC. - if (InMicroMipsMode) { - if (TII->getEquivalentCompactForm(I)) { - I = replaceWithCompactBranch(MBB, I, I->getDebugLoc()); - continue; - } - - if (I->isIndirectBranch() || I->isReturn()) { - // For microMIPS the PseudoReturn and PseudoIndirectBranch are always - // expanded to JR_MM, so they can be replaced with JRC16_MM. - I = replaceWithCompactJump(MBB, I, I->getDebugLoc()); - continue; - } - } + // For microMIPS if instruction is BEQ or BNE with one ZERO register, then + // instead of adding NOP replace this instruction with the corresponding + // compact branch instruction, i.e. BEQZC or BNEZC. Additionally + // PseduoReturn and PseudoIndirectBranch are expanded to JR_MM, so they can + // be replaced with JRC16_MM. // For MIPSR6 attempt to produce the corresponding compact (no delay slot) - // form of the branch. This should save putting in a NOP. - if ((STI.hasMips32r6()) && TII->getEquivalentCompactForm(I)) { + // form of the CTI. For indirect jumps this will not require inserting a + // NOP and for branches will hopefully avoid requiring a NOP. + if ((InMicroMipsMode || STI.hasMips32r6()) && + TII->getEquivalentCompactForm(I)) { I = replaceWithCompactBranch(MBB, I, I->getDebugLoc()); continue; } Index: lib/Target/Mips/MipsInstrInfo.cpp =================================================================== --- lib/Target/Mips/MipsInstrInfo.cpp +++ lib/Target/Mips/MipsInstrInfo.cpp @@ -260,24 +260,28 @@ unsigned MipsInstrInfo::getEquivalentCompactForm( const MachineBasicBlock::iterator I) const { unsigned Opcode = I->getOpcode(); - bool canUseShortMMBranches = + bool canUseShortMicroMipsCTI = Subtarget.inMicroMipsMode() && - (Opcode == Mips::BNE || Opcode == Mips::BEQ) && - I->getOperand(1).getReg() == Subtarget.getABI().GetZeroReg(); - - if (Subtarget.hasMips32r6() || canUseShortMMBranches) { + (((Opcode == Mips::BNE || Opcode == Mips::BEQ) && + I->getOperand(1).getReg() == Subtarget.getABI().GetZeroReg()) || + // For microMIPS the PseudoReturn and PseudoIndirectBranch are always + // expanded to JR_MM, so they can be replaced with JRC16_MM. + (Opcode == Mips::JR || Opcode == Mips::PseudoReturn || + Opcode == Mips::PseudoIndirectBranch)); + + if (Subtarget.hasMips32r6() || canUseShortMicroMipsCTI) { switch (Opcode) { case Mips::B: return Mips::BC; case Mips::BAL: return Mips::BALC; case Mips::BEQ: - if (canUseShortMMBranches) + if (canUseShortMicroMipsCTI) return Mips::BEQZC_MM; else return Mips::BEQC; case Mips::BNE: - if (canUseShortMMBranches) + if (canUseShortMicroMipsCTI) return Mips::BNEZC_MM; else return Mips::BNEC; @@ -297,7 +301,23 @@ return Mips::BLTUC; case Mips::BLTZ: return Mips::BLTZC; - default: + // For MIPSR6, the instruction 'jic' can be used for these cases. Some + // tools will accept 'jrc reg' as an alias for 'jic 0, $reg'. + case Mips::JR: + case Mips::PseudoReturn: + case Mips::PseudoIndirectBranch: + if (canUseShortMicroMipsCTI) + return Mips::JRC16_MM; + return Mips::JIC; + case Mips::JALRPseudo: + return Mips::JIALC; + case Mips::JR64: + case Mips::PseudoReturn64: + case Mips::PseudoIndirectBranch64: + return Mips::JIC64; + case Mips::JALR64Pseudo: + return Mips::JIALC64; + default: return 0; } } @@ -342,19 +362,20 @@ MipsInstrInfo::genInstrWithNewOpc(unsigned NewOpc, MachineBasicBlock::iterator I) const { MachineInstrBuilder MIB; - bool BranchWithZeroOperand = false; // Certain branches have two forms: e.g beq $1, $zero, dst vs beqz $1, dest // Pick the zero form of the branch for readable assembly and for greater // branch distance in non-microMIPS mode. - if (I->isBranch() && I->getOperand(1).isReg() && - // FIXME: Certain atomic sequences on mips64 generate 32bit references to - // Mips::ZERO, which is incorrect. This test should be updated to use - // Subtarget.getABI().GetZeroReg() when those atomic sequences and others - // are fixed. - (I->getOperand(1).getReg() == Mips::ZERO || - I->getOperand(1).getReg() == Mips::ZERO_64)) { - BranchWithZeroOperand = true; + // FIXME: Certain atomic sequences on mips64 generate 32bit references to + // Mips::ZERO, which is incorrect. This test should be updated to use + // Subtarget.getABI().GetZeroReg() when those atomic sequences and others + // are fixed. + bool BranchWithZeroOperand = + (I->isBranch() && !I->isPseudo() && I->getOperand(1).isReg() && + (I->getOperand(1).getReg() == Mips::ZERO || + I->getOperand(1).getReg() == Mips::ZERO_64)); + + if (BranchWithZeroOperand) { switch (NewOpc) { case Mips::BEQC: NewOpc = Mips::BEQZC; @@ -368,20 +389,43 @@ case Mips::BLTC: NewOpc = Mips::BLTZC; break; - case Mips::BNEZC_MM: - case Mips::BEQZC_MM: - break; - default: - BranchWithZeroOperand = false; - break; } } MIB = BuildMI(*I->getParent(), I, I->getDebugLoc(), get(NewOpc)); - for (unsigned J = 0, E = I->getDesc().getNumOperands(); J < E; ++J) - if (!(BranchWithZeroOperand && (J == 1))) + // For MIPSR6 JI*C requires an immediate 0 as an operand, JIALC(64) an + // immediate 0 as an operand and requires the removal of it's %RA + // implicit operand as copying the implicit operations of the instructio we're + // looking at will give us the correct flags. + if (NewOpc == Mips::JIC || NewOpc == Mips::JIALC || NewOpc == Mips::JIC64 || + NewOpc == Mips::JIALC64) { + + if (NewOpc == Mips::JIALC || NewOpc == Mips::JIALC64) + MIB->RemoveOperand(0); + + for (unsigned J = 0, E = I->getDesc().getNumOperands(); J < E; ++J) { MIB.addOperand(I->getOperand(J)); + } + + MIB.addImm(0); + + } else if (BranchWithZeroOperand) { + // For MIPSR6 and microMIPS branches with an explicit zero operand, copy + // everything after the zero. + MIB.addOperand(I->getOperand(0)); + + for (unsigned J = 2, E = I->getDesc().getNumOperands(); J < E; ++J) { + MIB.addOperand(I->getOperand(J)); + } + } else { + // All other cases copy all other operands. + for (unsigned J = 0, E = I->getDesc().getNumOperands(); J < E; ++J) { + MIB.addOperand(I->getOperand(J)); + } + } + + MIB.copyImplicitOps(*I); MIB.setMemRefs(I->memoperands_begin(), I->memoperands_end()); return MIB; Index: test/CodeGen/Mips/compactbranches/compact-branches.ll =================================================================== --- test/CodeGen/Mips/compactbranches/compact-branches.ll +++ test/CodeGen/Mips/compactbranches/compact-branches.ll @@ -1,21 +1,26 @@ -; RUN: llc -march=mipsel -mcpu=mips32r6 -relocation-model=static < %s | FileCheck %s +; RUN: llc -march=mipsel -mcpu=mips32r6 -relocation-model=static -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=STATIC32 +; RUN: llc -march=mipsel -mcpu=mips64r6 -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=PIC ; Function Attrs: nounwind define void @l() { entry: +; PIC: jialc $25, 0 %call = tail call i32 @k() +; PIC: jialc $25, 0 %call1 = tail call i32 @j() %cmp = icmp eq i32 %call, %call1 ; CHECK: bnec br i1 %cmp, label %if.then, label %if.end if.then: ; preds = %entry: -; CHECK: nop -; CHECK: jal +; STATIC: nop +; STATIC: jal +; PIC: jialc $25, 0 tail call void @f(i32 signext -2) br label %if.end if.end: ; preds = %if.then, %entry +; CHECK: jic $ra, 0 ret void } @@ -28,19 +33,23 @@ ; Function Attrs: define void @l2() { define void @l2() { entry: +; PIC: jialc $25, 0 %call = tail call i32 @k() +; PIC: jialc $25, 0 %call1 = tail call i32 @i() %cmp = icmp eq i32 %call, %call1 ; CHECK beqc br i1 %cmp, label %if.end, label %if.then if.then: ; preds = %entry: -; CHECK: nop -; CHECK: jal +; STATIC: nop +; STATIC: jal +; PIC: jialc $25, 0 tail call void @f(i32 signext -1) br label %if.end if.end: ; preds = %entry, %if.then +; CHECK: jic $ra, 0 ret void } @@ -49,18 +58,21 @@ ; Function Attrs: nounwind define void @l3() { entry: +; PIC: jialc $25, 0 %call = tail call i32 @k() %cmp = icmp slt i32 %call, 0 ; CHECK : bgez br i1 %cmp, label %if.then, label %if.end if.then: ; preds = %entry: -; CHECK: nop -; CHECK: jal +; STATIC: nop +; STATIC: jal +; PIC: jialc $25, 0 tail call void @f(i32 signext 0) br label %if.end if.end: ; preds = %if.then, %entry +; CHECK: jic $ra, 0 ret void } @@ -73,83 +85,122 @@ br i1 %cmp, label %if.then, label %if.end if.then: ; preds = %entry: -; CHECK: nop -; CHECK: jal +; STATIC: nop +; STATIC: jal tail call void @f(i32 signext 1) br label %if.end if.end: ; preds = %if.then, %entry +; CHECK: jic $ra, 0 ret void } ; Function Attrs: nounwind define void @l5() { entry: +; PIC: jialc $25, 0 %call = tail call i32 @k() +; PIC: jialc $25, 0 %cmp = icmp sgt i32 %call, 0 ; CHECK: blezc br i1 %cmp, label %if.then, label %if.end if.then: ; preds = %entry: -; CHECK: nop -; CHECK: jal +; STATIC: nop +; STATIC: jal +; PIC: jialc $25, 0 tail call void @f(i32 signext 2) br label %if.end if.end: ; preds = %if.then, %entry +; CHECK: jic $ra, 0 ret void } ; Function Attrs: nounwind define void @l6() { entry: +; PIC: jialc $25, 0 %call = tail call i32 @k() +; PIC: jialc $25, 0 %cmp = icmp sgt i32 %call, -1 ; CHECK: bltzc br i1 %cmp, label %if.then, label %if.end if.then: ; preds = %entry: -; CHECK: nop -; CHECK: jal +; STATIC: nop +; STATIC: jal +; PIC: jialc $25, 0 tail call void @f(i32 signext 3) br label %if.end if.end: ; preds = %if.then, %entry +; CHECK: jic $ra, 0 ret void } ; Function Attrs: nounwind define void @l7() { entry: +; PIC: jialc $25, 0 %call = tail call i32 @k() %cmp = icmp eq i32 %call, 0 ; CHECK: bnezc br i1 %cmp, label %if.then, label %if.end if.then: ; preds = %entry: -; CHECK: nop -; CHECK: jal +; STATIC: nop +; STATIC: jal +; PIC: jialc $25, 0 tail call void @f(i32 signext 4) br label %if.end if.end: ; preds = %if.then, %entry +; CHECK: jic $ra, 0 ret void } ; Function Attrs: nounwind define void @l8() { entry: +; PIC: jialc $25, 0 %call = tail call i32 @k() %cmp = icmp eq i32 %call, 0 ; CHECK: beqzc br i1 %cmp, label %if.end, label %if.then if.then: ; preds = %entry: -; CHECK: nop -; CHECK: jal +; STATIC: nop +; STATIC: jal +; PIC: jialc $25, 0 tail call void @f(i32 signext 5) br label %if.end if.end: ; preds = %entry, %if.then +; CHECK: jic $ra, 0 ret void } + +define i32 @l9(i8* ()* %i) #0 { +entry: + %i.addr = alloca i8* ()*, align 4 + store i8* ()* %i, i8* ()** %i.addr, align 4 +; STATIC32: jal +; STATIC32: nop +; PIC: jialc $25, 0 + %call = call i32 @k() +; PIC: jialc $25, 0 + %cmp = icmp ne i32 %call, 0 +; CHECK: beqzc + br i1 %cmp, label %if.then, label %if.end + +if.then: ; preds = %entry + %0 = load i8* ()*, i8* ()** %i.addr, align 4 +; CHECK: jialc $25, 0 + %call1 = call i8* %0() + br label %if.end + +if.end: ; preds = %if.then, %entry +; CHECK: jic $ra, 0 + ret i32 -1 +} Index: test/CodeGen/Mips/llvm-ir/call.ll =================================================================== --- test/CodeGen/Mips/llvm-ir/call.ll +++ test/CodeGen/Mips/llvm-ir/call.ll @@ -1,18 +1,18 @@ ; Test the 'call' instruction and the tailcall variant. ; FIXME: We should remove the need for -enable-mips-tail-calls -; RUN: llc -march=mips -mcpu=mips32 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -; RUN: llc -march=mips -mcpu=mips32r2 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -; RUN: llc -march=mips -mcpu=mips32r3 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -; RUN: llc -march=mips -mcpu=mips32r5 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -; RUN: llc -march=mips -mcpu=mips32r6 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -; RUN: llc -march=mips -mcpu=mips32r6 -mattr=+fp64,+nooddspreg -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -; RUN: llc -march=mips64 -mcpu=mips4 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -; RUN: llc -march=mips64 -mcpu=mips64 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -; RUN: llc -march=mips64 -mcpu=mips64r2 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -; RUN: llc -march=mips64 -mcpu=mips64r3 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -; RUN: llc -march=mips64 -mcpu=mips64r5 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -; RUN: llc -march=mips64 -mcpu=mips64r6 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 +; RUN: llc -march=mips -mcpu=mips32 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=NOT-R6C +; RUN: llc -march=mips -mcpu=mips32r2 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=NOT-R6C +; RUN: llc -march=mips -mcpu=mips32r3 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=NOT-R6C +; RUN: llc -march=mips -mcpu=mips32r5 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=NOT-R6C +; RUN: llc -march=mips -mcpu=mips32r6 -disable-mips-delay-filler -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=R6C +; RUN: llc -march=mips -mcpu=mips32r6 -mattr=+fp64,+nooddspreg -disable-mips-delay-filler -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 -check-prefix=R6C +; RUN: llc -march=mips64 -mcpu=mips4 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C +; RUN: llc -march=mips64 -mcpu=mips64 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C +; RUN: llc -march=mips64 -mcpu=mips64r2 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C +; RUN: llc -march=mips64 -mcpu=mips64r3 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C +; RUN: llc -march=mips64 -mcpu=mips64r5 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=NOT-R6C +; RUN: llc -march=mips64 -mcpu=mips64r6 -disable-mips-delay-filler -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 -check-prefix=R6C declare void @extern_void_void() declare i32 @extern_i32_void() @@ -25,7 +25,8 @@ ; N64: ld $[[TGT:[0-9]+]], %call16(extern_void_void)($gp) -; ALL: jalr $[[TGT]] +; NOT-R6C: jalr $[[TGT]] +; R6C: jialc $[[TGT]], 0 call void @extern_void_void() ret i32 0 @@ -38,7 +39,8 @@ ; N64: ld $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp) -; ALL: jalr $[[TGT]] +; NOT-R6C: jalr $[[TGT]] +; R6C: jialc $[[TGT]], 0 %1 = call i32 @extern_i32_void() %2 = add i32 %1, 1 @@ -55,9 +57,9 @@ ; N64: ld $[[TGT:[0-9]+]], %call16(extern_float_void)($gp) -; ALL: jalr $[[TGT]] +; NOT-R6C: jalr $[[TGT]] +; R6C: jialc $[[TGT]], 0 -; O32: move $gp, $[[GP]] %1 = call float @extern_float_void() %2 = fadd float %1, 1.0 @@ -71,8 +73,7 @@ ; N64: ld $[[TGT:[0-9]+]], %call16(extern_void_void)($gp) -; NOT-R6: jr $[[TGT]] -; R6: r6.jr $[[TGT]] +; ALL: jr $[[TGT]] musttail call void @extern_void_void() ret void @@ -85,8 +86,7 @@ ; N64: ld $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp) -; NOT-R6: jr $[[TGT]] -; R6: r6.jr $[[TGT]] +; ALL: jr $[[TGT]] %1 = musttail call i32 @extern_i32_void() ret i32 %1 @@ -99,8 +99,7 @@ ; N64: ld $[[TGT:[0-9]+]], %call16(extern_float_void)($gp) -; NOT-R6: jr $[[TGT]] -; R6: r6.jr $[[TGT]] +; ALL: jr $[[TGT]] %1 = musttail call float @extern_float_void() ret float %1 @@ -110,7 +109,9 @@ ; ALL-LABEL: indirect_call_void_void: ; ALL: move $25, $4 -; ALL: jalr $25 +; NOT-R6C: jalr $25 +; R6C: jialc $25, 0 + call void %addr() ret i32 0 @@ -120,7 +121,9 @@ ; ALL-LABEL: indirect_call_i32_void: ; ALL: move $25, $4 -; ALL: jalr $25 +; NOT-R6C: jalr $25 +; R6C: jialc $25, 0 + %1 = call i32 %addr() %2 = add i32 %1, 1 @@ -131,7 +134,9 @@ ; ALL-LABEL: indirect_call_float_void: ; ALL: move $25, $4 -; ALL: jalr $25 +; NOT-R6C: jalr $25 +; R6C: jialc $25, 0 + %1 = call float %addr() %2 = fadd float %1, 1.0 @@ -178,7 +183,8 @@ ; ALL-LABEL: thunk_undef_double: ; O32: # implicit-def: %A2 ; O32: # implicit-def: %A3 -; ALL: jr $25 +; ALL: jr $25 + tail call void @undef_double(i32 undef, double undef) #8 ret void } @@ -190,7 +196,8 @@ ; ALL-NOT: {{jal }} ; ALL: addiu $[[TGT:[0-9]+]], $zero, 1234 ; ALL-NOT: {{jal }} -; ALL: jalr $[[TGT]] +; NOT-R6C: jalr $[[TGT]] +; R6C: jialc $[[TGT]], 0 ; ALL-NOT: {{jal }} call void () inttoptr (i32 1234 to void ()*)() Index: test/CodeGen/Mips/llvm-ir/indirectbr.ll =================================================================== --- test/CodeGen/Mips/llvm-ir/indirectbr.ll +++ test/CodeGen/Mips/llvm-ir/indirectbr.ll @@ -4,7 +4,7 @@ ; RUN: llc -march=mips -mcpu=mips32r2 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=NOT-R6 ; RUN: llc -march=mips -mcpu=mips32r3 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=NOT-R6 ; RUN: llc -march=mips -mcpu=mips32r5 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=NOT-R6 -; RUN: llc -march=mips -mcpu=mips32r6 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=R6 +; RUN: llc -march=mips -mcpu=mips32r6 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=R6C ; RUN: llc -march=mips64 -mcpu=mips4 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=NOT-R6 ; RUN: llc -march=mips64 -mcpu=mips64 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=NOT-R6 ; RUN: llc -march=mips64 -mcpu=mips64r2 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=NOT-R6 @@ -15,16 +15,19 @@ define i32 @br(i8 *%addr) { ; ALL-LABEL: br: ; NOT-R6: jr $4 #