diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 0d629dbab76..78c0263c14e 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -5450,7 +5450,14 @@ ExpandIntToFP(bool isSigned, MVT::ValueType DestTy, SDOperand Source) { } RTLIB::Libcall LC; - if (SourceVT == MVT::i64) { + if (SourceVT == MVT::i32) { + if (DestTy == MVT::f32) + LC = isSigned ? RTLIB::SINTTOFP_I64_F32 : RTLIB::UINTTOFP_I64_F32; + else { + assert(DestTy == MVT::f64 && "Unknown fp value type!"); + LC = isSigned ? RTLIB::SINTTOFP_I32_F64 : RTLIB::UINTTOFP_I32_F64; + } + } else if (SourceVT == MVT::i64) { if (DestTy == MVT::f32) LC = RTLIB::SINTTOFP_I64_F32; else if (DestTy == MVT::f64) @@ -5481,7 +5488,7 @@ ExpandIntToFP(bool isSigned, MVT::ValueType DestTy, SDOperand Source) { SDOperand HiPart; SDOperand Result = ExpandLibCall(TLI.getLibcallName(LC), Source.Val, isSigned, HiPart); - if (Result.getValueType() != DestTy) + if (Result.getValueType() != DestTy && HiPart.Val) Result = DAG.getNode(ISD::BUILD_PAIR, DestTy, Result, HiPart); return Result; } @@ -6773,7 +6780,8 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ Lo = ExpandIntToFP(Node->getOpcode() == ISD::SINT_TO_FP, VT, Node->getOperand(0)); - ExpandOp(Lo, Lo, Hi); + if (getTypeAction(Lo.getValueType()) == Expand) + ExpandOp(Lo, Lo, Hi); break; } } diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 421a03fca00..7218560cc6c 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -248,16 +248,20 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) setOperationAction(ISD::FCOS , MVT::f64, Expand); setOperationAction(ISD::FREM , MVT::f64, Expand); setOperationAction(ISD::FREM , MVT::f32, Expand); - setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom); - setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom); + if (!UseSoftFloat && Subtarget->hasVFP2() && !Subtarget->isThumb()) { + setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom); + setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom); + } setOperationAction(ISD::FPOW , MVT::f64, Expand); setOperationAction(ISD::FPOW , MVT::f32, Expand); // int <-> fp are custom expanded into bit_convert + ARMISD ops. - setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom); - setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom); - setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom); - setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); + if (!UseSoftFloat && Subtarget->hasVFP2() && !Subtarget->isThumb()) { + setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom); + setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom); + setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom); + setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); + } // We have target-specific dag combine patterns for the following nodes: // ARMISD::FMRRD - No need to call setTargetDAGCombine diff --git a/test/CodeGen/ARM/fpconv.ll b/test/CodeGen/ARM/fpconv.ll index fd1322735b7..a2771fea472 100644 --- a/test/CodeGen/ARM/fpconv.ll +++ b/test/CodeGen/ARM/fpconv.ll @@ -9,6 +9,16 @@ ; RUN: grep fsitod %t ; RUN: grep fuitos %t ; RUN: grep fuitod %t +; RUN: llvm-as < %s | llc -march=arm > %t +; RUN: grep truncdfsf2 %t +; RUN: grep extendsfdf2 %t +; RUN: grep fixsfsi %t +; RUN: grep fixunssfsi %t +; RUN: grep fixdfsi %t +; RUN: grep fixunsdfsi %t +; RUN: grep floatdisf %t +; RUN: grep floatsidf %t +; RUN: llvm-as < %s | llc -march=thumb define float @f1(double %x) { entry: