diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -31,6 +31,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/EHPersonalities.h" +#include "llvm/Analysis/MemoryLocation.h" #include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/BinaryFormat/COFF.h" #include "llvm/BinaryFormat/Dwarf.h" @@ -847,12 +848,16 @@ CommentOS << *Size << "-byte Reload\n"; } else if ((Size = MI.getFoldedRestoreSize(TII))) { if (*Size) - CommentOS << *Size << "-byte Folded Reload\n"; + (*Size == static_cast(MemoryLocation::UnknownSize)) ? + CommentOS << "Unknown size Folded Reload\n" : + CommentOS << *Size << "-byte Folded Reload\n"; } else if ((Size = MI.getSpillSize(TII))) { CommentOS << *Size << "-byte Spill\n"; } else if ((Size = MI.getFoldedSpillSize(TII))) { if (*Size) - CommentOS << *Size << "-byte Folded Spill\n"; + (*Size == static_cast(MemoryLocation::UnknownSize)) ? + CommentOS << "Unknown size Folded Spill\n" : + CommentOS << *Size << "-byte Folded Spill\n"; } // Check for spill-induced copies diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -12,11 +12,13 @@ #include "RISCVInstrInfo.h" #include "RISCV.h" +#include "RISCVMachineFunctionInfo.h" #include "RISCVSubtarget.h" #include "RISCVTargetMachine.h" #include "Utils/RISCVMatInt.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Analysis/MemoryLocation.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" @@ -141,12 +143,10 @@ DL = I->getDebugLoc(); MachineFunction *MF = MBB.getParent(); - const MachineFrameInfo &MFI = MF->getFrameInfo(); - MachineMemOperand *MMO = MF->getMachineMemOperand( - MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOStore, - MFI.getObjectSize(FI), MFI.getObjectAlign(FI)); + MachineFrameInfo &MFI = MF->getFrameInfo(); unsigned Opcode; + bool IsScalableVector = false; if (RISCV::GPRRegClass.hasSubClassEq(RC)) Opcode = TRI->getRegSizeInBits(RISCV::GPRRegClass) == 32 ? RISCV::SW : RISCV::SD; @@ -156,14 +156,42 @@ Opcode = RISCV::FSW; else if (RISCV::FPR64RegClass.hasSubClassEq(RC)) Opcode = RISCV::FSD; - else + else if (RISCV::VRRegClass.hasSubClassEq(RC)) { + Opcode = RISCV::PseudoVSPILL_M1; + IsScalableVector = true; + } else if (RISCV::VRM2RegClass.hasSubClassEq(RC)) { + Opcode = RISCV::PseudoVSPILL_M2; + IsScalableVector = true; + } else if (RISCV::VRM4RegClass.hasSubClassEq(RC)) { + Opcode = RISCV::PseudoVSPILL_M4; + IsScalableVector = true; + } else if (RISCV::VRM8RegClass.hasSubClassEq(RC)) { + Opcode = RISCV::PseudoVSPILL_M8; + IsScalableVector = true; + } else llvm_unreachable("Can't store this register to stack slot"); - BuildMI(MBB, I, DL, get(Opcode)) - .addReg(SrcReg, getKillRegState(IsKill)) - .addFrameIndex(FI) - .addImm(0) - .addMemOperand(MMO); + if (IsScalableVector) { + MachineMemOperand *MMO = MF->getMachineMemOperand( + MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOStore, + MemoryLocation::UnknownSize, MFI.getObjectAlign(FI)); + + MFI.setStackID(FI, TargetStackID::RISCVVector); + BuildMI(MBB, I, DL, get(Opcode)) + .addReg(SrcReg, getKillRegState(IsKill)) + .addFrameIndex(FI) + .addMemOperand(MMO); + } else { + MachineMemOperand *MMO = MF->getMachineMemOperand( + MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOStore, + MFI.getObjectSize(FI), MFI.getObjectAlign(FI)); + + BuildMI(MBB, I, DL, get(Opcode)) + .addReg(SrcReg, getKillRegState(IsKill)) + .addFrameIndex(FI) + .addImm(0) + .addMemOperand(MMO); + } } void RISCVInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, @@ -176,12 +204,10 @@ DL = I->getDebugLoc(); MachineFunction *MF = MBB.getParent(); - const MachineFrameInfo &MFI = MF->getFrameInfo(); - MachineMemOperand *MMO = MF->getMachineMemOperand( - MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad, - MFI.getObjectSize(FI), MFI.getObjectAlign(FI)); + MachineFrameInfo &MFI = MF->getFrameInfo(); unsigned Opcode; + bool IsScalableVector = false; if (RISCV::GPRRegClass.hasSubClassEq(RC)) Opcode = TRI->getRegSizeInBits(RISCV::GPRRegClass) == 32 ? RISCV::LW : RISCV::LD; @@ -191,13 +217,40 @@ Opcode = RISCV::FLW; else if (RISCV::FPR64RegClass.hasSubClassEq(RC)) Opcode = RISCV::FLD; - else + else if (RISCV::VRRegClass.hasSubClassEq(RC)) { + Opcode = RISCV::PseudoVRELOAD_M1; + IsScalableVector = true; + } else if (RISCV::VRM2RegClass.hasSubClassEq(RC)) { + Opcode = RISCV::PseudoVRELOAD_M2; + IsScalableVector = true; + } else if (RISCV::VRM4RegClass.hasSubClassEq(RC)) { + Opcode = RISCV::PseudoVRELOAD_M4; + IsScalableVector = true; + } else if (RISCV::VRM8RegClass.hasSubClassEq(RC)) { + Opcode = RISCV::PseudoVRELOAD_M8; + IsScalableVector = true; + } else llvm_unreachable("Can't load this register from stack slot"); - BuildMI(MBB, I, DL, get(Opcode), DstReg) - .addFrameIndex(FI) - .addImm(0) - .addMemOperand(MMO); + if (IsScalableVector) { + MachineMemOperand *MMO = MF->getMachineMemOperand( + MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad, + MemoryLocation::UnknownSize, MFI.getObjectAlign(FI)); + + MFI.setStackID(FI, TargetStackID::RISCVVector); + BuildMI(MBB, I, DL, get(Opcode), DstReg) + .addFrameIndex(FI) + .addMemOperand(MMO); + } else { + MachineMemOperand *MMO = MF->getMachineMemOperand( + MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad, + MFI.getObjectSize(FI), MFI.getObjectAlign(FI)); + + BuildMI(MBB, I, DL, get(Opcode), DstReg) + .addFrameIndex(FI) + .addImm(0) + .addMemOperand(MMO); + } } void RISCVInstrInfo::movImm(MachineBasicBlock &MBB, diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td @@ -1662,6 +1662,20 @@ def PseudoReadVLENB : Pseudo<(outs GPR:$rd), (ins), []>; } +let hasSideEffects = 0, mayLoad = 0, mayStore = 1, isCodeGenOnly = 1 in { + def PseudoVSPILL_M1 : VPseudo; + def PseudoVSPILL_M2 : VPseudo; + def PseudoVSPILL_M4 : VPseudo; + def PseudoVSPILL_M8 : VPseudo; +} + +let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 1 in { + def PseudoVRELOAD_M1 : VPseudo; + def PseudoVRELOAD_M2 : VPseudo; + def PseudoVRELOAD_M4 : VPseudo; + def PseudoVRELOAD_M8 : VPseudo; +} + //===----------------------------------------------------------------------===// // 6. Configuration-Setting Instructions //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp @@ -76,6 +76,7 @@ BitVector RISCVRegisterInfo::getReservedRegs(const MachineFunction &MF) const { const RISCVFrameLowering *TFI = getFrameLowering(MF); BitVector Reserved(getNumRegs()); + const RISCVSubtarget &Subtarget = MF.getSubtarget(); // Mark any registers requested to be reserved as such for (size_t Reg = 0; Reg < getNumRegs(); Reg++) { @@ -88,7 +89,12 @@ markSuperRegs(Reserved, RISCV::X2); // sp markSuperRegs(Reserved, RISCV::X3); // gp markSuperRegs(Reserved, RISCV::X4); // tp - if (TFI->hasFP(MF)) + // If there is need to spill RVV object as register allocation, SP will + // be adjusted by a variable length at runtime. We need to reserve FP to + // access callee-saved registers. However, we have no information for RVV + // spilling after ISel lowering. Here, we reserve FP if V extension is + // enabled. See llvm/test/CodeGen/RISCV/rvv/spill-vector-csr.ll. + if (TFI->hasFP(MF) || Subtarget.hasStdExtV()) markSuperRegs(Reserved, RISCV::X8); // fp // Reserve the base register if we need to realign the stack and allocate // variable-sized objects at runtime. diff --git a/llvm/test/CodeGen/RISCV/rvv/spill-vector-csr.ll b/llvm/test/CodeGen/RISCV/rvv/spill-vector-csr.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rvv/spill-vector-csr.ll @@ -0,0 +1,87 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv64 -mattr=+experimental-v -mattr=+d -O0 < %s \ +; RUN: | FileCheck --check-prefix=SPILL-O0 %s +; RUN: llc -mtriple=riscv64 -mattr=+experimental-v -mattr=+d -O2 < %s \ +; RUN: | FileCheck --check-prefix=SPILL-O2 %s + +@.str = private unnamed_addr constant [6 x i8] c"hello\00", align 1 + +define @foo( %a, %b, %c, i64 %gvl) nounwind +; SPILL-O0-LABEL: foo: +; SPILL-O0: # %bb.0: +; SPILL-O0-NEXT: addi sp, sp, -48 +; SPILL-O0-NEXT: sd ra, 40(sp) # 8-byte Folded Spill +; SPILL-O0-NEXT: sd s0, 32(sp) # 8-byte Folded Spill +; SPILL-O0-NEXT: addi s0, sp, 48 +; SPILL-O0-NEXT: csrr a1, vlenb +; SPILL-O0-NEXT: sub sp, sp, a1 +; SPILL-O0-NEXT: sd sp, -32(s0) # 8-byte Folded Spill +; SPILL-O0-NEXT: sub sp, sp, a1 +; SPILL-O0-NEXT: sd sp, -40(s0) # 8-byte Folded Spill +; SPILL-O0-NEXT: sd a0, -24(s0) # 8-byte Folded Spill +; SPILL-O0-NEXT: ld a1, -32(s0) +; SPILL-O0-NEXT: vs1r.v v16, (a1) # Unknown size Folded Spill +; SPILL-O0-NEXT: vsetvli a0, a0, e64,m1,ta,mu +; SPILL-O0-NEXT: vfadd.vv v25, v16, v17 +; SPILL-O0-NEXT: ld a0, -40(s0) +; SPILL-O0-NEXT: vs1r.v v25, (a0) # Unknown size Folded Spill +; SPILL-O0-NEXT: lui a0, %hi(.L.str) +; SPILL-O0-NEXT: addi a0, a0, %lo(.L.str) +; SPILL-O0-NEXT: call puts@plt +; SPILL-O0-NEXT: ld a1, -40(s0) +; SPILL-O0-NEXT: vl1r.v v25, (a1) # Unknown size Folded Reload +; SPILL-O0-NEXT: ld a1, -32(s0) +; SPILL-O0-NEXT: vl1r.v v16, (a1) # Unknown size Folded Reload +; SPILL-O0-NEXT: # kill: def $x11 killed $x10 +; SPILL-O0-NEXT: ld a0, -24(s0) # 8-byte Folded Reload +; SPILL-O0-NEXT: vsetvli a0, a0, e64,m1,ta,mu +; SPILL-O0-NEXT: vfadd.vv v16, v16, v25 +; SPILL-O0-NEXT: addi sp, s0, -48 +; SPILL-O0-NEXT: ld s0, 32(sp) # 8-byte Folded Reload +; SPILL-O0-NEXT: ld ra, 40(sp) # 8-byte Folded Reload +; SPILL-O0-NEXT: addi sp, sp, 48 +; SPILL-O0-NEXT: ret +; +; SPILL-O2-LABEL: foo: +; SPILL-O2: # %bb.0: +; SPILL-O2-NEXT: addi sp, sp, -48 +; SPILL-O2-NEXT: sd ra, 40(sp) # 8-byte Folded Spill +; SPILL-O2-NEXT: sd s0, 32(sp) # 8-byte Folded Spill +; SPILL-O2-NEXT: sd s1, 24(sp) # 8-byte Folded Spill +; SPILL-O2-NEXT: addi s0, sp, 48 +; SPILL-O2-NEXT: csrr a1, vlenb +; SPILL-O2-NEXT: sub sp, sp, a1 +; SPILL-O2-NEXT: sd sp, -32(s0) # 8-byte Folded Spill +; SPILL-O2-NEXT: sub sp, sp, a1 +; SPILL-O2-NEXT: sd sp, -40(s0) # 8-byte Folded Spill +; SPILL-O2-NEXT: mv s1, a0 +; SPILL-O2-NEXT: ld a1, -40(s0) +; SPILL-O2-NEXT: vs1r.v v16, (a1) # Unknown size Folded Spill +; SPILL-O2-NEXT: vsetvli a0, a0, e64,m1,ta,mu +; SPILL-O2-NEXT: vfadd.vv v25, v16, v17 +; SPILL-O2-NEXT: ld a0, -32(s0) +; SPILL-O2-NEXT: vs1r.v v25, (a0) # Unknown size Folded Spill +; SPILL-O2-NEXT: lui a0, %hi(.L.str) +; SPILL-O2-NEXT: addi a0, a0, %lo(.L.str) +; SPILL-O2-NEXT: call puts@plt +; SPILL-O2-NEXT: vsetvli a0, s1, e64,m1,ta,mu +; SPILL-O2-NEXT: ld a0, -32(s0) +; SPILL-O2-NEXT: vl1r.v v25, (a0) # Unknown size Folded Reload +; SPILL-O2-NEXT: ld a0, -40(s0) +; SPILL-O2-NEXT: vl1r.v v26, (a0) # Unknown size Folded Reload +; SPILL-O2-NEXT: vfadd.vv v16, v26, v25 +; SPILL-O2-NEXT: addi sp, s0, -48 +; SPILL-O2-NEXT: ld s1, 24(sp) # 8-byte Folded Reload +; SPILL-O2-NEXT: ld s0, 32(sp) # 8-byte Folded Reload +; SPILL-O2-NEXT: ld ra, 40(sp) # 8-byte Folded Reload +; SPILL-O2-NEXT: addi sp, sp, 48 +; SPILL-O2-NEXT: ret +{ + %x = call @llvm.riscv.vfadd.nxv1f64.nxv1f64( %a, %b, i64 %gvl) + %call = call signext i32 @puts(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i64 0, i64 0)) + %z = call @llvm.riscv.vfadd.nxv1f64.nxv1f64( %a, %x, i64 %gvl) + ret %z +} + +declare @llvm.riscv.vfadd.nxv1f64.nxv1f64( %a, %b, i64 %gvl) +declare i32 @puts(i8*); diff --git a/llvm/test/CodeGen/RISCV/rvv/spill-vector.ll b/llvm/test/CodeGen/RISCV/rvv/spill-vector.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rvv/spill-vector.ll @@ -0,0 +1,207 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv64 -mattr=+experimental-v -O0 < %s \ +; RUN: | FileCheck --check-prefix=SPILL-O0 %s +; RUN: llc -mtriple=riscv64 -mattr=+experimental-v -O2 < %s \ +; RUN: | FileCheck --check-prefix=SPILL-O2 %s + +define @spill_lmul_1( %va) nounwind { +; SPILL-O0-LABEL: spill_lmul_1: +; SPILL-O0: # %bb.0: # %entry +; SPILL-O0-NEXT: addi sp, sp, -32 +; SPILL-O0-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; SPILL-O0-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; SPILL-O0-NEXT: addi s0, sp, 32 +; SPILL-O0-NEXT: csrr a0, vlenb +; SPILL-O0-NEXT: sub sp, sp, a0 +; SPILL-O0-NEXT: sd sp, -24(s0) # 8-byte Folded Spill +; SPILL-O0-NEXT: ld a0, -24(s0) +; SPILL-O0-NEXT: vs1r.v v16, (a0) # Unknown size Folded Spill +; SPILL-O0-NEXT: #APP +; SPILL-O0-NEXT: #NO_APP +; SPILL-O0-NEXT: ld a0, -24(s0) +; SPILL-O0-NEXT: vl1r.v v16, (a0) # Unknown size Folded Reload +; SPILL-O0-NEXT: addi sp, s0, -32 +; SPILL-O0-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; SPILL-O0-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; SPILL-O0-NEXT: addi sp, sp, 32 +; SPILL-O0-NEXT: ret +; +; SPILL-O2-LABEL: spill_lmul_1: +; SPILL-O2: # %bb.0: # %entry +; SPILL-O2-NEXT: addi sp, sp, -32 +; SPILL-O2-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; SPILL-O2-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; SPILL-O2-NEXT: addi s0, sp, 32 +; SPILL-O2-NEXT: csrr a0, vlenb +; SPILL-O2-NEXT: sub sp, sp, a0 +; SPILL-O2-NEXT: sd sp, -24(s0) # 8-byte Folded Spill +; SPILL-O2-NEXT: ld a0, -24(s0) +; SPILL-O2-NEXT: vs1r.v v16, (a0) # Unknown size Folded Spill +; SPILL-O2-NEXT: #APP +; SPILL-O2-NEXT: #NO_APP +; SPILL-O2-NEXT: ld a0, -24(s0) +; SPILL-O2-NEXT: vl1r.v v16, (a0) # Unknown size Folded Reload +; SPILL-O2-NEXT: addi sp, s0, -32 +; SPILL-O2-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; SPILL-O2-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; SPILL-O2-NEXT: addi sp, sp, 32 +; SPILL-O2-NEXT: ret +entry: + call void asm sideeffect "", + "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31}"() + + ret %va +} + +define @spill_lmul_2( %va) nounwind { +; SPILL-O0-LABEL: spill_lmul_2: +; SPILL-O0: # %bb.0: # %entry +; SPILL-O0-NEXT: addi sp, sp, -32 +; SPILL-O0-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; SPILL-O0-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; SPILL-O0-NEXT: addi s0, sp, 32 +; SPILL-O0-NEXT: csrr a0, vlenb +; SPILL-O0-NEXT: slli a0, a0, 1 +; SPILL-O0-NEXT: sub sp, sp, a0 +; SPILL-O0-NEXT: sd sp, -24(s0) # 16-byte Folded Spill +; SPILL-O0-NEXT: ld a0, -24(s0) +; SPILL-O0-NEXT: vs2r.v v16, (a0) # Unknown size Folded Spill +; SPILL-O0-NEXT: #APP +; SPILL-O0-NEXT: #NO_APP +; SPILL-O0-NEXT: ld a0, -24(s0) +; SPILL-O0-NEXT: vl2r.v v16, (a0) # Unknown size Folded Reload +; SPILL-O0-NEXT: addi sp, s0, -32 +; SPILL-O0-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; SPILL-O0-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; SPILL-O0-NEXT: addi sp, sp, 32 +; SPILL-O0-NEXT: ret +; +; SPILL-O2-LABEL: spill_lmul_2: +; SPILL-O2: # %bb.0: # %entry +; SPILL-O2-NEXT: addi sp, sp, -32 +; SPILL-O2-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; SPILL-O2-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; SPILL-O2-NEXT: addi s0, sp, 32 +; SPILL-O2-NEXT: csrr a0, vlenb +; SPILL-O2-NEXT: slli a0, a0, 1 +; SPILL-O2-NEXT: sub sp, sp, a0 +; SPILL-O2-NEXT: sd sp, -24(s0) # 16-byte Folded Spill +; SPILL-O2-NEXT: ld a0, -24(s0) +; SPILL-O2-NEXT: vs2r.v v16, (a0) # Unknown size Folded Spill +; SPILL-O2-NEXT: #APP +; SPILL-O2-NEXT: #NO_APP +; SPILL-O2-NEXT: ld a0, -24(s0) +; SPILL-O2-NEXT: vl2r.v v16, (a0) # Unknown size Folded Reload +; SPILL-O2-NEXT: addi sp, s0, -32 +; SPILL-O2-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; SPILL-O2-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; SPILL-O2-NEXT: addi sp, sp, 32 +; SPILL-O2-NEXT: ret +entry: + call void asm sideeffect "", + "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31}"() + + ret %va +} + +define @spill_lmul_4( %va) nounwind { +; SPILL-O0-LABEL: spill_lmul_4: +; SPILL-O0: # %bb.0: # %entry +; SPILL-O0-NEXT: addi sp, sp, -32 +; SPILL-O0-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; SPILL-O0-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; SPILL-O0-NEXT: addi s0, sp, 32 +; SPILL-O0-NEXT: csrr a0, vlenb +; SPILL-O0-NEXT: slli a0, a0, 2 +; SPILL-O0-NEXT: sub sp, sp, a0 +; SPILL-O0-NEXT: sd sp, -24(s0) # 32-byte Folded Spill +; SPILL-O0-NEXT: ld a0, -24(s0) +; SPILL-O0-NEXT: vs4r.v v16, (a0) # Unknown size Folded Spill +; SPILL-O0-NEXT: #APP +; SPILL-O0-NEXT: #NO_APP +; SPILL-O0-NEXT: ld a0, -24(s0) +; SPILL-O0-NEXT: vl4r.v v16, (a0) # Unknown size Folded Reload +; SPILL-O0-NEXT: addi sp, s0, -32 +; SPILL-O0-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; SPILL-O0-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; SPILL-O0-NEXT: addi sp, sp, 32 +; SPILL-O0-NEXT: ret +; +; SPILL-O2-LABEL: spill_lmul_4: +; SPILL-O2: # %bb.0: # %entry +; SPILL-O2-NEXT: addi sp, sp, -32 +; SPILL-O2-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; SPILL-O2-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; SPILL-O2-NEXT: addi s0, sp, 32 +; SPILL-O2-NEXT: csrr a0, vlenb +; SPILL-O2-NEXT: slli a0, a0, 2 +; SPILL-O2-NEXT: sub sp, sp, a0 +; SPILL-O2-NEXT: sd sp, -24(s0) # 32-byte Folded Spill +; SPILL-O2-NEXT: ld a0, -24(s0) +; SPILL-O2-NEXT: vs4r.v v16, (a0) # Unknown size Folded Spill +; SPILL-O2-NEXT: #APP +; SPILL-O2-NEXT: #NO_APP +; SPILL-O2-NEXT: ld a0, -24(s0) +; SPILL-O2-NEXT: vl4r.v v16, (a0) # Unknown size Folded Reload +; SPILL-O2-NEXT: addi sp, s0, -32 +; SPILL-O2-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; SPILL-O2-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; SPILL-O2-NEXT: addi sp, sp, 32 +; SPILL-O2-NEXT: ret +entry: + call void asm sideeffect "", + "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31}"() + + ret %va +} + +define @spill_lmul_8( %va) nounwind { +; SPILL-O0-LABEL: spill_lmul_8: +; SPILL-O0: # %bb.0: # %entry +; SPILL-O0-NEXT: addi sp, sp, -32 +; SPILL-O0-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; SPILL-O0-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; SPILL-O0-NEXT: addi s0, sp, 32 +; SPILL-O0-NEXT: csrr a0, vlenb +; SPILL-O0-NEXT: slli a0, a0, 3 +; SPILL-O0-NEXT: sub sp, sp, a0 +; SPILL-O0-NEXT: sd sp, -24(s0) # 64-byte Folded Spill +; SPILL-O0-NEXT: ld a0, -24(s0) +; SPILL-O0-NEXT: vs8r.v v16, (a0) # Unknown size Folded Spill +; SPILL-O0-NEXT: #APP +; SPILL-O0-NEXT: #NO_APP +; SPILL-O0-NEXT: ld a0, -24(s0) +; SPILL-O0-NEXT: vl8r.v v16, (a0) # Unknown size Folded Reload +; SPILL-O0-NEXT: addi sp, s0, -32 +; SPILL-O0-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; SPILL-O0-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; SPILL-O0-NEXT: addi sp, sp, 32 +; SPILL-O0-NEXT: ret +; +; SPILL-O2-LABEL: spill_lmul_8: +; SPILL-O2: # %bb.0: # %entry +; SPILL-O2-NEXT: addi sp, sp, -32 +; SPILL-O2-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; SPILL-O2-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; SPILL-O2-NEXT: addi s0, sp, 32 +; SPILL-O2-NEXT: csrr a0, vlenb +; SPILL-O2-NEXT: slli a0, a0, 3 +; SPILL-O2-NEXT: sub sp, sp, a0 +; SPILL-O2-NEXT: sd sp, -24(s0) # 64-byte Folded Spill +; SPILL-O2-NEXT: ld a0, -24(s0) +; SPILL-O2-NEXT: vs8r.v v16, (a0) # Unknown size Folded Spill +; SPILL-O2-NEXT: #APP +; SPILL-O2-NEXT: #NO_APP +; SPILL-O2-NEXT: ld a0, -24(s0) +; SPILL-O2-NEXT: vl8r.v v16, (a0) # Unknown size Folded Reload +; SPILL-O2-NEXT: addi sp, s0, -32 +; SPILL-O2-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; SPILL-O2-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; SPILL-O2-NEXT: addi sp, sp, 32 +; SPILL-O2-NEXT: ret +entry: + call void asm sideeffect "", + "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31}"() + + ret %va +}