[FastISel][AArch64] Add basic bitcast support for conversion between float and int.
authorJuergen Ributzka <juergen@apple.com>
Thu, 31 Jul 2014 06:25:37 +0000 (06:25 +0000)
committerJuergen Ributzka <juergen@apple.com>
Thu, 31 Jul 2014 06:25:37 +0000 (06:25 +0000)
Fixes <rdar://problem/17867078>.

llvm-svn: 214389

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

index 647bb57..8d7bddb 100644 (file)
@@ -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.
index c5417de..ab46bb6 100644 (file)
@@ -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
+}
+