Index: llvm/trunk/lib/Target/Mips/MipsSEFrameLowering.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/MipsSEFrameLowering.cpp +++ llvm/trunk/lib/Target/Mips/MipsSEFrameLowering.cpp @@ -319,6 +319,15 @@ bool ExpandPseudo::expandExtractElementF64(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, bool FP64) const { + const MachineOperand &Op1 = I->getOperand(1); + const MachineOperand &Op2 = I->getOperand(2); + + if ((Op1.isReg() && Op1.isUndef()) || (Op2.isReg() && Op2.isUndef())) { + unsigned DstReg = I->getOperand(0).getReg(); + BuildMI(MBB, I, I->getDebugLoc(), TII.get(Mips::IMPLICIT_DEF), DstReg); + return true; + } + // For fpxx and when mfhc1 is not available, use: // spill + reload via ldc1 // @@ -335,8 +344,8 @@ if ((Subtarget.isABI_FPXX() && !Subtarget.hasMTHC1()) || (FP64 && !Subtarget.useOddSPReg())) { unsigned DstReg = I->getOperand(0).getReg(); - unsigned SrcReg = I->getOperand(1).getReg(); - unsigned N = I->getOperand(2).getImm(); + unsigned SrcReg = Op1.getReg(); + unsigned N = Op2.getImm(); int64_t Offset = 4 * (Subtarget.isLittle() ? N : (1 - N)); // It should be impossible to have FGR64 on MIPS-II or MIPS32r1 (which are @@ -352,8 +361,7 @@ // We re-use the same spill slot each time so that the stack frame doesn't // grow too much in functions with a large number of moves. int FI = MF.getInfo()->getMoveF64ViaSpillFI(RC); - TII.storeRegToStack(MBB, I, SrcReg, I->getOperand(1).isKill(), FI, RC, - &RegInfo, 0); + TII.storeRegToStack(MBB, I, SrcReg, Op1.isKill(), FI, RC, &RegInfo, 0); TII.loadRegFromStack(MBB, I, DstReg, FI, RC2, &RegInfo, Offset); return true; } Index: llvm/trunk/test/CodeGen/Mips/llvm-ir/call.ll =================================================================== --- llvm/trunk/test/CodeGen/Mips/llvm-ir/call.ll +++ llvm/trunk/test/CodeGen/Mips/llvm-ir/call.ll @@ -6,6 +6,7 @@ ; RUN: llc -march=mips -mcpu=mips32r3 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 ; RUN: llc -march=mips -mcpu=mips32r5 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 ; RUN: llc -march=mips -mcpu=mips32r6 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 +; RUN: llc -march=mips -mcpu=mips32r6 -mattr=+fp64,+nooddspreg -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 ; RUN: llc -march=mips64 -mcpu=mips4 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 ; RUN: llc -march=mips64 -mcpu=mips64 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 ; RUN: llc -march=mips64 -mcpu=mips64r2 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 @@ -168,3 +169,16 @@ %1 = tail call float %addr() ret float %1 } + +; Check that passing undef as a double value doesn't cause machine code errors +; for FP64. +declare hidden void @undef_double(i32 %this, double %volume) unnamed_addr align 2 + +define hidden void @thunk_undef_double(i32 %this, double %volume) unnamed_addr align 2 { +; ALL-LABEL: thunk_undef_double: +; O32: # implicit-def: A2 +; O32: # implicit-def: A3 +; ALL: jr $25 + tail call void @undef_double(i32 undef, double undef) #8 + ret void +}