[llvm] r265390 - [mips] MIPSR6 Compact jump support

Simon Dardis via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 5 05:50:29 PDT 2016


Author: sdardis
Date: Tue Apr  5 07:50:29 2016
New Revision: 265390

URL: http://llvm.org/viewvc/llvm-project?rev=265390&view=rev
Log:
[mips] MIPSR6 Compact jump support

This patch adds support for compact jumps similiar to the previous compact
branch support for MIPSR6. Unlike compact branches, compact jumps do not
have a forbidden slot.

As MipsInstrInfo::getEquivalentCompactForm can determine the correct
expansion for jumps and branches for both microMIPS and MIPSR6, remove the
unnecessary distinction in the delay slot filler.

Reviewers: vkalintiris

Subscribers: llvm-commits, dsanders

Modified:
    llvm/trunk/lib/Target/Mips/Mips32r6InstrInfo.td
    llvm/trunk/lib/Target/Mips/Mips64r6InstrInfo.td
    llvm/trunk/lib/Target/Mips/MipsDelaySlotFiller.cpp
    llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp
    llvm/trunk/test/CodeGen/Mips/compactbranches/compact-branches.ll
    llvm/trunk/test/CodeGen/Mips/llvm-ir/call.ll
    llvm/trunk/test/CodeGen/Mips/llvm-ir/indirectbr.ll
    llvm/trunk/test/CodeGen/Mips/llvm-ir/ret.ll
    llvm/trunk/test/CodeGen/Mips/mips64-f128.ll
    llvm/trunk/test/MC/Mips/mips32r6/valid.s

Modified: llvm/trunk/lib/Target/Mips/Mips32r6InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/Mips32r6InstrInfo.td?rev=265390&r1=265389&r2=265390&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/Mips32r6InstrInfo.td (original)
+++ llvm/trunk/lib/Target/Mips/Mips32r6InstrInfo.td Tue Apr  5 07:50:29 2016
@@ -412,10 +412,11 @@ class JMP_IDX_COMPACT_DESC_BASE<string o
   dag InOperandList = (ins GPROpnd:$rt, opnd:$offset);
   string AsmString = !strconcat(opstr, "\t$rt, $offset");
   list<dag> 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 JIALC_DESC : JMP_IDX_COMPACT_DESC_
 class JIC_DESC : JMP_IDX_COMPACT_DESC_BASE<"jic", jmpoffset16,
                                            GPR32Opnd, II_JIALC> {
   bit isBarrier = 1;
+  bit isTerminator = 1;
   list<Register> Defs = [AT];
 }
 

Modified: llvm/trunk/lib/Target/Mips/Mips64r6InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/Mips64r6InstrInfo.td?rev=265390&r1=265389&r2=265390&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/Mips64r6InstrInfo.td (original)
+++ llvm/trunk/lib/Target/Mips/Mips64r6InstrInfo.td Tue Apr  5 07:50:29 2016
@@ -76,6 +76,18 @@ class SCD_R6_DESC   : SC_R6_DESC_BASE<"s
 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<Register> Defs = [RA];
+}
+
+class JIC64_DESC : JMP_IDX_COMPACT_DESC_BASE<"jic", jmpoffset16, GPR64Opnd> {
+  bit isBarrier = 1;
+  bit isTerminator = 1;
+  list<Register> Defs = [AT];
+}
+
 //===----------------------------------------------------------------------===//
 //
 // Instruction Definitions
@@ -107,7 +119,10 @@ let DecoderNamespace = "Mips32r6_64r6_GP
   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

