Index: lib/Target/RISCV/RISCVISelLowering.h =================================================================== --- lib/Target/RISCV/RISCVISelLowering.h +++ lib/Target/RISCV/RISCVISelLowering.h @@ -141,6 +141,8 @@ unsigned getExceptionSelectorRegister(const Constant *PersonalityFn) const override; + bool shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const override; + private: void analyzeInputArgs(MachineFunction &MF, CCState &CCInfo, const SmallVectorImpl &Ins, Index: lib/Target/RISCV/RISCVISelLowering.cpp =================================================================== --- lib/Target/RISCV/RISCVISelLowering.cpp +++ lib/Target/RISCV/RISCVISelLowering.cpp @@ -2643,3 +2643,12 @@ const Constant *PersonalityFn) const { return RISCV::X11; } + +bool RISCVTargetLowering::shouldSignExtendTypeInLibCall(EVT Type, + bool IsSigned) const { + RISCVABI::ABI ABI = Subtarget.getTargetABI(); + if ((ABI == RISCVABI::ABI_LP64) && Type == MVT::i32) + return true; + + return IsSigned; +} Index: test/CodeGen/RISCV/calling-conv-lp64.ll =================================================================== --- test/CodeGen/RISCV/calling-conv-lp64.ll +++ test/CodeGen/RISCV/calling-conv-lp64.ll @@ -21,8 +21,7 @@ ; RV64I-FPELIM-NEXT: sd ra, 8(sp) ; RV64I-FPELIM-NEXT: sd s0, 0(sp) ; RV64I-FPELIM-NEXT: mv s0, a0 -; RV64I-FPELIM-NEXT: slli a0, a1, 32 -; RV64I-FPELIM-NEXT: srli a0, a0, 32 +; RV64I-FPELIM-NEXT: sext.w a0, a1 ; RV64I-FPELIM-NEXT: call __fixsfdi ; RV64I-FPELIM-NEXT: add a0, s0, a0 ; RV64I-FPELIM-NEXT: ld s0, 0(sp) @@ -38,8 +37,7 @@ ; RV64I-WITHFP-NEXT: sd s1, 8(sp) ; RV64I-WITHFP-NEXT: addi s0, sp, 32 ; RV64I-WITHFP-NEXT: mv s1, a0 -; RV64I-WITHFP-NEXT: slli a0, a1, 32 -; RV64I-WITHFP-NEXT: srli a0, a0, 32 +; RV64I-WITHFP-NEXT: sext.w a0, a1 ; RV64I-WITHFP-NEXT: call __fixsfdi ; RV64I-WITHFP-NEXT: add a0, s1, a0 ; RV64I-WITHFP-NEXT: ld s1, 8(sp) Index: test/CodeGen/RISCV/rv32i-rv64i-float-double.ll =================================================================== --- test/CodeGen/RISCV/rv32i-rv64i-float-double.ll +++ test/CodeGen/RISCV/rv32i-rv64i-float-double.ll @@ -31,10 +31,8 @@ ; RV64IF-NEXT: addi sp, sp, -16 ; RV64IF-NEXT: sd ra, 8(sp) ; RV64IF-NEXT: sd s0, 0(sp) -; RV64IF-NEXT: slli a0, a0, 32 -; RV64IF-NEXT: srli a0, a0, 32 -; RV64IF-NEXT: slli a1, a1, 32 -; RV64IF-NEXT: srli s0, a1, 32 +; RV64IF-NEXT: sext.w a0, a0 +; RV64IF-NEXT: sext.w s0, a1 ; RV64IF-NEXT: mv a1, s0 ; RV64IF-NEXT: call __addsf3 ; RV64IF-NEXT: mv a1, s0 Index: test/CodeGen/RISCV/rv64-complex-floating-add.ll =================================================================== --- /dev/null +++ test/CodeGen/RISCV/rv64-complex-floating-add.ll @@ -0,0 +1,55 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s | FileCheck %s + +; The test case check that zero_extensions will be generated when lowering +; single floating operations. +; Please reference https://bugs.llvm.org/show_bug.cgi?id=42820 for more details. + +define i64 @complex_float_add(i64 %a.coerce, i64 %b.coerce) nounwind { +; CHECK-LABEL: complex_float_add: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: addi sp, sp, -32 +; CHECK-NEXT: sd ra, 24(sp) +; CHECK-NEXT: sd s0, 16(sp) +; CHECK-NEXT: sd s1, 8(sp) +; CHECK-NEXT: sd s2, 0(sp) +; CHECK-NEXT: mv s0, a1 +; CHECK-NEXT: mv s1, a0 +; CHECK-NEXT: sext.w a0, a0 +; CHECK-NEXT: sext.w a1, a1 +; CHECK-NEXT: call __addsf3 +; CHECK-NEXT: mv s2, a0 +; CHECK-NEXT: srai a0, s1, 32 +; CHECK-NEXT: srai a1, s0, 32 +; CHECK-NEXT: call __addsf3 +; CHECK-NEXT: slli a0, a0, 32 +; CHECK-NEXT: slli a1, s2, 32 +; CHECK-NEXT: srli a1, a1, 32 +; CHECK-NEXT: or a0, a0, a1 +; CHECK-NEXT: ld s2, 0(sp) +; CHECK-NEXT: ld s1, 8(sp) +; CHECK-NEXT: ld s0, 16(sp) +; CHECK-NEXT: ld ra, 24(sp) +; CHECK-NEXT: addi sp, sp, 32 +; CHECK-NEXT: ret +entry: + %a.sroa.0.0.extract.trunc = trunc i64 %a.coerce to i32 + %0 = bitcast i32 %a.sroa.0.0.extract.trunc to float + %a.sroa.2.0.extract.shift = lshr i64 %a.coerce, 32 + %a.sroa.2.0.extract.trunc = trunc i64 %a.sroa.2.0.extract.shift to i32 + %1 = bitcast i32 %a.sroa.2.0.extract.trunc to float + %b.sroa.0.0.extract.trunc = trunc i64 %b.coerce to i32 + %2 = bitcast i32 %b.sroa.0.0.extract.trunc to float + %b.sroa.2.0.extract.shift = lshr i64 %b.coerce, 32 + %b.sroa.2.0.extract.trunc = trunc i64 %b.sroa.2.0.extract.shift to i32 + %3 = bitcast i32 %b.sroa.2.0.extract.trunc to float + %add.r = fadd float %0, %2 + %add.i = fadd float %1, %3 + %4 = bitcast float %add.r to i32 + %5 = bitcast float %add.i to i32 + %retval.sroa.2.0.insert.ext = zext i32 %5 to i64 + %retval.sroa.2.0.insert.shift = shl nuw i64 %retval.sroa.2.0.insert.ext, 32 + %retval.sroa.0.0.insert.ext = zext i32 %4 to i64 + %retval.sroa.0.0.insert.insert = or i64 %retval.sroa.2.0.insert.shift, %retval.sroa.0.0.insert.ext + ret i64 %retval.sroa.0.0.insert.insert +}