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

Fixes <rdar://problem/17867078>.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@214389 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Juergen Ributzka 2014-07-31 06:25:37 +00:00
parent a60ed423a6
commit 95ec2761f3
2 changed files with 58 additions and 0 deletions

View 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.

View 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
}