diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -8353,27 +8353,37 @@ DebugLoc DL = MI.getDebugLoc(); const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo(); + const MachineRegisterInfo &RegInfo = MF.getRegInfo(); Register LoReg = MI.getOperand(0).getReg(); Register HiReg = MI.getOperand(1).getReg(); Register SrcReg = MI.getOperand(2).getReg(); - const TargetRegisterClass *SrcRC = &RISCV::FPR64RegClass; - int FI = MF.getInfo()->getMoveF64FrameIndex(MF); - TII.storeRegToStackSlot(*BB, MI, SrcReg, MI.getOperand(2).isKill(), FI, SrcRC, - RI); - MachinePointerInfo MPI = MachinePointerInfo::getFixedStack(MF, FI); - MachineMemOperand *MMOLo = - MF.getMachineMemOperand(MPI, MachineMemOperand::MOLoad, 4, Align(8)); - MachineMemOperand *MMOHi = MF.getMachineMemOperand( - MPI.getWithOffset(4), MachineMemOperand::MOLoad, 4, Align(8)); - BuildMI(*BB, MI, DL, TII.get(RISCV::LW), LoReg) - .addFrameIndex(FI) - .addImm(0) - .addMemOperand(MMOLo); - BuildMI(*BB, MI, DL, TII.get(RISCV::LW), HiReg) - .addFrameIndex(FI) - .addImm(4) - .addMemOperand(MMOHi); + // If the source is undef, we split it into two integer undefs. No need to + // remove SrcDef since the ProcessImplicitDefs pass will do it for us. + MachineInstr *SrcDef = RegInfo.getVRegDef(SrcReg); + if (SrcDef->isImplicitDef()) { + BuildMI(*BB, MI, DL, TII.get(TargetOpcode::IMPLICIT_DEF), LoReg); + BuildMI(*BB, MI, DL, TII.get(TargetOpcode::IMPLICIT_DEF), HiReg); + } else { + const TargetRegisterClass *SrcRC = &RISCV::FPR64RegClass; + int FI = MF.getInfo()->getMoveF64FrameIndex(MF); + + TII.storeRegToStackSlot(*BB, MI, SrcReg, MI.getOperand(2).isKill(), FI, + SrcRC, RI); + MachinePointerInfo MPI = MachinePointerInfo::getFixedStack(MF, FI); + MachineMemOperand *MMOLo = + MF.getMachineMemOperand(MPI, MachineMemOperand::MOLoad, 4, Align(8)); + MachineMemOperand *MMOHi = MF.getMachineMemOperand( + MPI.getWithOffset(4), MachineMemOperand::MOLoad, 4, Align(8)); + BuildMI(*BB, MI, DL, TII.get(RISCV::LW), LoReg) + .addFrameIndex(FI) + .addImm(0) + .addMemOperand(MMOLo); + BuildMI(*BB, MI, DL, TII.get(RISCV::LW), HiReg) + .addFrameIndex(FI) + .addImm(4) + .addMemOperand(MMOHi); + } MI.eraseFromParent(); // The pseudo instruction is gone now. return BB; } diff --git a/llvm/test/CodeGen/RISCV/calling-conv-ilp32d.ll b/llvm/test/CodeGen/RISCV/calling-conv-ilp32d.ll --- a/llvm/test/CodeGen/RISCV/calling-conv-ilp32d.ll +++ b/llvm/test/CodeGen/RISCV/calling-conv-ilp32d.ll @@ -265,3 +265,10 @@ %3 = trunc i64 %2 to i32 ret i32 %3 } + +define double @func_return_undef() { +; RV32-ILP32D-LABEL: func_return_undef: +; RV32-ILP32D: # %bb.0: +; RV32-ILP32D-NEXT: ret + ret double undef +}