Index: llvm/lib/Target/RISCV/RISCVFrameLowering.cpp =================================================================== --- llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -379,6 +379,35 @@ Amount = -Amount; Opc = RISCV::SUB; } + + // Optimize compile time offset case + if (STI.getRealMinVLen() == STI.getRealMaxVLen()) { + // 1. Multiply the number of v-slots by the (constant) length of register + Register ScratchReg = + MF.getRegInfo().createVirtualRegister(&RISCV::GPRRegClass); + const int64_t VLENB = STI.getRealMinVLen() / 8; + const int64_t Offset = Amount * VLENB; + if (!isInt<32>(Offset)) { + report_fatal_error( + "Frame size outside of the signed 32-bit range not supported"); + } + if (isInt<12>(Offset)) { + BuildMI(MBB, MBBI, DL, TII->get(Opc), SPReg) + .addReg(SPReg) + .addImm(Offset) + .setMIFlag(Flag); + return; + } + + TII->movImm(MBB, MBBI, DL, ScratchReg, Offset); + // 2. SP = SP - RVV stack size + BuildMI(MBB, MBBI, DL, TII->get(Opc), SPReg) + .addReg(SPReg) + .addReg(ScratchReg, RegState::Kill) + .setMIFlag(Flag); + return; + } + // 1. Multiply the number of v-slots to the length of registers Register FactorRegister = MF.getRegInfo().createVirtualRegister(&RISCV::GPRRegClass); Index: llvm/test/CodeGen/RISCV/rvv/rv64-spill-vector-csr.ll =================================================================== --- llvm/test/CodeGen/RISCV/rvv/rv64-spill-vector-csr.ll +++ llvm/test/CodeGen/RISCV/rvv/rv64-spill-vector-csr.ll @@ -87,9 +87,7 @@ ; SPILL-O2-VLEN128-NEXT: addi sp, sp, -32 ; SPILL-O2-VLEN128-NEXT: sd ra, 24(sp) # 8-byte Folded Spill ; SPILL-O2-VLEN128-NEXT: sd s0, 16(sp) # 8-byte Folded Spill -; SPILL-O2-VLEN128-NEXT: csrr a1, vlenb -; SPILL-O2-VLEN128-NEXT: slli a1, a1, 1 -; SPILL-O2-VLEN128-NEXT: sub sp, sp, a1 +; SPILL-O2-VLEN128-NEXT: sub sp, sp, 512 ; SPILL-O2-VLEN128-NEXT: mv s0, a0 ; SPILL-O2-VLEN128-NEXT: addi a1, sp, 16 ; SPILL-O2-VLEN128-NEXT: vs1r.v v8, (a1) # Unknown-size Folded Spill @@ -106,9 +104,7 @@ ; SPILL-O2-VLEN128-NEXT: addi a0, sp, 16 ; SPILL-O2-VLEN128-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload ; SPILL-O2-VLEN128-NEXT: vfadd.vv v8, v9, v8 -; SPILL-O2-VLEN128-NEXT: csrr a0, vlenb -; SPILL-O2-VLEN128-NEXT: slli a0, a0, 1 -; SPILL-O2-VLEN128-NEXT: add sp, sp, a0 +; SPILL-O2-VLEN128-NEXT: add sp, sp, 512 ; SPILL-O2-VLEN128-NEXT: ld ra, 24(sp) # 8-byte Folded Reload ; SPILL-O2-VLEN128-NEXT: ld s0, 16(sp) # 8-byte Folded Reload ; SPILL-O2-VLEN128-NEXT: addi sp, sp, 32