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 @@ -15149,7 +15149,10 @@ } } - if (LocVT == MVT::f16) { + const RISCVSubtarget &Subtarget = TLI.getSubtarget(); + + if (LocVT == MVT::f16 && + (Subtarget.hasStdExtZfh() || Subtarget.hasStdExtZfhmin())) { static const MCPhysReg FPR16List[] = { RISCV::F10_H, RISCV::F11_H, RISCV::F12_H, RISCV::F13_H, RISCV::F14_H, RISCV::F15_H, RISCV::F16_H, RISCV::F17_H, RISCV::F0_H, RISCV::F1_H, @@ -15161,7 +15164,7 @@ } } - if (LocVT == MVT::f32) { + if (LocVT == MVT::f32 && Subtarget.hasStdExtF()) { static const MCPhysReg FPR32List[] = { RISCV::F10_F, RISCV::F11_F, RISCV::F12_F, RISCV::F13_F, RISCV::F14_F, RISCV::F15_F, RISCV::F16_F, RISCV::F17_F, RISCV::F0_F, RISCV::F1_F, @@ -15173,7 +15176,7 @@ } } - if (LocVT == MVT::f64) { + if (LocVT == MVT::f64 && Subtarget.hasStdExtD()) { static const MCPhysReg FPR64List[] = { RISCV::F10_D, RISCV::F11_D, RISCV::F12_D, RISCV::F13_D, RISCV::F14_D, RISCV::F15_D, RISCV::F16_D, RISCV::F17_D, RISCV::F0_D, RISCV::F1_D, diff --git a/llvm/test/CodeGen/RISCV/fastcc-without-f-reg.ll b/llvm/test/CodeGen/RISCV/fastcc-without-f-reg.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/fastcc-without-f-reg.ll @@ -0,0 +1,145 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 +; RUN: llc -mtriple=riscv32 -mattr=+zfinx -verify-machineinstrs < %s \ +; RUN: | FileCheck -check-prefix=ZFINX32 %s +; RUN: llc -mtriple=riscv64 -mattr=+zfinx -verify-machineinstrs < %s \ +; RUN: | FileCheck -check-prefix=ZFINX64 %s +; RUN: llc -mtriple=riscv32 -mattr=+zdinx -verify-machineinstrs < %s \ +; RUN: | FileCheck -check-prefix=ZDINX32 %s +; RUN: llc -mtriple=riscv64 -mattr=+zdinx -verify-machineinstrs < %s \ +; RUN: | FileCheck -check-prefix=ZDINX64 %s + +define float @caller_float(float %x) nounwind { +; ZFINX32-LABEL: caller_float: +; ZFINX32: # %bb.0: # %entry +; ZFINX32-NEXT: addi sp, sp, -16 +; ZFINX32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; ZFINX32-NEXT: sw a0, 0(sp) +; ZFINX32-NEXT: call f +; ZFINX32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; ZFINX32-NEXT: addi sp, sp, 16 +; ZFINX32-NEXT: ret +; +; ZFINX64-LABEL: caller_float: +; ZFINX64: # %bb.0: # %entry +; ZFINX64-NEXT: addi sp, sp, -16 +; ZFINX64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill +; ZFINX64-NEXT: sw a0, 0(sp) +; ZFINX64-NEXT: call f +; ZFINX64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload +; ZFINX64-NEXT: addi sp, sp, 16 +; ZFINX64-NEXT: ret +; +; ZDINX32-LABEL: caller_float: +; ZDINX32: # %bb.0: # %entry +; ZDINX32-NEXT: addi sp, sp, -16 +; ZDINX32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; ZDINX32-NEXT: sw a0, 0(sp) +; ZDINX32-NEXT: call f +; ZDINX32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; ZDINX32-NEXT: addi sp, sp, 16 +; ZDINX32-NEXT: ret +; +; ZDINX64-LABEL: caller_float: +; ZDINX64: # %bb.0: # %entry +; ZDINX64-NEXT: addi sp, sp, -16 +; ZDINX64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill +; ZDINX64-NEXT: sw a0, 0(sp) +; ZDINX64-NEXT: call f +; ZDINX64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload +; ZDINX64-NEXT: addi sp, sp, 16 +; ZDINX64-NEXT: ret +entry: + %0 = tail call fastcc float @f(float %x) + ret float %0 +} + +define internal fastcc float @f(float %x) nounwind { +; ZFINX32-LABEL: f: +; ZFINX32: # %bb.0: # %entry +; ZFINX32-NEXT: lw a0, 0(sp) +; ZFINX32-NEXT: ret +; +; ZFINX64-LABEL: f: +; ZFINX64: # %bb.0: # %entry +; ZFINX64-NEXT: lw a0, 0(sp) +; ZFINX64-NEXT: ret +; +; ZDINX32-LABEL: f: +; ZDINX32: # %bb.0: # %entry +; ZDINX32-NEXT: lw a0, 0(sp) +; ZDINX32-NEXT: ret +; +; ZDINX64-LABEL: f: +; ZDINX64: # %bb.0: # %entry +; ZDINX64-NEXT: lw a0, 0(sp) +; ZDINX64-NEXT: ret +entry: + ret float %x +} + +define double @caller_double(double %x) nounwind { +; ZFINX32-LABEL: caller_double: +; ZFINX32: # %bb.0: # %entry +; ZFINX32-NEXT: tail d +; +; ZFINX64-LABEL: caller_double: +; ZFINX64: # %bb.0: # %entry +; ZFINX64-NEXT: tail d +; +; ZDINX32-LABEL: caller_double: +; ZDINX32: # %bb.0: # %entry +; ZDINX32-NEXT: addi sp, sp, -32 +; ZDINX32-NEXT: sw ra, 28(sp) # 4-byte Folded Spill +; ZDINX32-NEXT: sw a0, 16(sp) +; ZDINX32-NEXT: sw a1, 20(sp) +; ZDINX32-NEXT: lw a0, 16(sp) +; ZDINX32-NEXT: lw a1, 20(sp) +; ZDINX32-NEXT: sw a0, 0(sp) +; ZDINX32-NEXT: sw a1, 4(sp) +; ZDINX32-NEXT: call d +; ZDINX32-NEXT: lw ra, 28(sp) # 4-byte Folded Reload +; ZDINX32-NEXT: addi sp, sp, 32 +; ZDINX32-NEXT: ret +; +; ZDINX64-LABEL: caller_double: +; ZDINX64: # %bb.0: # %entry +; ZDINX64-NEXT: addi sp, sp, -16 +; ZDINX64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill +; ZDINX64-NEXT: sd a0, 0(sp) +; ZDINX64-NEXT: call d +; ZDINX64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload +; ZDINX64-NEXT: addi sp, sp, 16 +; ZDINX64-NEXT: ret +entry: + %0 = tail call fastcc double @d(double %x) + ret double %0 +} + +define internal fastcc double @d(double %x) nounwind { +; ZFINX32-LABEL: d: +; ZFINX32: # %bb.0: # %entry +; ZFINX32-NEXT: ret +; +; ZFINX64-LABEL: d: +; ZFINX64: # %bb.0: # %entry +; ZFINX64-NEXT: ret +; +; ZDINX32-LABEL: d: +; ZDINX32: # %bb.0: # %entry +; ZDINX32-NEXT: addi sp, sp, -16 +; ZDINX32-NEXT: lw a0, 16(sp) +; ZDINX32-NEXT: lw a1, 20(sp) +; ZDINX32-NEXT: sw a0, 8(sp) +; ZDINX32-NEXT: sw a1, 12(sp) +; ZDINX32-NEXT: lw a0, 8(sp) +; ZDINX32-NEXT: lw a1, 12(sp) +; ZDINX32-NEXT: addi sp, sp, 16 +; ZDINX32-NEXT: ret +; +; ZDINX64-LABEL: d: +; ZDINX64: # %bb.0: # %entry +; ZDINX64-NEXT: ld a0, 0(sp) +; ZDINX64-NEXT: ret +entry: + ret double %x +}