[llvm] r219556 - Add basic conditional branches in mips fast-isel

Reed Kotler rkotler at mips.com
Fri Oct 10 17:55:18 PDT 2014


Author: rkotler
Date: Fri Oct 10 19:55:18 2014
New Revision: 219556

URL: http://llvm.org/viewvc/llvm-project?rev=219556&view=rev
Log:
Add basic conditional branches in mips fast-isel

Summary: Implement the most basic form of conditional branches in Mips fast-isel.

Test Plan:
br1.ll
run 4 flavors of test-suite. mips32 r1/r2 and at -O0/O2

Reviewers: dsanders

Reviewed By: dsanders

Subscribers: llvm-commits, rfuhler

Differential Revision: http://reviews.llvm.org/D5583

Added:
    llvm/trunk/test/CodeGen/Mips/Fast-ISel/br1.ll
Modified:
    llvm/trunk/lib/Target/Mips/MipsFastISel.cpp

Modified: llvm/trunk/lib/Target/Mips/MipsFastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsFastISel.cpp?rev=219556&r1=219555&r2=219556&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsFastISel.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsFastISel.cpp Fri Oct 10 19:55:18 2014
@@ -77,7 +77,9 @@ private:
                 unsigned Alignment = 0);
   bool EmitStore(MVT VT, unsigned SrcReg, Address &Addr,
                  unsigned Alignment = 0);
+  bool EmitCmp(unsigned DestReg, const CmpInst *CI);
   bool SelectLoad(const Instruction *I);
+  bool SelectBranch(const Instruction *I);
   bool SelectRet(const Instruction *I);
   bool SelectStore(const Instruction *I);
   bool SelectIntExt(const Instruction *I);
@@ -353,6 +355,38 @@ bool MipsFastISel::EmitIntZExt(MVT SrcVT
   return true;
 }
 
+//
+// This can cause a redundant sltiu to be generated.
+// FIXME: try and eliminate this in a future patch.
+//
+bool MipsFastISel::SelectBranch(const Instruction *I) {
+  const BranchInst *BI = cast<BranchInst>(I);
+  MachineBasicBlock *BrBB = FuncInfo.MBB;
+  //
+  // TBB is the basic block for the case where the comparison is true.
+  // FBB is the basic block for the case where the comparison is false.
+  // if (cond) goto TBB
+  // goto FBB
+  // TBB:
+  //
+  MachineBasicBlock *TBB = FuncInfo.MBBMap[BI->getSuccessor(0)];
+  MachineBasicBlock *FBB = FuncInfo.MBBMap[BI->getSuccessor(1)];
+  BI->getCondition();
+  // For now, just try the simplest case where it's fed by a compare.
+  if (const CmpInst *CI = dyn_cast<CmpInst>(BI->getCondition())) {
+    unsigned CondReg = createResultReg(&Mips::GPR32RegClass);
+    if (!EmitCmp(CondReg, CI))
+      return false;
+    BuildMI(*BrBB, FuncInfo.InsertPt, DbgLoc, TII.get(Mips::BGTZ))
+        .addReg(CondReg)
+        .addMBB(TBB);
+    fastEmitBranch(FBB, DbgLoc);
+    FuncInfo.MBB->addSuccessor(TBB);
+    return true;
+  }
+  return false;
+}
+
 bool MipsFastISel::SelectLoad(const Instruction *I) {
   // Atomic loads need special handling.
   if (cast<LoadInst>(I)->isAtomic())
@@ -560,25 +594,22 @@ bool MipsFastISel::SelectFPToI(const Ins
   updateValueMap(I, DestReg);
   return true;
 }
-
 //
-// Because of how SelectCmp is called with fast-isel, you can
+// Because of how EmitCmp is called with fast-isel, you can
 // end up with redundant "andi" instructions after the sequences emitted below.
 // We should try and solve this issue in the future.
 //
-bool MipsFastISel::SelectCmp(const Instruction *I) {
-  const CmpInst *CI = cast<CmpInst>(I);
+bool MipsFastISel::EmitCmp(unsigned ResultReg, const CmpInst *CI) {
+  const Value *Left = CI->getOperand(0), *Right = CI->getOperand(1);
   bool IsUnsigned = CI->isUnsigned();
-  const Value *Left = I->getOperand(0), *Right = I->getOperand(1);
-
   unsigned LeftReg = getRegEnsuringSimpleIntegerWidening(Left, IsUnsigned);
   if (LeftReg == 0)
     return false;
   unsigned RightReg = getRegEnsuringSimpleIntegerWidening(Right, IsUnsigned);
   if (RightReg == 0)
     return false;
-  unsigned ResultReg = createResultReg(&Mips::GPR32RegClass);
   CmpInst::Predicate P = CI->getPredicate();
+
   switch (P) {
   default:
     return false;
@@ -689,6 +720,14 @@ bool MipsFastISel::SelectCmp(const Instr
     break;
   }
   }
+  return true;
+}
+
+bool MipsFastISel::SelectCmp(const Instruction *I) {
+  const CmpInst *CI = cast<CmpInst>(I);
+  unsigned ResultReg = createResultReg(&Mips::GPR32RegClass);
+  if (!EmitCmp(ResultReg, CI))
+    return false;
   updateValueMap(I, ResultReg);
   return true;
 }
@@ -703,6 +742,8 @@ bool MipsFastISel::fastSelectInstruction
     return SelectLoad(I);
   case Instruction::Store:
     return SelectStore(I);
+  case Instruction::Br:
+    return SelectBranch(I);
   case Instruction::Ret:
     return SelectRet(I);
   case Instruction::Trunc:

Added: llvm/trunk/test/CodeGen/Mips/Fast-ISel/br1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/Fast-ISel/br1.ll?rev=219556&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/Fast-ISel/br1.ll (added)
+++ llvm/trunk/test/CodeGen/Mips/Fast-ISel/br1.ll Fri Oct 10 19:55:18 2014
@@ -0,0 +1,34 @@
+; RUN: llc -march=mipsel -relocation-model=pic -O0 -mips-fast-isel -fast-isel-abort -mcpu=mips32r2 \
+; RUN:     < %s | FileCheck %s
+; RUN: llc -march=mipsel -relocation-model=pic -O0 -mips-fast-isel -fast-isel-abort -mcpu=mips32 \
+; RUN:     < %s | FileCheck %s
+
+ at b = global i32 1, align 4
+ at i = global i32 0, align 4
+ at .str = private unnamed_addr constant [5 x i8] c"%i \0A\00", align 1
+
+; Function Attrs: nounwind
+define void @br() #0 {
+entry:
+  %0 = load i32* @b, align 4
+  %tobool = icmp eq i32 %0, 0
+  br i1 %tobool, label %if.end, label %if.then
+
+if.then:                                          ; preds = %entry
+  store i32 6754, i32* @i, align 4
+  br label %if.end
+
+if.end:                                           ; preds = %entry, %if.then
+  ret void
+; FIXME: This instruction is redundant.
+; CHECK:  xor  $[[REG1:[0-9]+]], ${{[0-9]+}}, $zero
+; CHECK:  sltiu  $[[REG2:[0-9]+]], $[[REG1]], 1
+; CHECK:  bgtz  $[[REG2]], $BB[[BL:[0-9]+_[0-9]+]]
+; CHECK:  nop
+; CHECK:  addiu  ${{[0-9]+}}, $zero, 6754
+; CHECK:  sw  ${{[0-9]+}}, 0(${{[0-9]+}})
+; CHECK: $BB[[BL]]:
+
+}
+
+attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }





More information about the llvm-commits mailing list