[fast-isel] Add support for FPToUI. Also add test cases for FPToSI.
authorChad Rosier <mcrosier@apple.com>
Fri, 3 Feb 2012 20:27:51 +0000 (20:27 +0000)
committerChad Rosier <mcrosier@apple.com>
Fri, 3 Feb 2012 20:27:51 +0000 (20:27 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149706 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMFastISel.cpp
test/CodeGen/ARM/fast-isel-conversion.ll

index 48cd5f4b574a3a0dae1464cc32f32500407a01b7..e30cee3dbd4be1b2a7b171920e1b2561737d113f 100644 (file)
@@ -162,7 +162,7 @@ class ARMFastISel : public FastISel {
     bool SelectFPTrunc(const Instruction *I);
     bool SelectBinaryOp(const Instruction *I, unsigned ISDOpcode);
     bool SelectIToFP(const Instruction *I, bool isZExt);
-    bool SelectFPToSI(const Instruction *I);
+    bool SelectFPToI(const Instruction *I, bool isZExt);
     bool SelectSDiv(const Instruction *I);
     bool SelectSRem(const Instruction *I);
     bool SelectCall(const Instruction *I, const char *IntrMemName);
@@ -1578,7 +1578,7 @@ bool ARMFastISel::SelectIToFP(const Instruction *I, bool isZExt) {
   return true;
 }
 
-bool ARMFastISel::SelectFPToSI(const Instruction *I) {
+bool ARMFastISel::SelectFPToI(const Instruction *I, bool isZExt) {
   // Make sure we have VFP.
   if (!Subtarget->hasVFP2()) return false;
 
@@ -1592,11 +1592,11 @@ bool ARMFastISel::SelectFPToSI(const Instruction *I) {
 
   unsigned Opc;
   Type *OpTy = I->getOperand(0)->getType();
-  if (OpTy->isFloatTy()) Opc = ARM::VTOSIZS;
-  else if (OpTy->isDoubleTy()) Opc = ARM::VTOSIZD;
+  if (OpTy->isFloatTy()) Opc = isZExt ? ARM::VTOUIZS : ARM::VTOSIZS;
+  else if (OpTy->isDoubleTy()) Opc = isZExt ? ARM::VTOUIZD : ARM::VTOSIZD;
   else return false;
 
-  // f64->s32 or f32->s32 both need an intermediate f32 reg.
+  // f64->s32/u32 or f32->s32/u32 both need an intermediate f32 reg.
   unsigned ResultReg = createResultReg(TLI.getRegClassFor(MVT::f32));
   AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
                           ResultReg)
@@ -2453,7 +2453,9 @@ bool ARMFastISel::TargetSelectInstruction(const Instruction *I) {
     case Instruction::UIToFP:
       return SelectIToFP(I, /*isZExt*/ true);
     case Instruction::FPToSI:
-      return SelectFPToSI(I);
+      return SelectFPToI(I, /*isZExt*/ false);
+    case Instruction::FPToUI:
+      return SelectFPToI(I, /*isZExt*/ true);
     case Instruction::FAdd:
       return SelectBinaryOp(I, ISD::FADD);
     case Instruction::FSub:
index f33c98d7dfc5362fce00f668fe570924df47ad70..686ccad029d87e5d08fd2c55bfcb1e17e53cd58f 100644 (file)
@@ -188,3 +188,55 @@ entry:
   store double %conv, double* %b.addr, align 8
   ret void
 }
+
+; Test fptosi
+
+define void @fptosi_float(float %a) nounwind ssp {
+entry:
+; ARM: fptosi_float
+; ARM: vcvt.s32.f32 s0, s0
+; THUMB: fptosi_float
+; THUMB: vcvt.s32.f32 s0, s0
+  %b.addr = alloca i32, align 4
+  %conv = fptosi float %a to i32
+  store i32 %conv, i32* %b.addr, align 4
+  ret void
+}
+
+define void @fptosi_double(double %a) nounwind ssp {
+entry:
+; ARM: fptosi_double
+; ARM: vcvt.s32.f64 s0, d16
+; THUMB: fptosi_double
+; THUMB: vcvt.s32.f64 s0, d16
+  %b.addr = alloca i32, align 8
+  %conv = fptosi double %a to i32
+  store i32 %conv, i32* %b.addr, align 8
+  ret void
+}
+
+; Test fptoui
+
+define void @fptoui_float(float %a) nounwind ssp {
+entry:
+; ARM: fptoui_float
+; ARM: vcvt.u32.f32 s0, s0
+; THUMB: fptoui_float
+; THUMB: vcvt.u32.f32 s0, s0
+  %b.addr = alloca i32, align 4
+  %conv = fptoui float %a to i32
+  store i32 %conv, i32* %b.addr, align 4
+  ret void
+}
+
+define void @fptoui_double(double %a) nounwind ssp {
+entry:
+; ARM: fptoui_double
+; ARM: vcvt.u32.f64 s0, d16
+; THUMB: fptoui_double
+; THUMB: vcvt.u32.f64 s0, d16
+  %b.addr = alloca i32, align 8
+  %conv = fptoui double %a to i32
+  store i32 %conv, i32* %b.addr, align 8
+  ret void
+}