Modified: llvm/trunk/lib/Target/Mips/MipsDelaySlotFiller.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsDelaySlotFiller.cpp?rev=265390&r1=265389&r2=265390&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsDelaySlotFiller.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsDelaySlotFiller.cpp Tue Apr  5 07:50:29 2016
@@ -205,9 +205,6 @@ namespace {
     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.
@@ -522,24 +519,6 @@ Iter Filler::replaceWithCompactBranch(Ma
   return Branch;
 }
 
-// Replace Jumps with the compact jump instruction.
-Iter Filler::replaceWithCompactJump(MachineBasicBlock &MBB,
-                                    Iter Jump, DebugLoc DL) {
-  const MipsInstrInfo *TII =
-      MBB.getParent()->getSubtarget<MipsSubtarget>().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) {
@@ -604,31 +583,21 @@ bool Filler::runOnMachineBasicBlock(Mach
           // 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
+    // PseudoReturn 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;
     }

Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp?rev=265390&r1=265389&r2=265390&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp Tue Apr  5 07:50:29 2016
@@ -261,24 +261,40 @@ MipsInstrInfo::BranchType MipsInstrInfo:
 unsigned MipsInstrInfo::getEquivalentCompactForm(
     const MachineBasicBlock::iterator I) const {
   unsigned Opcode = I->getOpcode();
-  bool canUseShortMMBranches =
-      Subtarget.inMicroMipsMode() &&
-      (Opcode == Mips::BNE || Opcode == Mips::BEQ) &&
-      I->getOperand(1).getReg() == Subtarget.getABI().GetZeroReg();
+  bool canUseShortMicroMipsCTI = false;
 
-  if (Subtarget.hasMips32r6() || canUseShortMMBranches) {
+  if (Subtarget.inMicroMipsMode()) {
+    switch (Opcode) {
+    case Mips::BNE:
+    case Mips::BEQ:
+    // microMIPS has NE,EQ branches that do not have delay slots provided one
+    // of the operands is zero.
+      if (I->getOperand(1).getReg() == Subtarget.getABI().GetZeroReg())
+        canUseShortMicroMipsCTI = true;
+      break;
+    // For microMIPS the PseudoReturn and PseudoIndirectBranch are always
+    // expanded to JR_MM, so they can be replaced with JRC16_MM.
+    case Mips::JR:
+    case Mips::PseudoReturn:
+    case Mips::PseudoIndirectBranch:
+      canUseShortMicroMipsCTI = true;
+      break;
+    }
+  }
+
+  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;
@@ -298,7 +314,23 @@ unsigned MipsInstrInfo::getEquivalentCom
       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;
     }
   }
@@ -343,19 +375,20 @@ MachineInstrBuilder
 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;
@@ -369,20 +402,43 @@ MipsInstrInfo::genInstrWithNewOpc(unsign
     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<imp-def>
+  // 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;

Modified: llvm/trunk/test/CodeGen/Mips/compactbranches/compact-branches.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/compactbranches/compact-branches.ll?rev=265390&r1=265389&r2=265390&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/compactbranches/compact-branches.ll (original)
+++ llvm/trunk/test/CodeGen/Mips/compactbranches/compact-branches.ll Tue Apr  5 07:50:29 2016
@@ -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 @@ declare void @f(i32 signext)
 ; 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 @@ declare i32 @i()
 ; 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 @@ entry:
   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
+}

Modified: llvm/trunk/test/CodeGen/Mips/llvm-ir/call.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/llvm-ir/call.ll?rev=265390&r1=265389&r2=265390&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/llvm-ir/call.ll (original)
+++ llvm/trunk/test/CodeGen/Mips/llvm-ir/call.ll Tue Apr  5 07:50:29 2016
@@ -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 @@ define i32 @call_void_void() {
 
 ; 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 @@ define i32 @call_i32_void() {
 
 ; 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 @@ define float @call_float_void() {
 
 ; 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 @@ define void @musttail_call_void_void() {
 
 ; 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 @@ define i32 @musttail_call_i32_void() {
 
 ; 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 @@ define float @musttail_call_float_void()
 
 ; 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 @@ define i32 @indirect_call_void_void(void
 ; 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 @@ define i32 @indirect_call_i32_void(i32 (
 ; 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 @@ define float @indirect_call_float_void(f
 ; 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 @@ define hidden void @thunk_undef_double(i
 ; 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 @@ define i32 @jal_only_allows_symbols() {
 ; 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 ()*)()

Modified: llvm/trunk/test/CodeGen/Mips/llvm-ir/indirectbr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/llvm-ir/indirectbr.ll?rev=265390&r1=265389&r2=265390&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/llvm-ir/indirectbr.ll (original)
+++ llvm/trunk/test/CodeGen/Mips/llvm-ir/indirectbr.ll Tue Apr  5 07:50:29 2016
@@ -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 # <MCInst #{{[0-9]+}} JR
-; R6:            jr $4 # <MCInst #{{[0-9]+}} JALR
+; R6C:           jic $4, 0 # <MCInst #{{[0-9]+}} JIC
+
 
 ; ALL: $BB0_1: # %L1
 ; NOT-R6:        jr $ra # <MCInst #{{[0-9]+}} JR
 ; R6:            jr $ra # <MCInst #{{[0-9]+}} JALR
+; R6C:           jr $ra # <MCInst #{{[0-9]+}} JALR
 ; ALL:           addiu $2, $zero, 0
 
 ; ALL: $BB0_2: # %L2
 ; NOT-R6:        jr $ra # <MCInst #{{[0-9]+}} JR
 ; R6:            jr $ra # <MCInst #{{[0-9]+}} JALR
+; R6C:           jr $ra # <MCInst #{{[0-9]+}} JALR
 ; ALL:           addiu $2, $zero, 1
 
 entry:

Modified: llvm/trunk/test/CodeGen/Mips/llvm-ir/ret.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/llvm-ir/ret.ll?rev=265390&r1=265389&r2=265390&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/llvm-ir/ret.ll (original)
+++ llvm/trunk/test/CodeGen/Mips/llvm-ir/ret.ll Tue Apr  5 07:50:29 2016
@@ -11,19 +11,27 @@
 ; RUN: llc -march=mips   -mcpu=mips32r2 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR32 -check-prefix=MTHC1 -check-prefix=NOT-R6
 ; RUN: llc -march=mips   -mcpu=mips32r3 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR32 -check-prefix=MTHC1 -check-prefix=NOT-R6
 ; RUN: llc -march=mips   -mcpu=mips32r5 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR32 -check-prefix=MTHC1 -check-prefix=NOT-R6
-; RUN: llc -march=mips   -mcpu=mips32r6 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR32 -check-prefix=MTHC1 -check-prefix=R6
+; RUN: llc -march=mips   -mcpu=mips32r6 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR32 -check-prefix=MTHC1 -check-prefix=R6C
 ; RUN: llc -march=mips64 -mcpu=mips4    -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=DMTC1 -check-prefix=NOT-R6
 ; RUN: llc -march=mips64 -mcpu=mips64   -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=DMTC1 -check-prefix=NOT-R6
 ; RUN: llc -march=mips64 -mcpu=mips64r2 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=DMTC1 -check-prefix=NOT-R6
 ; RUN: llc -march=mips64 -mcpu=mips64r3 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=DMTC1 -check-prefix=NOT-R6
 ; RUN: llc -march=mips64 -mcpu=mips64r5 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=DMTC1 -check-prefix=NOT-R6
-; RUN: llc -march=mips64 -mcpu=mips64r6 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=DMTC1 -check-prefix=R6
+
+; FIXME: for the test ret_double_0x0, the delay slot of jr cannot be filled
+;        as mthc1 has unmodeled side effects. This is an artifact of our backend.
+;        Force the delay slot filler off to check that the sequence jr $ra; nop is
+;        turned into jic 0, $ra.
+
+; RUN: llc -march=mips64 -mcpu=mips64r6 -asm-show-inst -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=DMTC1 \
+; RUN:     -check-prefix=R6C
 
 define void @ret_void() {
 ; ALL-LABEL: ret_void:
 
 ; NOT-R6-DAG:    jr $ra # <MCInst #{{[0-9]+}} JR
 ; R6-DAG:        jr $ra # <MCInst #{{[0-9]+}} JALR
+; R6C-DAG:       jic $ra, 0 # <MCInst #{{[0-9]+}} JIC
 
   ret void
 }
@@ -173,6 +181,7 @@ define float @ret_float_0x3() {
 
 ; NOT-R6-DAG:    jr $ra # <MCInst #{{[0-9]+}} JR
 ; R6-DAG:        jr $ra # <MCInst #{{[0-9]+}} JALR
+; R6C-DAG:       jic $ra, 0 # <MCInst #{{[0-9]+}} JIC
 
 ; float constants are written as double constants
   ret float 0x36b8000000000000
@@ -191,6 +200,7 @@ define double @ret_double_0x0() {
 
 ; NOT-R6-DAG:    jr $ra # <MCInst #{{[0-9]+}} JR
 ; R6-DAG:        jr $ra # <MCInst #{{[0-9]+}} JALR
+; R6C-DAG:       jic $ra, 0 # <MCInst #{{[0-9]+}} JIC
 
   ret double 0x0000000000000000
 }
@@ -204,6 +214,7 @@ define double @ret_double_0x3() {
 
 ; NOT-R6-DAG:    jr $ra # <MCInst #{{[0-9]+}} JR
 ; R6-DAG:        jr $ra # <MCInst #{{[0-9]+}} JALR
+; R6C-DAG:       jic $ra, 0 # <MCInst #{{[0-9]+}} JIC
 
   ret double 0x0000000000000003
 }

Modified: llvm/trunk/test/CodeGen/Mips/mips64-f128.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/mips64-f128.ll?rev=265390&r1=265389&r2=265390&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/mips64-f128.ll (original)
+++ llvm/trunk/test/CodeGen/Mips/mips64-f128.ll Tue Apr  5 07:50:29 2016
@@ -1,11 +1,11 @@
 ; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips4 -mattr=+soft-float -O1 \
-; RUN:     -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=ALL -check-prefix=C_CC_FMT
+; RUN:     -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=ALL -check-prefix=C_CC_FMT -check-prefix=PRER6
 ; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips64 -mattr=+soft-float -O1 \
-; RUN:     -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=ALL -check-prefix=C_CC_FMT
+; RUN:     -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=ALL -check-prefix=C_CC_FMT -check-prefix=PRER6
 ; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips64r2 -mattr=+soft-float -O1 \
-; RUN:     -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=ALL -check-prefix=C_CC_FMT
+; RUN:     -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=ALL -check-prefix=C_CC_FMT -check-prefix=PRER6
 ; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips64r6 -mattr=+soft-float -O1 \
-; RUN:     -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=ALL -check-prefix=CMP_CC_FMT
+; RUN:     -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=ALL -check-prefix=CMP_CC_FMT -check-prefix=R6
 
 @gld0 = external global fp128
 @gld1 = external global fp128
@@ -544,10 +544,11 @@ entry:
 }
 
 ; ALL-LABEL: load_LD_float:
-; ALL: ld   $[[R0:[0-9]+]], %got_disp(gf1)
-; ALL: lw   $4, 0($[[R0]])
-; ALL: ld   $25, %call16(__extendsftf2)
-; ALL: jalr $25
+; ALL:   ld   $[[R0:[0-9]+]], %got_disp(gf1)
+; ALL:   lw   $4, 0($[[R0]])
+; ALL:   ld   $25, %call16(__extendsftf2)
+; PRER6: jalr $25
+; R6:    jialc $25, 0
 
 define fp128 @load_LD_float() {
 entry:
@@ -557,10 +558,11 @@ entry:
 }
 
 ; ALL-LABEL: load_LD_double:
-; ALL: ld   $[[R0:[0-9]+]], %got_disp(gd1)
-; ALL: ld   $4, 0($[[R0]])
-; ALL: ld   $25, %call16(__extenddftf2)
-; ALL: jalr $25
+; ALL:   ld   $[[R0:[0-9]+]], %got_disp(gd1)
+; ALL:   ld   $4, 0($[[R0]])
+; ALL:   ld   $25, %call16(__extenddftf2)
+; PRER6: jalr $25
+; R6:    jialc $25, 0
 
 define fp128 @load_LD_double() {
 entry:
@@ -585,13 +587,14 @@ entry:
 }
 
 ; ALL-LABEL: store_LD_float:
-; ALL: ld   $[[R0:[0-9]+]], %got_disp(gld1)
-; ALL: ld   $4, 0($[[R0]])
-; ALL: ld   $5, 8($[[R0]])
-; ALL: ld   $25, %call16(__trunctfsf2)
-; ALL: jalr $25
-; ALL: ld   $[[R1:[0-9]+]], %got_disp(gf1)
-; ALL: sw   $2, 0($[[R1]])
+; ALL:   ld   $[[R0:[0-9]+]], %got_disp(gld1)
+; ALL:   ld   $4, 0($[[R0]])
+; ALL:   ld   $5, 8($[[R0]])
+; ALL:   ld   $25, %call16(__trunctfsf2)
+; PRER6: jalr $25
+; R6:    jialc $25, 0
+; ALL:   ld   $[[R1:[0-9]+]], %got_disp(gf1)
+; ALL:   sw   $2, 0($[[R1]])
 
 define void @store_LD_float() {
 entry:
@@ -602,13 +605,14 @@ entry:
 }
 
 ; ALL-LABEL: store_LD_double:
-; ALL: ld   $[[R0:[0-9]+]], %got_disp(gld1)
-; ALL: ld   $4, 0($[[R0]])
-; ALL: ld   $5, 8($[[R0]])
-; ALL: ld   $25, %call16(__trunctfdf2)
-; ALL: jalr $25
-; ALL: ld   $[[R1:[0-9]+]], %got_disp(gd1)
-; ALL: sd   $2, 0($[[R1]])
+; ALL:   ld   $[[R0:[0-9]+]], %got_disp(gld1)
+; ALL:   ld   $4, 0($[[R0]])
+; ALL:   ld   $5, 8($[[R0]])
+; ALL:   ld   $25, %call16(__trunctfdf2)
+; PRER6: jalr $25
+; R6:    jialc $25, 0
+; ALL:   ld   $[[R1:[0-9]+]], %got_disp(gd1)
+; ALL:   sd   $2, 0($[[R1]])
 
 define void @store_LD_double() {
 entry:
@@ -648,7 +652,8 @@ entry:
 ; ALL:           move $[[R2:[0-9]+]], $9
 ; ALL:           move $[[R3:[0-9]+]], $8
 ; ALL:           ld   $25, %call16(__gttf2)($gp)
-; ALL:           jalr $25
+; PRER6:         jalr $25
+; R6:            jialc $25, 0
 
 ; C_CC_FMT:      slti $[[CC:[0-9]+]], $2, 1
 ; C_CC_FMT:      movz $[[R1]], $[[R3]], $[[CC]]

Modified: llvm/trunk/test/MC/Mips/mips32r6/valid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/mips32r6/valid.s?rev=265390&r1=265389&r2=265390&view=diff
==============================================================================
--- llvm/trunk/test/MC/Mips/mips32r6/valid.s (original)
+++ llvm/trunk/test/MC/Mips/mips32r6/valid.s Tue Apr  5 07:50:29 2016
@@ -165,6 +165,8 @@ a:
         jr      $25              # CHECK: jr $25                 # encoding: [0x03,0x20,0x00,0x09]
         jalr.hb $4               # CHECK: jalr.hb $4             # encoding: [0x00,0x80,0xfc,0x09]
         jalr.hb $4, $5           # CHECK: jalr.hb $4, $5         # encoding: [0x00,0xa0,0x24,0x09]
+        jialc   $15, 16161       # CHECK: jialc $15, 16161       # encoding: [0xf8,0x0f,0x3f,0x21]
+        jic     $12, -3920       # CHECK: jic $12, -3920         # encoding: [0xd8,0x0c,0xf0,0xb0]
         ldc2    $8, -701($at)    # CHECK: ldc2 $8, -701($1)      # encoding: [0x49,0xc8,0x0d,0x43]
         lwc2    $18,-841($a2)    # CHECK: lwc2 $18, -841($6)     # encoding: [0x49,0x52,0x34,0xb7]
         sdc2    $20,629($s2)     # CHECK: sdc2 $20, 629($18)     # encoding: [0x49,0xf4,0x92,0x75]




More information about the llvm-commits mailing list