From c537bd2da4c07c56dfa49a8bc593e4e61a84c5d2 Mon Sep 17 00:00:00 2001 From: Juergen Ributzka Date: Thu, 31 Jul 2014 06:25:37 +0000 Subject: [PATCH] [FastISel][AArch64] Add basic bitcast support for conversion between float and int. Fixes . llvm-svn: 214389 --- llvm/lib/Target/AArch64/AArch64FastISel.cpp | 37 ++++++++++++++++++++++ .../CodeGen/AArch64/arm64-fast-isel-conversion.ll | 21 ++++++++++++ 2 files changed, 58 insertions(+) diff --git a/llvm/lib/Target/AArch64/AArch64FastISel.cpp b/llvm/lib/Target/AArch64/AArch64FastISel.cpp index 647bb57..8d7bddb 100644 --- a/llvm/lib/Target/AArch64/AArch64FastISel.cpp +++ b/llvm/lib/Target/AArch64/AArch64FastISel.cpp @@ -114,6 +114,7 @@ private: bool SelectIntExt(const Instruction *I); bool SelectMul(const Instruction *I); bool SelectShift(const Instruction *I, bool IsLeftShift, bool IsArithmetic); + bool SelectBitCast(const Instruction *I); // Utility helper routines. bool isTypeLegal(Type *Ty, MVT &VT); @@ -2411,6 +2412,40 @@ bool AArch64FastISel::SelectShift(const Instruction *I, bool IsLeftShift, return true; } +bool AArch64FastISel::SelectBitCast(const Instruction *I) { + MVT RetVT, SrcVT; + + if (!isTypeLegal(I->getOperand(0)->getType(), SrcVT)) + return false; + if (!isTypeLegal(I->getType(), RetVT)) + return false; + + unsigned Opc; + if (RetVT == MVT::f32 && SrcVT == MVT::i32) + Opc = AArch64::FMOVWSr; + else if (RetVT == MVT::f64 && SrcVT == MVT::i64) + Opc = AArch64::FMOVXDr; + else if (RetVT == MVT::i32 && SrcVT == MVT::f32) + Opc = AArch64::FMOVSWr; + else if (RetVT == MVT::i64 && SrcVT == MVT::f64) + Opc = AArch64::FMOVDXr; + else + return false; + + unsigned Op0Reg = getRegForValue(I->getOperand(0)); + if (!Op0Reg) + return false; + bool Op0IsKill = hasTrivialKill(I->getOperand(0)); + unsigned ResultReg = FastEmitInst_r(Opc, TLI.getRegClassFor(RetVT), + Op0Reg, Op0IsKill); + + if (!ResultReg) + return false; + + UpdateValueMap(I, ResultReg); + return true; +} + bool AArch64FastISel::TargetSelectInstruction(const Instruction *I) { switch (I->getOpcode()) { default: @@ -2462,6 +2497,8 @@ bool AArch64FastISel::TargetSelectInstruction(const Instruction *I) { return SelectShift(I, /*IsLeftShift=*/false, /*IsArithmetic=*/false); case Instruction::AShr: return SelectShift(I, /*IsLeftShift=*/false, /*IsArithmetic=*/true); + case Instruction::BitCast: + return SelectBitCast(I); } return false; // Silence warnings. diff --git a/llvm/test/CodeGen/AArch64/arm64-fast-isel-conversion.ll b/llvm/test/CodeGen/AArch64/arm64-fast-isel-conversion.ll index c5417de..ab46bb6 100644 --- a/llvm/test/CodeGen/AArch64/arm64-fast-isel-conversion.ll +++ b/llvm/test/CodeGen/AArch64/arm64-fast-isel-conversion.ll @@ -440,3 +440,24 @@ define zeroext i64 @zext_i16_i64(i16 zeroext %in) { %big = zext i16 %in to i64 ret i64 %big } + +define float @bitcast_i32_to_float(i32 %a) { + %1 = bitcast i32 %a to float + ret float %1 +} + +define double @bitcast_i64_to_double(i64 %a) { + %1 = bitcast i64 %a to double + ret double %1 +} + +define i32 @bitcast_float_to_i32(float %a) { + %1 = bitcast float %a to i32 + ret i32 %1 +} + +define i64 @bitcast_double_to_i64(double %a) { + %1 = bitcast double %a to i64 + ret i64 %1 +} + -- 2.7.4