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 @@ -10603,7 +10603,7 @@ MVT XLenVT = XLen == 32 ? MVT::i32 : MVT::i64; // Static chain parameter must not be passed in normal argument registers, - // so we assign t2 for it as did in GCC's __builtin_call_with_static_chain + // so we assign t2 for it as done in GCC's __builtin_call_with_static_chain if (ArgFlags.isNest()) { if (unsigned Reg = State.AllocateReg(RISCV::X7)) { State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); @@ -11136,6 +11136,11 @@ CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State) { + if (ArgFlags.isNest()) { + report_fatal_error( + "Attribute 'nest' is not supported in GHC calling convention"); + } + if (LocVT == MVT::i32 || LocVT == MVT::i64) { // Pass in STG registers: Base, Sp, Hp, R1, R2, R3, R4, R5, R6, R7, SpLim // s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 diff --git a/llvm/test/CodeGen/RISCV/ghccc-nest.ll b/llvm/test/CodeGen/RISCV/ghccc-nest.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/ghccc-nest.ll @@ -0,0 +1,15 @@ +; Check that no nest arguments are not passed in GHC calling convention +; +; RUN: not --crash llc -mtriple=riscv64 -mattr=+f,+d -verify-machineinstrs < %s 2>&1 | FileCheck %s +; RUN: not --crash llc -mtriple=riscv32 -mattr=+f,+d -verify-machineinstrs < %s 2>&1 | FileCheck %s + +define ghccc i8* @nest_receiver(i8* nest %arg) nounwind { + ret i8* %arg +} + +define ghccc i8* @nest_caller(i8* %arg) nounwind { + %result = call ghccc i8* @nest_receiver(i8* nest %arg) + ret i8* %result +} + +; CHECK: LLVM ERROR: Attribute 'nest' is not supported in GHC calling convention diff --git a/llvm/test/CodeGen/RISCV/nest-register.ll b/llvm/test/CodeGen/RISCV/nest-register.ll --- a/llvm/test/CodeGen/RISCV/nest-register.ll +++ b/llvm/test/CodeGen/RISCV/nest-register.ll @@ -1,12 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ ; RUN: | FileCheck -check-prefix=RV32I %s -; RUN: llc -mtriple=riscv32 -mattr=+m -verify-machineinstrs < %s \ -; RUN: | FileCheck -check-prefix=RV32IM %s ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ ; RUN: | FileCheck -check-prefix=RV64I %s -; RUN: llc -mtriple=riscv64 -mattr=+m -verify-machineinstrs < %s \ -; RUN: | FileCheck -check-prefix=RV64IM %s ; Tests that the 'nest' parameter attribute causes the relevant parameter to be ; passed in the right register. @@ -17,20 +13,11 @@ ; RV32I-NEXT: mv a0, t2 ; RV32I-NEXT: ret ; -; RV32IM-LABEL: nest_receiver: -; RV32IM: # %bb.0: -; RV32IM-NEXT: mv a0, t2 -; RV32IM-NEXT: ret -; ; RV64I-LABEL: nest_receiver: ; RV64I: # %bb.0: ; RV64I-NEXT: mv a0, t2 ; RV64I-NEXT: ret ; -; RV64IM-LABEL: nest_receiver: -; RV64IM: # %bb.0: -; RV64IM-NEXT: mv a0, t2 -; RV64IM-NEXT: ret ret i8* %arg } @@ -45,16 +32,6 @@ ; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret ; -; RV32IM-LABEL: nest_caller: -; RV32IM: # %bb.0: -; RV32IM-NEXT: addi sp, sp, -16 -; RV32IM-NEXT: sw ra, 12(sp) # 4-byte Folded Spill -; RV32IM-NEXT: mv t2, a0 -; RV32IM-NEXT: call nest_receiver@plt -; RV32IM-NEXT: lw ra, 12(sp) # 4-byte Folded Reload -; RV32IM-NEXT: addi sp, sp, 16 -; RV32IM-NEXT: ret -; ; RV64I-LABEL: nest_caller: ; RV64I: # %bb.0: ; RV64I-NEXT: addi sp, sp, -16 @@ -65,15 +42,6 @@ ; RV64I-NEXT: addi sp, sp, 16 ; RV64I-NEXT: ret ; -; RV64IM-LABEL: nest_caller: -; RV64IM: # %bb.0: -; RV64IM-NEXT: addi sp, sp, -16 -; RV64IM-NEXT: sd ra, 8(sp) # 8-byte Folded Spill -; RV64IM-NEXT: mv t2, a0 -; RV64IM-NEXT: call nest_receiver@plt -; RV64IM-NEXT: ld ra, 8(sp) # 8-byte Folded Reload -; RV64IM-NEXT: addi sp, sp, 16 -; RV64IM-NEXT: ret %result = call i8* @nest_receiver(i8* nest %arg) ret i8* %result }