[llvm] r214389 - [FastISel][AArch64] Add basic bitcast support for conversion between float and int.

Juergen Ributzka juergen at apple.com
Wed Jul 30 23:25:37 PDT 2014


Author: ributzka
Date: Thu Jul 31 01:25:37 2014
New Revision: 214389

URL: http://llvm.org/viewvc/llvm-project?rev=214389&view=rev
Log:
[FastISel][AArch64] Add basic bitcast support for conversion between float and int.

Fixes <rdar://problem/17867078>.

Modified:
    llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp
    llvm/trunk/test/CodeGen/AArch64/arm64-fast-isel-conversion.ll

Modified: llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp?rev=214389&r1=214388&r2=214389&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp Thu Jul 31 01:25:37 2014
@@ -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
   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::TargetSelectInstru
     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.

Modified: llvm/trunk/test/CodeGen/AArch64/arm64-fast-isel-conversion.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64-fast-isel-conversion.ll?rev=214389&r1=214388&r2=214389&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/arm64-fast-isel-conversion.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/arm64-fast-isel-conversion.ll Thu Jul 31 01:25:37 2014
@@ -440,3 +440,24 @@ define zeroext i64 @zext_i16_i64(i16 zer
   %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
+}
+





More information about the llvm-commits mailing list