diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp index 8edfa9ff09f77..730e9992d7c16 100644 --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp @@ -300,14 +300,19 @@ void RISCVRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset.getFixed()); } - MachineFrameInfo &MFI = MF.getFrameInfo(); auto ZvlssegInfo = TII->isRVVSpillForZvlsseg(MI.getOpcode()); if (ZvlssegInfo) { - int64_t ScalableValue = MFI.getObjectSize(FrameIndex) / ZvlssegInfo->first; - Register FactorRegister = - TII->getVLENFactoredAmount(MF, MBB, II, ScalableValue); - MI.getOperand(FIOperandNum + 1) - .ChangeToRegister(FactorRegister, /*isDef=*/false); + Register VL = MRI.createVirtualRegister(&RISCV::GPRRegClass); + BuildMI(MBB, II, DL, TII->get(RISCV::PseudoReadVLENB), VL); + uint32_t ShiftAmount = Log2_32(ZvlssegInfo->second); + if (ShiftAmount != 0) + BuildMI(MBB, II, DL, TII->get(RISCV::SLLI), VL) + .addReg(VL) + .addImm(ShiftAmount); + // The last argument of pseudo spilling opcode for zvlsseg is the length of + // one element of zvlsseg types. For example, for vint32m2x2_t, it will be + // the length of vint32m2_t. + MI.getOperand(FIOperandNum + 1).ChangeToRegister(VL, /*isDef=*/false); } } diff --git a/llvm/test/CodeGen/RISCV/rvv/zvlsseg-spill.mir b/llvm/test/CodeGen/RISCV/rvv/zvlsseg-spill.mir new file mode 100644 index 0000000000000..40ea93c872440 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rvv/zvlsseg-spill.mir @@ -0,0 +1,49 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -march=riscv64 -stop-after=prologepilog %s -o - 2>&1 | FileCheck %s + +--- | + target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n64-S128" + target triple = "riscv64" + + define void @zvlsseg_spill(i64 *%base, i64 %vl) { + ret void + } +... +--- +name: zvlsseg_spill +tracksRegLiveness: true +stack: + - { id: 0, offset: 0, size: 64, alignment: 8, stack-id: scalable-vector } +body: | + bb.0: + liveins: $x10, $x11 + + ; CHECK-LABEL: name: zvlsseg_spill + ; CHECK: liveins: $x10, $x11 + ; CHECK: $x2 = frame-setup ADDI $x2, -16 + ; CHECK: CFI_INSTRUCTION def_cfa_offset 16 + ; CHECK: $x12 = PseudoReadVLENB + ; CHECK: $x12 = SLLI killed $x12, 3 + ; CHECK: $x2 = SUB $x2, killed $x12 + ; CHECK: dead renamable $x11 = PseudoVSETVLI killed renamable $x11, 88, implicit-def $vl, implicit-def $vtype + ; CHECK: $v0_v1_v2_v3_v4_v5_v6 = PseudoVLSEG7E64_V_M1 renamable $x10, $noreg, 6, implicit $vl, implicit $vtype + ; CHECK: $x11 = ADDI $x2, 16 + ; CHECK: $x12 = PseudoReadVLENB + ; CHECK: PseudoVSPILL7_M1 killed renamable $v0_v1_v2_v3_v4_v5_v6, killed $x11, killed $x12 + ; CHECK: $x11 = ADDI $x2, 16 + ; CHECK: $x12 = PseudoReadVLENB + ; CHECK: dead renamable $v7_v8_v9_v10_v11_v12_v13 = PseudoVRELOAD7_M1 killed $x11, killed $x12, implicit-def $v8 + ; CHECK: VS1R_V killed $v8, killed renamable $x10 + ; CHECK: $x10 = PseudoReadVLENB + ; CHECK: $x10 = SLLI killed $x10, 3 + ; CHECK: $x2 = ADD $x2, killed $x10 + ; CHECK: $x2 = frame-destroy ADDI $x2, 16 + ; CHECK: PseudoRET + %0:gpr = COPY $x10 + %1:gpr = COPY $x11 + $v0_v1_v2_v3_v4_v5_v6 = PseudoVLSEG7E64_V_M1 %0, %1, 6, implicit $vl, implicit $vtype + PseudoVSPILL7_M1 killed renamable $v0_v1_v2_v3_v4_v5_v6, %stack.0, $x0 + renamable $v7_v8_v9_v10_v11_v12_v13 = PseudoVRELOAD7_M1 %stack.0, $x0 + VS1R_V killed $v8, %0:gpr + PseudoRET +...