Index: lib/Target/Mips/MipsISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsISelLowering.cpp +++ lib/Target/Mips/MipsISelLowering.cpp @@ -1203,8 +1203,9 @@ SelectionDAG &DAG) const { SDValue Res = LowerOperation(SDValue(N, 0), DAG); - for (unsigned I = 0, E = Res->getNumValues(); I != E; ++I) - Results.push_back(Res.getValue(I)); + if (Res) + for (unsigned I = 0, E = Res->getNumValues(); I != E; ++I) + Results.push_back(Res.getValue(I)); } void Index: lib/Target/Mips/MipsSEISelLowering.h =================================================================== --- lib/Target/Mips/MipsSEISelLowering.h +++ lib/Target/Mips/MipsSEISelLowering.h @@ -72,6 +72,7 @@ SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const; SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const; + SDValue lowerBITCAST(SDValue Op, SelectionDAG &DAG) const; SDValue lowerMulDiv(SDValue Op, unsigned NewOpc, bool HasLo, bool HasHi, SelectionDAG &DAG) const; Index: lib/Target/Mips/MipsSEISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsSEISelLowering.cpp +++ lib/Target/Mips/MipsSEISelLowering.cpp @@ -213,6 +213,11 @@ setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom); setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom); + if (Subtarget.hasMips32r2() && !Subtarget.useSoftFloat() && + !Subtarget.hasMips64()) { + setOperationAction(ISD::BITCAST, MVT::i64, Custom); + } + if (NoDPLoadStore) { setOperationAction(ISD::LOAD, MVT::f64, Custom); setOperationAction(ISD::STORE, MVT::f64, Custom); @@ -462,6 +467,7 @@ case ISD::BUILD_VECTOR: return lowerBUILD_VECTOR(Op, DAG); case ISD::VECTOR_SHUFFLE: return lowerVECTOR_SHUFFLE(Op, DAG); case ISD::SELECT: return lowerSELECT(Op, DAG); + case ISD::BITCAST: return lowerBITCAST(Op, DAG); } return MipsTargetLowering::LowerOperation(Op, DAG); @@ -1220,6 +1226,36 @@ Nd.getMemOperand()->getFlags(), Nd.getAAInfo()); } +SDValue MipsSETargetLowering::lowerBITCAST(SDValue Op, + SelectionDAG &DAG) const { + SDLoc DL(Op); + MVT Src = Op.getOperand(0).getValueType().getSimpleVT(); + MVT Dest = Op.getValueType().getSimpleVT(); + + // Bitcast i64 to double. + if (Src == MVT::i64 && Dest == MVT::f64) { + SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, + Op.getOperand(0), DAG.getIntPtrConstant(0, DL)); + SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, + Op.getOperand(0), DAG.getIntPtrConstant(1, DL)); + return DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, Lo, Hi); + } + + // Bitcast double to i64. + if (Src == MVT::f64 && Dest == MVT::i64) { + SDValue Lo = + DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, Op.getOperand(0), + DAG.getConstant(0, DL, MVT::i32)); + SDValue Hi = + DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, Op.getOperand(0), + DAG.getConstant(1, DL, MVT::i32)); + return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi); + } + + // Skip other cases of bitcast and use default lowering. + return SDValue(); +} + SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc, bool HasLo, bool HasHi, SelectionDAG &DAG) const { Index: test/CodeGen/Mips/llvm-ir/bitcast.ll =================================================================== --- test/CodeGen/Mips/llvm-ir/bitcast.ll +++ test/CodeGen/Mips/llvm-ir/bitcast.ll @@ -1,13 +1,13 @@ ; RUN: llc -march=mips -mcpu=mips32r2 -asm-show-inst \ -; RUN: -mno-ldc1-sdc1 < %s | FileCheck %s --check-prefix=MIPS32R2 +; RUN: < %s | FileCheck %s --check-prefix=MIPS32R2 ; RUN: llc -march=mips -mcpu=mips32r2 -mattr=+fp64 -asm-show-inst \ -; RUN: -mno-ldc1-sdc1 < %s | FileCheck %s --check-prefix=MIPS32FP64 +; RUN: < %s | FileCheck %s --check-prefix=MIPS32FP64 ; RUN: llc -march=mips -mcpu=mips32r3 -mattr=+micromips -asm-show-inst \ -; RUN: -mno-ldc1-sdc1 < %s | FileCheck %s --check-prefix=MM +; RUN: < %s | FileCheck %s --check-prefix=MM ; RUN: llc -march=mips -mcpu=mips32r3 -mattr=+micromips,+fp64 -asm-show-inst \ -; RUN: -mno-ldc1-sdc1 < %s | FileCheck %s --check-prefix=MMFP64 +; RUN: < %s | FileCheck %s --check-prefix=MMFP64 ; RUN: llc -march=mips -mcpu=mips32r6 -mattr=+micromips -asm-show-inst \ -; RUN: -mno-ldc1-sdc1 < %s | FileCheck %s --check-prefix=MMR6 +; RUN: < %s | FileCheck %s --check-prefix=MMR6 define double @mthc1(i64 %a) { ; MIPS32R2: mthc1 {{.*}} #