[llvm] r238756 - [mips][FastISel] Implement the select statement for MIPS FastISel.

Vasileios Kalintiris Vasileios.Kalintiris at imgtec.com
Mon Jun 1 08:56:40 PDT 2015


Author: vkalintiris
Date: Mon Jun  1 10:56:40 2015
New Revision: 238756

URL: http://llvm.org/viewvc/llvm-project?rev=238756&view=rev
Log:
[mips][FastISel] Implement the select statement for MIPS FastISel.

Summary: Implement the LLVM IR select statement for MIPS FastISelsel.

Based on a patch by Reed Kotler.

Test Plan:
"Make check" test included now.
Passes test-suite at O2/O0 mips32 r1/r2.

Reviewers: dsanders, rkotler

Subscribers: llvm-commits, rfuhler

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

Added:
    llvm/trunk/test/CodeGen/Mips/Fast-ISel/sel1.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=238756&r1=238755&r2=238756&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsFastISel.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsFastISel.cpp Mon Jun  1 10:56:40 2015
@@ -94,6 +94,7 @@ private:
   bool selectLoad(const Instruction *I);
   bool selectStore(const Instruction *I);
   bool selectBranch(const Instruction *I);
+  bool selectSelect(const Instruction *I);
   bool selectCmp(const Instruction *I);
   bool selectFPExt(const Instruction *I);
   bool selectFPTrunc(const Instruction *I);
@@ -899,6 +900,50 @@ bool MipsFastISel::selectFPExt(const Ins
   return true;
 }
 
+bool MipsFastISel::selectSelect(const Instruction *I) {
+  assert(isa<SelectInst>(I) && "Expected a select instruction.");
+
+  MVT VT;
+  if (!isTypeSupported(I->getType(), VT))
+    return false;
+
+  unsigned CondMovOpc;
+  const TargetRegisterClass *RC;
+
+  if (VT.isInteger() && !VT.isVector() && VT.getSizeInBits() <= 32) {
+    CondMovOpc = Mips::MOVN_I_I;
+    RC = &Mips::GPR32RegClass;
+  } else if (VT == MVT::f32) {
+    CondMovOpc = Mips::MOVN_I_S;
+    RC = &Mips::FGR32RegClass;
+  } else if (VT == MVT::f64) {
+    CondMovOpc = Mips::MOVN_I_D32;
+    RC = &Mips::AFGR64RegClass;
+  } else
+    return false;
+
+  const SelectInst *SI = cast<SelectInst>(I);
+  const Value *Cond = SI->getCondition();
+  unsigned Src1Reg = getRegForValue(SI->getTrueValue());
+  unsigned Src2Reg = getRegForValue(SI->getFalseValue());
+  unsigned CondReg = getRegForValue(Cond);
+
+  if (!Src1Reg || !Src2Reg || !CondReg)
+    return false;
+
+  unsigned ResultReg = createResultReg(RC);
+  unsigned TempReg = createResultReg(RC);
+
+  if (!ResultReg || !TempReg)
+    return false;
+
+  emitInst(TargetOpcode::COPY, TempReg).addReg(Src2Reg);
+  emitInst(CondMovOpc, ResultReg)
+    .addReg(Src1Reg).addReg(CondReg).addReg(TempReg);
+  updateValueMap(I, ResultReg);
+  return true;
+}
+
 // Attempt to fast-select a floating-point truncate instruction.
 bool MipsFastISel::selectFPTrunc(const Instruction *I) {
   if (UnsupportedFPMode)
@@ -1539,6 +1584,8 @@ bool MipsFastISel::fastSelectInstruction
   case Instruction::ICmp:
   case Instruction::FCmp:
     return selectCmp(I);
+  case Instruction::Select:
+    return selectSelect(I);
   }
   return false;
 }

