[llvm] r269893 - [mips] Restrict the creation of compact branches

Simon Dardis via llvm-commits llvm-commits at lists.llvm.org
Wed May 18 02:21:45 PDT 2016


Author: sdardis
Date: Wed May 18 04:21:44 2016
New Revision: 269893

URL: http://llvm.org/viewvc/llvm-project?rev=269893&view=rev
Log:
[mips] Restrict the creation of compact branches

Restrict the creation of compact branches so that they meet the ISA encoding
requirements. Notably do not permit $zero to be used as a operand for compact
branches and ensure that some other branches fulfil the requirement that
rs != rt.

Fixup cases where $rs > $rt for bnec and beqc.

Reviewers: dsanders, vkalintiris

Differential Review: http://reviews.llvm.org/D20284

Added:
    llvm/trunk/test/CodeGen/Mips/compactbranches/no-beqzc-bnezc.ll
Modified:
    llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
    llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
    llvm/trunk/lib/Target/Mips/Mips32r6InstrFormats.td
    llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp

Modified: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp?rev=269893&r1=269892&r2=269893&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp Wed May 18 04:21:44 2016
@@ -106,6 +106,26 @@ static void LowerDins(MCInst& InstIn) {
   return;
 }
 
+// Fix a bad compact branch encoding for beqc/bnec.
+void MipsMCCodeEmitter::LowerCompactBranch(MCInst& Inst) const {
+
+  // Encoding may be illegal !(rs < rt), but this situation is
+  // easily fixed.
+  unsigned RegOp0 = Inst.getOperand(0).getReg();
+  unsigned RegOp1 = Inst.getOperand(1).getReg();
+
+  unsigned Reg0 =  Ctx.getRegisterInfo()->getEncodingValue(RegOp0);
+  unsigned Reg1 =  Ctx.getRegisterInfo()->getEncodingValue(RegOp1);
+
+  assert(Reg0 != Reg1 && "Instruction has bad operands ($rs == $rt)!");
+  if (Reg0 < Reg1)
+    return;
+
+  Inst.getOperand(0).setReg(RegOp1);
+  Inst.getOperand(1).setReg(RegOp0);
+
+}
+
 bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const {
   return STI.getFeatureBits()[Mips::FeatureMicroMips];
 }
@@ -160,6 +180,11 @@ encodeInstruction(const MCInst &MI, raw_
     // Double extract instruction is chosen by pos and size operands
   case Mips::DINS:
     LowerDins(TmpInst);
+    break;
+  // Compact branches.
+  case Mips::BEQC:
+  case Mips::BNEC:
+    LowerCompactBranch(TmpInst);
   }
 
   unsigned long N = Fixups.size();

Modified: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h?rev=269893&r1=269892&r2=269893&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h (original)
+++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h Wed May 18 04:21:44 2016
@@ -253,6 +253,8 @@ public:
   unsigned getRegisterListOpValue16(const MCInst &MI, unsigned OpNo,
                                     SmallVectorImpl<MCFixup> &Fixups,
                                     const MCSubtargetInfo &STI) const;
+  private:
+  void LowerCompactBranch(MCInst& Inst) const;
 }; // class MipsMCCodeEmitter
 } // namespace llvm.
 

Modified: llvm/trunk/lib/Target/Mips/Mips32r6InstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/Mips32r6InstrFormats.td?rev=269893&r1=269892&r2=269893&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/Mips32r6InstrFormats.td (original)
+++ llvm/trunk/lib/Target/Mips/Mips32r6InstrFormats.td Wed May 18 04:21:44 2016
@@ -360,7 +360,7 @@ class SPECIAL_SDBBP_FM : MipsR6Inst {
 }
 
 // This class is ambiguous with other branches:
-//   BEQC/BNEC require that rs > rt
+//   BEQC/BNEC require that rs < rt
 class CMP_BRANCH_2R_OFF16_FM<OPGROUP funct> : MipsR6Inst {
   bits<5> rs;
   bits<5> rt;

Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp?rev=269893&r1=269892&r2=269893&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp Wed May 18 04:21:44 2016
@@ -282,6 +282,16 @@ unsigned MipsInstrInfo::getEquivalentCom
     }
   }
 
