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 @@ -7509,6 +7509,12 @@ if (Op0->getOpcode() == RISCVISD::BuildPairF64) return DCI.CombineTo(N, Op0.getOperand(0), Op0.getOperand(1)); + if (Op0->isUndef()) { + SDValue Lo = DAG.getUNDEF(MVT::i32); + SDValue Hi = DAG.getUNDEF(MVT::i32); + return DCI.CombineTo(N, Lo, Hi); + } + SDLoc DL(N); // It's cheaper to materialise two 32-bit integers than to load a double diff --git a/llvm/test/CodeGen/RISCV/calling-conv-ilp32.ll b/llvm/test/CodeGen/RISCV/calling-conv-ilp32.ll --- a/llvm/test/CodeGen/RISCV/calling-conv-ilp32.ll +++ b/llvm/test/CodeGen/RISCV/calling-conv-ilp32.ll @@ -3,6 +3,8 @@ ; RUN: | FileCheck -check-prefix=RV32I-FPELIM %s ; RUN: llc -mtriple=riscv32 -verify-machineinstrs -frame-pointer=all < %s \ ; RUN: | FileCheck -check-prefix=RV32I-WITHFP %s +; RUN: llc -mtriple=riscv32 -verify-machineinstrs -mattr=+d < %s \ +; RUN: | FileCheck -check-prefix=RV32ID-FPELIM %s ; As well as calling convention details, we check that ra and fp are ; consistently stored to fp-4 and fp-8. @@ -43,6 +45,13 @@ ; RV32I-WITHFP-NEXT: lw s1, 4(sp) # 4-byte Folded Reload ; RV32I-WITHFP-NEXT: addi sp, sp, 16 ; RV32I-WITHFP-NEXT: ret +; +; RV32ID-FPELIM-LABEL: callee_float_in_regs: +; RV32ID-FPELIM: # %bb.0: +; RV32ID-FPELIM-NEXT: fmv.w.x ft0, a1 +; RV32ID-FPELIM-NEXT: fcvt.w.s a1, ft0, rtz +; RV32ID-FPELIM-NEXT: add a0, a0, a1 +; RV32ID-FPELIM-NEXT: ret %b_fptosi = fptosi float %b to i32 %1 = add i32 %a, %b_fptosi ret i32 %1 @@ -73,6 +82,17 @@ ; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload ; RV32I-WITHFP-NEXT: addi sp, sp, 16 ; RV32I-WITHFP-NEXT: ret +; +; RV32ID-FPELIM-LABEL: caller_float_in_regs: +; RV32ID-FPELIM: # %bb.0: +; RV32ID-FPELIM-NEXT: addi sp, sp, -16 +; RV32ID-FPELIM-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32ID-FPELIM-NEXT: li a0, 1 +; RV32ID-FPELIM-NEXT: lui a1, 262144 +; RV32ID-FPELIM-NEXT: call callee_float_in_regs@plt +; RV32ID-FPELIM-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32ID-FPELIM-NEXT: addi sp, sp, 16 +; RV32ID-FPELIM-NEXT: ret %1 = call i32 @callee_float_in_regs(i32 1, float 2.0) ret i32 %1 } @@ -96,6 +116,12 @@ ; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload ; RV32I-WITHFP-NEXT: addi sp, sp, 16 ; RV32I-WITHFP-NEXT: ret +; +; RV32ID-FPELIM-LABEL: callee_float_on_stack: +; RV32ID-FPELIM: # %bb.0: +; RV32ID-FPELIM-NEXT: lw a0, 0(sp) +; RV32ID-FPELIM-NEXT: add a0, a6, a0 +; RV32ID-FPELIM-NEXT: ret %1 = trunc i64 %d to i32 %2 = bitcast float %e to i32 %3 = add i32 %1, %2 @@ -143,6 +169,25 @@ ; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload ; RV32I-WITHFP-NEXT: addi sp, sp, 16 ; RV32I-WITHFP-NEXT: ret +; +; RV32ID-FPELIM-LABEL: caller_float_on_stack: +; RV32ID-FPELIM: # %bb.0: +; RV32ID-FPELIM-NEXT: addi sp, sp, -16 +; RV32ID-FPELIM-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32ID-FPELIM-NEXT: lui a1, 264704 +; RV32ID-FPELIM-NEXT: li a0, 1 +; RV32ID-FPELIM-NEXT: li a2, 2 +; RV32ID-FPELIM-NEXT: li a4, 3 +; RV32ID-FPELIM-NEXT: li a6, 4 +; RV32ID-FPELIM-NEXT: sw a1, 0(sp) +; RV32ID-FPELIM-NEXT: li a1, 0 +; RV32ID-FPELIM-NEXT: li a3, 0 +; RV32ID-FPELIM-NEXT: li a5, 0 +; RV32ID-FPELIM-NEXT: li a7, 0 +; RV32ID-FPELIM-NEXT: call callee_float_on_stack@plt +; RV32ID-FPELIM-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32ID-FPELIM-NEXT: addi sp, sp, 16 +; RV32ID-FPELIM-NEXT: ret %1 = call i32 @callee_float_on_stack(i64 1, i64 2, i64 3, i64 4, float 5.0) ret i32 %1 } @@ -164,6 +209,11 @@ ; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload ; RV32I-WITHFP-NEXT: addi sp, sp, 16 ; RV32I-WITHFP-NEXT: ret +; +; RV32ID-FPELIM-LABEL: callee_tiny_scalar_ret: +; RV32ID-FPELIM: # %bb.0: +; RV32ID-FPELIM-NEXT: lui a0, 260096 +; RV32ID-FPELIM-NEXT: ret ret float 1.0 } @@ -188,7 +238,42 @@ ; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload ; RV32I-WITHFP-NEXT: addi sp, sp, 16 ; RV32I-WITHFP-NEXT: ret +; +; RV32ID-FPELIM-LABEL: caller_tiny_scalar_ret: +; RV32ID-FPELIM: # %bb.0: +; RV32ID-FPELIM-NEXT: addi sp, sp, -16 +; RV32ID-FPELIM-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32ID-FPELIM-NEXT: call callee_tiny_scalar_ret@plt +; RV32ID-FPELIM-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32ID-FPELIM-NEXT: addi sp, sp, 16 +; RV32ID-FPELIM-NEXT: ret %1 = call float @callee_tiny_scalar_ret() %2 = bitcast float %1 to i32 ret i32 %2 } + +define double @func_return_double_undef() { +; RV32I-FPELIM-LABEL: func_return_double_undef: +; RV32I-FPELIM: # %bb.0: +; RV32I-FPELIM-NEXT: ret +; +; RV32I-WITHFP-LABEL: func_return_double_undef: +; RV32I-WITHFP: # %bb.0: +; RV32I-WITHFP-NEXT: addi sp, sp, -16 +; RV32I-WITHFP-NEXT: .cfi_def_cfa_offset 16 +; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32I-WITHFP-NEXT: .cfi_offset ra, -4 +; RV32I-WITHFP-NEXT: .cfi_offset s0, -8 +; RV32I-WITHFP-NEXT: addi s0, sp, 16 +; RV32I-WITHFP-NEXT: .cfi_def_cfa s0, 0 +; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32I-WITHFP-NEXT: addi sp, sp, 16 +; RV32I-WITHFP-NEXT: ret +; +; RV32ID-FPELIM-LABEL: func_return_double_undef: +; RV32ID-FPELIM: # %bb.0: +; RV32ID-FPELIM-NEXT: ret + ret double undef +}