Add fptrunc to mips fast-sel
authorReed Kotler <rkotler@mips.com>
Wed, 1 Oct 2014 18:47:02 +0000 (18:47 +0000)
committerReed Kotler <rkotler@mips.com>
Wed, 1 Oct 2014 18:47:02 +0000 (18:47 +0000)
Summary: Implement conversion of 64 to 32 bit floating point numbers (fptrunc) in mips fast-isel

Test Plan:
fptrunc.ll
checked also with 4 internal mips build bot flavors mip32r1/miprs32r2 and at -O0 and -O2

Reviewers: dsanders

Reviewed By: dsanders

Subscribers: rfuhler

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218785 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/MipsFastISel.cpp
test/CodeGen/Mips/Fast-ISel/fptrunc.ll [new file with mode: 0644]

index bd3d08527b7bdf15991c179d2a6cd08781e451b5..14cf86f0b77d8f4e0fcb84a03a21cdd185b650f7 100644 (file)
@@ -81,6 +81,7 @@ private:
   bool SelectIntExt(const Instruction *I);
   bool SelectTrunc(const Instruction *I);
   bool SelectFPExt(const Instruction *I);
+  bool SelectFPTrunc(const Instruction *I);
 
   bool isTypeLegal(Type *Ty, MVT &VT);
   bool isLoadTypeLegal(Type *Ty, MVT &VT);
@@ -406,6 +407,28 @@ bool MipsFastISel::SelectFPExt(const Instruction *I) {
   return true;
 }
 
+// Attempt to fast-select a floating-point truncate instruction.
+bool MipsFastISel::SelectFPTrunc(const Instruction *I) {
+  Value *Src = I->getOperand(0);
+  EVT SrcVT = TLI.getValueType(Src->getType(), true);
+  EVT DestVT = TLI.getValueType(I->getType(), true);
+
+  if (SrcVT != MVT::f64 || DestVT != MVT::f32)
+    return false;
+
+  unsigned SrcReg = getRegForValue(Src);
+  if (!SrcReg)
+    return false;
+
+  unsigned DestReg = createResultReg(&Mips::FGR32RegClass);
+  if (!DestReg)
+    return false;
+
+  EmitInst(Mips::CVT_S_D32, DestReg).addReg(SrcReg);
+  updateValueMap(I, DestReg);
+  return true;
+}
+
 bool MipsFastISel::SelectIntExt(const Instruction *I) {
   Type *DestTy = I->getType();
   Value *Src = I->getOperand(0);
@@ -475,6 +498,8 @@ bool MipsFastISel::fastSelectInstruction(const Instruction *I) {
   case Instruction::ZExt:
   case Instruction::SExt:
     return SelectIntExt(I);
+  case Instruction::FPTrunc:
+    return SelectFPTrunc(I);
   case Instruction::FPExt:
     return SelectFPExt(I);
   }
diff --git a/test/CodeGen/Mips/Fast-ISel/fptrunc.ll b/test/CodeGen/Mips/Fast-ISel/fptrunc.ll
new file mode 100644 (file)
index 0000000..d843dee
--- /dev/null
@@ -0,0 +1,20 @@
+; 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
+
+@d = global double 0x40147E6B74DF0446, align 8
+@f = common global float 0.000000e+00, align 4
+@.str = private unnamed_addr constant [6 x i8] c"%f  \0A\00", align 1
+
+; Function Attrs: nounwind
+define void @fv() #0 {
+entry:
+  %0 = load double* @d, align 8
+  %conv = fptrunc double %0 to float
+; CHECK: cvt.s.d  $f{{[0-9]+}}, $f{{[0-9]+}}
+  store float %conv, float* @f, align 4
+  ret void
+}
+
+attributes #1 = { nounwind }