diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -67,11 +67,13 @@ BuildMI(MBB, MI, DL, TII->get(IsRV64 ? RISCV::SD : RISCV::SW)) .addReg(RAReg) .addReg(SCSPReg) - .addImm(0); + .addImm(0) + .setMIFlag(MachineInstr::FrameSetup); BuildMI(MBB, MI, DL, TII->get(RISCV::ADDI)) .addReg(SCSPReg, RegState::Define) .addReg(SCSPReg) - .addImm(SlotSize); + .addImm(SlotSize) + .setMIFlag(MachineInstr::FrameSetup); } static void emitSCSEpilogue(MachineFunction &MF, MachineBasicBlock &MBB, @@ -115,11 +117,13 @@ BuildMI(MBB, MI, DL, TII->get(IsRV64 ? RISCV::LD : RISCV::LW)) .addReg(RAReg, RegState::Define) .addReg(SCSPReg) - .addImm(-SlotSize); + .addImm(-SlotSize) + .setMIFlag(MachineInstr::FrameDestroy); BuildMI(MBB, MI, DL, TII->get(RISCV::ADDI)) .addReg(SCSPReg, RegState::Define) .addReg(SCSPReg) - .addImm(-SlotSize); + .addImm(-SlotSize) + .setMIFlag(MachineInstr::FrameDestroy); } // Get the ID of the libcall used for spilling and restoring callee saved @@ -313,18 +317,21 @@ const RISCVInstrInfo *TII = STI.getInstrInfo(); Register SPReg = getSPReg(STI); unsigned Opc = RISCV::ADD; + MachineInstr::MIFlag FrameFlag = MachineInstr::FrameDestroy; if (Amount < 0) { Amount = -Amount; Opc = RISCV::SUB; + FrameFlag = MachineInstr::FrameSetup; } // 1. Multiply the number of v-slots to the length of registers - Register FactorRegister = - TII->getVLENFactoredAmount(MF, MBB, MBBI, DL, Amount); + Register FactorRegister = TII->getVLENFactoredAmount( + MF, MBB, MBBI, DL, Amount, /*IsPrologue=*/true, FrameFlag); // 2. SP = SP - RVV stack size BuildMI(MBB, MBBI, DL, TII->get(Opc), SPReg) .addReg(SPReg) - .addReg(FactorRegister, RegState::Kill); + .addReg(FactorRegister, RegState::Kill) + .setMIFlag(FrameFlag); } void RISCVFrameLowering::emitPrologue(MachineFunction &MF, @@ -414,7 +421,8 @@ unsigned CFIIndex = MF.addFrameInst( MCCFIInstruction::cfiDefCfaOffset(nullptr, RealStackSize)); BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex); + .addCFIIndex(CFIIndex) + .setMIFlag(MachineInstr::FrameSetup); const auto &CSI = MFI.getCalleeSavedInfo(); @@ -442,7 +450,8 @@ unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( nullptr, RI->getDwarfRegNum(Reg, true), Offset)); BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex); + .addCFIIndex(CFIIndex) + .setMIFlag(MachineInstr::FrameSetup); } // Generate new FP. @@ -459,7 +468,8 @@ unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfa( nullptr, RI->getDwarfRegNum(FPReg, true), RVFI->getVarArgsSaveSize())); BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex); + .addCFIIndex(CFIIndex) + .setMIFlag(MachineInstr::FrameSetup); } // Emit the second SP adjustment after saving callee saved registers. @@ -477,7 +487,8 @@ unsigned CFIIndex = MF.addFrameInst( MCCFIInstruction::cfiDefCfaOffset(nullptr, MFI.getStackSize())); BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex); + .addCFIIndex(CFIIndex) + .setMIFlag(MachineInstr::FrameSetup); } } @@ -494,17 +505,20 @@ if (isInt<12>(-(int)MaxAlignment.value())) { BuildMI(MBB, MBBI, DL, TII->get(RISCV::ANDI), SPReg) .addReg(SPReg) - .addImm(-(int)MaxAlignment.value()); + .addImm(-(int)MaxAlignment.value()) + .setMIFlag(MachineInstr::FrameSetup); } else { unsigned ShiftAmount = Log2(MaxAlignment); Register VR = MF.getRegInfo().createVirtualRegister(&RISCV::GPRRegClass); BuildMI(MBB, MBBI, DL, TII->get(RISCV::SRLI), VR) .addReg(SPReg) - .addImm(ShiftAmount); + .addImm(ShiftAmount) + .setMIFlag(MachineInstr::FrameSetup); BuildMI(MBB, MBBI, DL, TII->get(RISCV::SLLI), SPReg) .addReg(VR) - .addImm(ShiftAmount); + .addImm(ShiftAmount) + .setMIFlag(MachineInstr::FrameSetup); } // FP will be used to restore the frame in the epilogue, so we need // another base register BP to record SP after re-alignment. SP will diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.h b/llvm/lib/Target/RISCV/RISCVInstrInfo.h --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.h +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.h @@ -147,9 +147,11 @@ MachineInstr &MI, LiveVariables *LV) const override; - Register getVLENFactoredAmount(MachineFunction &MF, MachineBasicBlock &MBB, - MachineBasicBlock::iterator II, - const DebugLoc &DL, int64_t Amount) const; + Register getVLENFactoredAmount( + MachineFunction &MF, MachineBasicBlock &MBB, + MachineBasicBlock::iterator II, const DebugLoc &DL, int64_t Amount, + bool IsPrologue = false, + MachineInstr::MIFlag Flag = MachineInstr::NoFlags) const; // Returns true if the given MI is an RVV instruction opcode for which we may // expect to see a FrameIndex operand. When CheckFIs is true, the instruction 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 @@ -1462,7 +1462,9 @@ MachineBasicBlock &MBB, MachineBasicBlock::iterator II, const DebugLoc &DL, - int64_t Amount) const { + int64_t Amount, + bool IsPrologue, + MachineInstr::MIFlag Flag) const { assert(Amount > 0 && "There is no need to get VLEN scaled value."); assert(Amount % 8 == 0 && "Reserve the stack by the multiple of one vector size."); @@ -1472,7 +1474,8 @@ int64_t NumOfVReg = Amount / 8; Register VL = MRI.createVirtualRegister(&RISCV::GPRRegClass); - BuildMI(MBB, II, DL, TII->get(RISCV::PseudoReadVLENB), VL); + BuildMI(MBB, II, DL, TII->get(RISCV::PseudoReadVLENB), VL) + .setMIFlag(Flag); assert(isInt<32>(NumOfVReg) && "Expect the number of vector registers within 32-bits."); if (isPowerOf2_32(NumOfVReg)) { @@ -1481,40 +1484,48 @@ return VL; BuildMI(MBB, II, DL, TII->get(RISCV::SLLI), VL) .addReg(VL, RegState::Kill) - .addImm(ShiftAmount); + .addImm(ShiftAmount) + .setMIFlag(Flag); } else if (isPowerOf2_32(NumOfVReg - 1)) { Register ScaledRegister = MRI.createVirtualRegister(&RISCV::GPRRegClass); uint32_t ShiftAmount = Log2_32(NumOfVReg - 1); BuildMI(MBB, II, DL, TII->get(RISCV::SLLI), ScaledRegister) .addReg(VL) - .addImm(ShiftAmount); + .addImm(ShiftAmount) + .setMIFlag(Flag); BuildMI(MBB, II, DL, TII->get(RISCV::ADD), VL) .addReg(ScaledRegister, RegState::Kill) - .addReg(VL, RegState::Kill); + .addReg(VL, RegState::Kill) + .setMIFlag(Flag); } else if (isPowerOf2_32(NumOfVReg + 1)) { Register ScaledRegister = MRI.createVirtualRegister(&RISCV::GPRRegClass); uint32_t ShiftAmount = Log2_32(NumOfVReg + 1); BuildMI(MBB, II, DL, TII->get(RISCV::SLLI), ScaledRegister) .addReg(VL) - .addImm(ShiftAmount); + .addImm(ShiftAmount) + .setMIFlag(Flag); BuildMI(MBB, II, DL, TII->get(RISCV::SUB), VL) .addReg(ScaledRegister, RegState::Kill) - .addReg(VL, RegState::Kill); + .addReg(VL, RegState::Kill) + .setMIFlag(Flag); } else { Register N = MRI.createVirtualRegister(&RISCV::GPRRegClass); if (!isInt<12>(NumOfVReg)) movImm(MBB, II, DL, N, NumOfVReg); - else + else { BuildMI(MBB, II, DL, TII->get(RISCV::ADDI), N) .addReg(RISCV::X0) - .addImm(NumOfVReg); + .addImm(NumOfVReg) + .setMIFlag(Flag); + } if (!MF.getSubtarget().hasStdExtM()) MF.getFunction().getContext().diagnose(DiagnosticInfoUnsupported{ MF.getFunction(), "M-extension must be enabled to calculate the vscaled size/offset."}); BuildMI(MBB, II, DL, TII->get(RISCV::MUL), VL) .addReg(VL, RegState::Kill) - .addReg(N, RegState::Kill); + .addReg(N, RegState::Kill) + .setMIFlag(Flag); } return VL; diff --git a/llvm/test/CodeGen/RISCV/rvv/addi-scalable-offset.mir b/llvm/test/CodeGen/RISCV/rvv/addi-scalable-offset.mir --- a/llvm/test/CodeGen/RISCV/rvv/addi-scalable-offset.mir +++ b/llvm/test/CodeGen/RISCV/rvv/addi-scalable-offset.mir @@ -28,16 +28,16 @@ ; CHECK-LABEL: name: add_scalable_offset ; CHECK: liveins: $x10, $x11, $x1 ; CHECK: $x2 = frame-setup ADDI $x2, -2032 - ; CHECK: CFI_INSTRUCTION def_cfa_offset 2032 + ; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 2032 ; CHECK: SD killed $x1, $x2, 2024 :: (store 8 into %stack.3) ; CHECK: SD killed $x8, $x2, 2016 :: (store 8 into %stack.4) - ; CHECK: CFI_INSTRUCTION offset $x1, -8 - ; CHECK: CFI_INSTRUCTION offset $x8, -16 + ; CHECK: frame-setup CFI_INSTRUCTION offset $x1, -8 + ; CHECK: frame-setup CFI_INSTRUCTION offset $x8, -16 ; CHECK: $x8 = frame-setup ADDI $x2, 2032 - ; CHECK: CFI_INSTRUCTION def_cfa $x8, 0 + ; CHECK: frame-setup CFI_INSTRUCTION def_cfa $x8, 0 ; CHECK: $x2 = frame-setup ADDI $x2, -240 - ; CHECK: $x12 = PseudoReadVLENB - ; CHECK: $x2 = SUB $x2, killed $x12 + ; CHECK: $x12 = frame-setup PseudoReadVLENB + ; CHECK: $x2 = frame-setup SUB $x2, killed $x12 ; CHECK: dead $x0 = PseudoVSETVLI killed renamable $x11, 88, implicit-def $vl, implicit-def $vtype ; CHECK: renamable $v25 = PseudoVLE64_V_M1 killed renamable $x10, $noreg, 6, implicit $vl, implicit $vtype :: (load unknown-size from %ir.pa, align 8) ; CHECK: $x11 = PseudoReadVLENB @@ -46,8 +46,8 @@ ; CHECK: $x10 = ADD $x8, killed $x10 ; CHECK: $x10 = SUB killed $x10, killed $x11 ; CHECK: VS1R_V killed renamable $v25, killed renamable $x10 - ; CHECK: $x10 = PseudoReadVLENB - ; CHECK: $x2 = ADD $x2, killed $x10 + ; CHECK: $x10 = frame-destroy PseudoReadVLENB + ; CHECK: $x2 = frame-destroy ADD $x2, killed $x10 ; CHECK: $x2 = frame-destroy ADDI $x2, 240 ; CHECK: $x8 = LD $x2, 2016 :: (load 8 from %stack.4) ; CHECK: $x1 = LD $x2, 2024 :: (load 8 from %stack.3) diff --git a/llvm/test/CodeGen/RISCV/rvv/emergency-slot.mir b/llvm/test/CodeGen/RISCV/rvv/emergency-slot.mir --- a/llvm/test/CodeGen/RISCV/rvv/emergency-slot.mir +++ b/llvm/test/CodeGen/RISCV/rvv/emergency-slot.mir @@ -53,7 +53,7 @@ ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000) ; CHECK: liveins: $x12, $x1, $x9, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27 ; CHECK: $x2 = frame-setup ADDI $x2, -2032 - ; CHECK: CFI_INSTRUCTION def_cfa_offset 2032 + ; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 2032 ; CHECK: SD killed $x1, $x2, 2024 :: (store 8 into %stack.3) ; CHECK: SD killed $x8, $x2, 2016 :: (store 8 into %stack.4) ; CHECK: SD killed $x9, $x2, 2008 :: (store 8 into %stack.5) @@ -67,27 +67,27 @@ ; CHECK: SD killed $x25, $x2, 1944 :: (store 8 into %stack.13) ; CHECK: SD killed $x26, $x2, 1936 :: (store 8 into %stack.14) ; CHECK: SD killed $x27, $x2, 1928 :: (store 8 into %stack.15) - ; CHECK: CFI_INSTRUCTION offset $x1, -8 - ; CHECK: CFI_INSTRUCTION offset $x8, -16 - ; CHECK: CFI_INSTRUCTION offset $x9, -24 - ; CHECK: CFI_INSTRUCTION offset $x18, -32 - ; CHECK: CFI_INSTRUCTION offset $x19, -40 - ; CHECK: CFI_INSTRUCTION offset $x20, -48 - ; CHECK: CFI_INSTRUCTION offset $x21, -56 - ; CHECK: CFI_INSTRUCTION offset $x22, -64 - ; CHECK: CFI_INSTRUCTION offset $x23, -72 - ; CHECK: CFI_INSTRUCTION offset $x24, -80 - ; CHECK: CFI_INSTRUCTION offset $x25, -88 - ; CHECK: CFI_INSTRUCTION offset $x26, -96 - ; CHECK: CFI_INSTRUCTION offset $x27, -104 + ; CHECK: frame-setup CFI_INSTRUCTION offset $x1, -8 + ; CHECK: frame-setup CFI_INSTRUCTION offset $x8, -16 + ; CHECK: frame-setup CFI_INSTRUCTION offset $x9, -24 + ; CHECK: frame-setup CFI_INSTRUCTION offset $x18, -32 + ; CHECK: frame-setup CFI_INSTRUCTION offset $x19, -40 + ; CHECK: frame-setup CFI_INSTRUCTION offset $x20, -48 + ; CHECK: frame-setup CFI_INSTRUCTION offset $x21, -56 + ; CHECK: frame-setup CFI_INSTRUCTION offset $x22, -64 + ; CHECK: frame-setup CFI_INSTRUCTION offset $x23, -72 + ; CHECK: frame-setup CFI_INSTRUCTION offset $x24, -80 + ; CHECK: frame-setup CFI_INSTRUCTION offset $x25, -88 + ; CHECK: frame-setup CFI_INSTRUCTION offset $x26, -96 + ; CHECK: frame-setup CFI_INSTRUCTION offset $x27, -104 ; CHECK: $x8 = frame-setup ADDI $x2, 2032 - ; CHECK: CFI_INSTRUCTION def_cfa $x8, 0 + ; CHECK: frame-setup CFI_INSTRUCTION def_cfa $x8, 0 ; CHECK: $x2 = frame-setup ADDI $x2, -272 - ; CHECK: $x10 = PseudoReadVLENB - ; CHECK: $x11 = ADDI $x0, 51 - ; CHECK: $x10 = MUL killed $x10, killed $x11 - ; CHECK: $x2 = SUB $x2, killed $x10 - ; CHECK: $x2 = ANDI $x2, -128 + ; CHECK: $x10 = frame-setup PseudoReadVLENB + ; CHECK: $x11 = frame-setup ADDI $x0, 51 + ; CHECK: $x10 = frame-setup MUL killed $x10, killed $x11 + ; CHECK: $x2 = frame-setup SUB $x2, killed $x10 + ; CHECK: $x2 = frame-setup ANDI $x2, -128 ; CHECK: dead renamable $x15 = PseudoVSETIVLI 1, 72, implicit-def $vl, implicit-def $vtype ; CHECK: renamable $v25 = PseudoVMV_V_X_M1 killed renamable $x12, $noreg, 16, implicit $vl, implicit $vtype ; CHECK: $x11 = PseudoReadVLENB diff --git a/llvm/test/CodeGen/RISCV/rvv/get-vlen-debugloc.mir b/llvm/test/CodeGen/RISCV/rvv/get-vlen-debugloc.mir --- a/llvm/test/CodeGen/RISCV/rvv/get-vlen-debugloc.mir +++ b/llvm/test/CodeGen/RISCV/rvv/get-vlen-debugloc.mir @@ -25,14 +25,14 @@ ; CHECK-LABEL: name: foo ; CHECK: bb.0: ; CHECK: successors: %bb.1(0x80000000) - ; CHECK: CFI_INSTRUCTION def_cfa_offset 0 - ; CHECK: $x10 = PseudoReadVLENB - ; CHECK: $x10 = SLLI killed $x10, 1 - ; CHECK: $x2 = SUB $x2, killed $x10 + ; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 0 + ; CHECK: $x10 = frame-setup PseudoReadVLENB + ; CHECK: $x10 = frame-setup SLLI killed $x10, 1 + ; CHECK: $x2 = frame-setup SUB $x2, killed $x10 ; CHECK: bb.1: - ; CHECK: $x10 = PseudoReadVLENB - ; CHECK: $x10 = SLLI killed $x10, 1 - ; CHECK: $x2 = ADD $x2, killed $x10 + ; CHECK: $x10 = frame-destroy PseudoReadVLENB + ; CHECK: $x10 = frame-destroy SLLI killed $x10, 1 + ; CHECK: $x2 = frame-destroy ADD $x2, killed $x10 ; CHECK: PseudoRET bb.0: bb.1: diff --git a/llvm/test/CodeGen/RISCV/rvv/zvlsseg-spill.mir b/llvm/test/CodeGen/RISCV/rvv/zvlsseg-spill.mir --- a/llvm/test/CodeGen/RISCV/rvv/zvlsseg-spill.mir +++ b/llvm/test/CodeGen/RISCV/rvv/zvlsseg-spill.mir @@ -21,10 +21,10 @@ ; 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: frame-setup CFI_INSTRUCTION def_cfa_offset 16 + ; CHECK: $x12 = frame-setup PseudoReadVLENB + ; CHECK: $x12 = frame-setup SLLI killed $x12, 3 + ; CHECK: $x2 = frame-setup SUB $x2, killed $x12 ; CHECK: dead $x0 = 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 @@ -34,9 +34,9 @@ ; 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: $x10 = frame-destroy PseudoReadVLENB + ; CHECK: $x10 = frame-destroy SLLI killed $x10, 3 + ; CHECK: $x2 = frame-destroy ADD $x2, killed $x10 ; CHECK: $x2 = frame-destroy ADDI $x2, 16 ; CHECK: PseudoRET %0:gpr = COPY $x10