+  // MIPSR6 forbids both operands being the zero register.
+  if (Subtarget.hasMips32r6() &&
+      (I->getOperand(0).getType() == MachineOperand::MO_Register &&
+       (I->getOperand(0).getReg() == Mips::ZERO ||
+        I->getOperand(0).getReg() == Mips::ZERO_64)) &&
+      (I->getOperand(1).getType() == MachineOperand::MO_Register &&
+       (I->getOperand(1).getReg() == Mips::ZERO ||
+        I->getOperand(1).getReg() == Mips::ZERO_64)))
+    return 0;
+
   if (Subtarget.hasMips32r6() || canUseShortMicroMipsCTI) {
     switch (Opcode) {
     case Mips::B:
@@ -299,8 +309,12 @@ unsigned MipsInstrInfo::getEquivalentCom
       else
         return Mips::BNEC;
     case Mips::BGE:
+      if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
+        return 0;
       return Mips::BGEC;
     case Mips::BGEU:
+      if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
+        return 0;
       return Mips::BGEUC;
     case Mips::BGEZ:
       return Mips::BGEZC;
@@ -309,8 +323,12 @@ unsigned MipsInstrInfo::getEquivalentCom
     case Mips::BLEZ:
       return Mips::BLEZC;
     case Mips::BLT:
+      if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
+        return 0;
       return Mips::BLTC;
     case Mips::BLTU:
+      if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
+        return 0;
       return Mips::BLTUC;
     case Mips::BLTZ:
       return Mips::BLTZC;
@@ -330,7 +348,7 @@ unsigned MipsInstrInfo::getEquivalentCom
       return Mips::JIC64;
     case Mips::JALR64Pseudo:
       return Mips::JIALC64;
-     default:
+    default:
       return 0;
     }
   }

Added: llvm/trunk/test/CodeGen/Mips/compactbranches/no-beqzc-bnezc.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/compactbranches/no-beqzc-bnezc.ll?rev=269893&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/compactbranches/no-beqzc-bnezc.ll (added)
+++ llvm/trunk/test/CodeGen/Mips/compactbranches/no-beqzc-bnezc.ll Wed May 18 04:21:44 2016
@@ -0,0 +1,52 @@
+; RUN: llc -march=mipsel -mcpu=mips32r6  -disable-mips-delay-filler < %s | FileCheck %s
+; RUN: llc -march=mips -mcpu=mips32r6 -disable-mips-delay-filler < %s -filetype=obj -o - | llvm-objdump -arch=mips -mcpu=mips32r6 -d - | FileCheck %s -check-prefix=ENCODING
+
+; bnezc and beqzc have restriction that $rt != 0
+
+define i32 @f() {
+; CHECK-LABEL: f
+; CHECK-NOT:   bnezc $0
+
+  %cmp = icmp eq i32 1, 1
+  br i1 %cmp, label %if.then, label %if.end
+
+  if.then:
+    ret i32 1
+
+  if.end:
+    ret i32 0
+}
+
+define i32 @f1() {
+; CHECK-LABEL: f1
+; CHECK-NOT:   beqzc $0
+
+  %cmp = icmp eq i32 0, 0
+  br i1 %cmp, label %if.then, label %if.end
+
+  if.then:
+    ret i32 1
+
+  if.end:
+    ret i32 0
+}
+
+; We silently fixup cases where the register allocator or user has given us
+; an instruction with incorrect operands that is trivially acceptable.
+; beqc and bnec have the restriction that $rs < $rt.
+
+define i32 @f2(i32 %a, i32 %b) {
+; ENCODING-LABEL: f2
+; ENCODING-NOT:   beqc $5, $4
+; ENCODING-NOT:   bnec $5, $4
+
+  %cmp = icmp eq i32 %b, %a
+  br i1 %cmp, label %if.then, label %if.end
+
+  if.then:
+    ret i32 1
+
+  if.end:
+    ret i32 0
+}
+




More information about the llvm-commits mailing list