From 36b7beb42921c428fc9f5b5a9cc9feb7fe7dd4b3 Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Fri, 3 Feb 2012 19:42:52 +0000 Subject: [PATCH] [fast-isel] Add support for selecting UIToFP. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149704 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMFastISel.cpp | 14 ++-- test/CodeGen/ARM/fast-isel-conversion.ll | 94 ++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 6 deletions(-) diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp index e8ba801d846..48cd5f4b574 100644 --- a/lib/Target/ARM/ARMFastISel.cpp +++ b/lib/Target/ARM/ARMFastISel.cpp @@ -161,7 +161,7 @@ class ARMFastISel : public FastISel { bool SelectFPExt(const Instruction *I); bool SelectFPTrunc(const Instruction *I); bool SelectBinaryOp(const Instruction *I, unsigned ISDOpcode); - bool SelectSIToFP(const Instruction *I); + bool SelectIToFP(const Instruction *I, bool isZExt); bool SelectFPToSI(const Instruction *I); bool SelectSDiv(const Instruction *I); bool SelectSRem(const Instruction *I); @@ -1535,7 +1535,7 @@ bool ARMFastISel::SelectFPTrunc(const Instruction *I) { return true; } -bool ARMFastISel::SelectSIToFP(const Instruction *I) { +bool ARMFastISel::SelectIToFP(const Instruction *I, bool isZExt) { // Make sure we have VFP. if (!Subtarget->hasVFP2()) return false; @@ -1555,7 +1555,7 @@ bool ARMFastISel::SelectSIToFP(const Instruction *I) { // Handle sign-extension. if (SrcVT == MVT::i16 || SrcVT == MVT::i8) { EVT DestVT = MVT::i32; - unsigned ResultReg = ARMEmitIntExt(SrcVT, SrcReg, DestVT, /*isZExt*/ false); + unsigned ResultReg = ARMEmitIntExt(SrcVT, SrcReg, DestVT, isZExt); if (ResultReg == 0) return false; SrcReg = ResultReg; } @@ -1566,8 +1566,8 @@ bool ARMFastISel::SelectSIToFP(const Instruction *I) { if (FP == 0) return false; unsigned Opc; - if (Ty->isFloatTy()) Opc = ARM::VSITOS; - else if (Ty->isDoubleTy()) Opc = ARM::VSITOD; + if (Ty->isFloatTy()) Opc = isZExt ? ARM::VUITOS : ARM::VSITOS; + else if (Ty->isDoubleTy()) Opc = isZExt ? ARM::VUITOD : ARM::VSITOD; else return false; unsigned ResultReg = createResultReg(TLI.getRegClassFor(DstVT)); @@ -2449,7 +2449,9 @@ bool ARMFastISel::TargetSelectInstruction(const Instruction *I) { case Instruction::FPTrunc: return SelectFPTrunc(I); case Instruction::SIToFP: - return SelectSIToFP(I); + return SelectIToFP(I, /*isZExt*/ false); + case Instruction::UIToFP: + return SelectIToFP(I, /*isZExt*/ true); case Instruction::FPToSI: return SelectFPToSI(I); case Instruction::FAdd: diff --git a/test/CodeGen/ARM/fast-isel-conversion.ll b/test/CodeGen/ARM/fast-isel-conversion.ll index f00762585d0..f33c98d7dfc 100644 --- a/test/CodeGen/ARM/fast-isel-conversion.ll +++ b/test/CodeGen/ARM/fast-isel-conversion.ll @@ -94,3 +94,97 @@ entry: store double %conv, double* %b.addr, align 8 ret void } + +; Test uitofp + +define void @uitofp_single_i32(i32 %a, float %b) nounwind ssp { +entry: +; ARM: uitofp_single_i32 +; ARM: vmov s0, r0 +; ARM: vcvt.f32.u32 s0, s0 +; THUMB: uitofp_single_i32 +; THUMB: vmov s0, r0 +; THUMB: vcvt.f32.u32 s0, s0 + %b.addr = alloca float, align 4 + %conv = uitofp i32 %a to float + store float %conv, float* %b.addr, align 4 + ret void +} + +define void @uitofp_single_i16(i16 %a, float %b) nounwind ssp { +entry: +; ARM: uitofp_single_i16 +; ARM: uxth r0, r0 +; ARM: vmov s0, r0 +; ARM: vcvt.f32.u32 s0, s0 +; THUMB: uitofp_single_i16 +; THUMB: uxth r0, r0 +; THUMB: vmov s0, r0 +; THUMB: vcvt.f32.u32 s0, s0 + %b.addr = alloca float, align 4 + %conv = uitofp i16 %a to float + store float %conv, float* %b.addr, align 4 + ret void +} + +define void @uitofp_single_i8(i8 %a) nounwind ssp { +entry: +; ARM: uitofp_single_i8 +; ARM: uxtb r0, r0 +; ARM: vmov s0, r0 +; ARM: vcvt.f32.u32 s0, s0 +; THUMB: uitofp_single_i8 +; THUMB: uxtb r0, r0 +; THUMB: vmov s0, r0 +; THUMB: vcvt.f32.u32 s0, s0 + %b.addr = alloca float, align 4 + %conv = uitofp i8 %a to float + store float %conv, float* %b.addr, align 4 + ret void +} + +define void @uitofp_double_i32(i32 %a, double %b) nounwind ssp { +entry: +; ARM: uitofp_double_i32 +; ARM: vmov s0, r0 +; ARM: vcvt.f64.u32 d16, s0 +; THUMB: uitofp_double_i32 +; THUMB: vmov s0, r0 +; THUMB: vcvt.f64.u32 d16, s0 + %b.addr = alloca double, align 8 + %conv = uitofp i32 %a to double + store double %conv, double* %b.addr, align 8 + ret void +} + +define void @uitofp_double_i16(i16 %a, double %b) nounwind ssp { +entry: +; ARM: uitofp_double_i16 +; ARM: uxth r0, r0 +; ARM: vmov s0, r0 +; ARM: vcvt.f64.u32 d16, s0 +; THUMB: uitofp_double_i16 +; THUMB: uxth r0, r0 +; THUMB: vmov s0, r0 +; THUMB: vcvt.f64.u32 d16, s0 + %b.addr = alloca double, align 8 + %conv = uitofp i16 %a to double + store double %conv, double* %b.addr, align 8 + ret void +} + +define void @uitofp_double_i8(i8 %a, double %b) nounwind ssp { +entry: +; ARM: uitofp_double_i8 +; ARM: uxtb r0, r0 +; ARM: vmov s0, r0 +; ARM: vcvt.f64.u32 d16, s0 +; THUMB: uitofp_double_i8 +; THUMB: uxtb r0, r0 +; THUMB: vmov s0, r0 +; THUMB: vcvt.f64.u32 d16, s0 + %b.addr = alloca double, align 8 + %conv = uitofp i8 %a to double + store double %conv, double* %b.addr, align 8 + ret void +} -- 2.34.1