Added: llvm/trunk/test/CodeGen/Mips/Fast-ISel/sel1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/Fast-ISel/sel1.ll?rev=238756&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/Fast-ISel/sel1.ll (added)
+++ llvm/trunk/test/CodeGen/Mips/Fast-ISel/sel1.ll Mon Jun  1 10:56:40 2015
@@ -0,0 +1,91 @@
+; RUN: llc < %s -march=mipsel -mcpu=mips32r2 -O2 -relocation-model=pic \
+; RUN:          -fast-isel -mips-fast-isel -fast-isel-abort=1 | FileCheck %s
+
+define i1 @sel_i1(i1 %j, i1 %k, i1 %l) {
+entry:
+  ; CHECK-LABEL:  sel_i1:
+
+  ; FIXME: The following instruction is redundant.
+  ; CHECK:            xor     $[[T0:[0-9]+]], $4, $zero
+  ; CHECK-NEXT:       sltu    $[[T1:[0-9]+]], $zero, $[[T0]]
+  ; CHECK-NEXT:       movn    $6, $5, $[[T1]]
+  ; CHECK:            move    $2, $6
+  %cond = icmp ne i1 %j, 0
+  %res = select i1 %cond, i1 %k, i1 %l
+  ret i1 %res
+}
+
+define i8 @sel_i8(i8 %j, i8 %k, i8 %l) {
+entry:
+  ; CHECK-LABEL:  sel_i8:
+
+  ; CHECK-DAG:        seb     $[[T0:[0-9]+]], $4
+  ; FIXME: The following 2 instructions are redundant.
+  ; CHECK-DAG:        seb     $[[T1:[0-9]+]], $zero
+  ; CHECK:            xor     $[[T2:[0-9]+]], $[[T0]], $[[T1]]
+  ; CHECK-NEXT:       sltu    $[[T3:[0-9]+]], $zero, $[[T2]]
+  ; CHECK-NEXT:       movn    $6, $5, $[[T3]]
+  ; CHECK:            move    $2, $6
+  %cond = icmp ne i8 %j, 0
+  %res = select i1 %cond, i8 %k, i8 %l
+  ret i8 %res
+}
+
+define i16 @sel_i16(i16 %j, i16 %k, i16 %l) {
+entry:
+  ; CHECK-LABEL:  sel_i16:
+
+  ; CHECK-DAG:        seh     $[[T0:[0-9]+]], $4
+  ; FIXME: The following 2 instructions are redundant.
+  ; CHECK-DAG:        seh     $[[T1:[0-9]+]], $zero
+  ; CHECK:            xor     $[[T2:[0-9]+]], $[[T0]], $[[T1]]
+  ; CHECK-NEXT:       sltu    $[[T3:[0-9]+]], $zero, $[[T2]]
+  ; CHECK-NEXT:       movn    $6, $5, $[[T3]]
+  ; CHECK:            move    $2, $6
+  %cond = icmp ne i16 %j, 0
+  %res = select i1 %cond, i16 %k, i16 %l
+  ret i16 %res
+}
+
+define i32 @sel_i32(i32 %j, i32 %k, i32 %l) {
+entry:
+  ; CHECK-LABEL:  sel_i32:
+
+  ; FIXME: The following instruction is redundant.
+  ; CHECK:            xor     $[[T0:[0-9]+]], $4, $zero
+  ; CHECK-NEXT:       sltu    $[[T1:[0-9]+]], $zero, $[[T0]]
+  ; CHECK-NEXT:       movn    $6, $5, $[[T1]]
+  ; CHECK:            move    $2, $6
+  %cond = icmp ne i32 %j, 0
+  %res = select i1 %cond, i32 %k, i32 %l
+  ret i32 %res
+}
+
+define float @sel_float(i32 %j, float %k, float %l) {
+entry:
+  ; CHECK-LABEL:  sel_float:
+
+  ; CHECK-DAG:        mtc1    $6, $f0
+  ; CHECK-DAG:        mtc1    $5, $f1
+  ; CHECK-DAG:        xor     $[[T0:[0-9]+]], $4, $zero
+  ; CHECK:            sltu    $[[T1:[0-9]+]], $zero, $[[T0]]
+  ; CHECK:            movn.s  $f0, $f1, $[[T1]]
+  %cond = icmp ne i32 %j, 0
+  %res = select i1 %cond, float %k, float %l
+  ret float %res
+}
+
+define double @sel_double(i32 %j, double %k, double %l) {
+entry:
+  ; CHECK-LABEL:  sel_double:
+
+  ; CHECK-DAG:        mtc1    $6, $f2
+  ; CHECK-DAG:        mthc1   $7, $f2
+  ; CHECK-DAG:        ldc1    $f0, 16($sp)
+  ; CHECK-DAG:        xor     $[[T0:[0-9]+]], $4, $zero
+  ; CHECK:            sltu    $[[T1:[0-9]+]], $zero, $[[T0]]
+  ; CHECK:            movn.d  $f0, $f2, $[[T1]]
+  %cond = icmp ne i32 %j, 0
+  %res = select i1 %cond, double %k, double %l
+  ret double %res
+}





More information about the llvm-commits mailing list