diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp index 9fc0d815ceee3..06ce91771c9e7 100644 --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -106,8 +106,14 @@ static void emitSCSPrologue(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL) { const auto &STI = MF.getSubtarget(); + // We check Zimop instead of (Zimop || Zcmop) to determine whether HW shadow + // stack is available despite the fact that sspush/sspopchk both have a + // compressed form, because if only Zcmop is available, we would need to + // reserve X5 due to c.sspopchk only takes X5 and we currently do not support + // using X5 as the return address register. + // However, we can still aggressively use c.sspush x1 if zcmop is available. bool HasHWShadowStack = MF.getFunction().hasFnAttribute("hw-shadow-stack") && - STI.hasStdExtZicfiss(); + STI.hasStdExtZimop(); bool HasSWShadowStack = MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack); if (!HasHWShadowStack && !HasSWShadowStack) @@ -124,7 +130,12 @@ static void emitSCSPrologue(MachineFunction &MF, MachineBasicBlock &MBB, const RISCVInstrInfo *TII = STI.getInstrInfo(); if (HasHWShadowStack) { - BuildMI(MBB, MI, DL, TII->get(RISCV::SSPUSH)).addReg(RAReg); + if (STI.hasStdExtZcmop()) { + static_assert(RAReg == RISCV::X1, "C.SSPUSH only accepts X1"); + BuildMI(MBB, MI, DL, TII->get(RISCV::PseudoMOP_C_SSPUSH)); + } else { + BuildMI(MBB, MI, DL, TII->get(RISCV::PseudoMOP_SSPUSH)).addReg(RAReg); + } return; } @@ -172,7 +183,7 @@ static void emitSCSEpilogue(MachineFunction &MF, MachineBasicBlock &MBB, const DebugLoc &DL) { const auto &STI = MF.getSubtarget(); bool HasHWShadowStack = MF.getFunction().hasFnAttribute("hw-shadow-stack") && - STI.hasStdExtZicfiss(); + STI.hasStdExtZimop(); bool HasSWShadowStack = MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack); if (!HasHWShadowStack && !HasSWShadowStack) @@ -186,7 +197,7 @@ static void emitSCSEpilogue(MachineFunction &MF, MachineBasicBlock &MBB, const RISCVInstrInfo *TII = STI.getInstrInfo(); if (HasHWShadowStack) { - BuildMI(MBB, MI, DL, TII->get(RISCV::SSPOPCHK)).addReg(RAReg); + BuildMI(MBB, MI, DL, TII->get(RISCV::PseudoMOP_SSPOPCHK)).addReg(RAReg); return; } diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index 23f5a848137c4..df55ee9652fdf 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -2330,7 +2330,6 @@ include "RISCVInstrInfoZalasr.td" include "RISCVInstrInfoZimop.td" include "RISCVInstrInfoZicbo.td" include "RISCVInstrInfoZicond.td" -include "RISCVInstrInfoZicfiss.td" include "RISCVInstrInfoZilsd.td" // Scalar FP @@ -2359,6 +2358,9 @@ include "RISCVInstrInfoZc.td" include "RISCVInstrInfoZcmop.td" include "RISCVInstrInfoZclsd.td" +// Control Flow Integriy, this requires Zimop/Zcmop +include "RISCVInstrInfoZicfiss.td" + // Short Forward Branch include "RISCVInstrInfoSFB.td" diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZicfiss.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZicfiss.td index 49a57f86cccd6..50ebaa9951979 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZicfiss.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZicfiss.td @@ -62,6 +62,21 @@ defm SSAMOSWAP_W : AMO_rr_aq_rl<0b01001, 0b010, "ssamoswap.w">; let Predicates = [HasStdExtZicfiss, IsRV64] in defm SSAMOSWAP_D : AMO_rr_aq_rl<0b01001, 0b011, "ssamoswap.d">; +let Predicates = [HasStdExtZimop] in { +let hasSideEffects = 1, mayLoad = 0, mayStore = 1 in +def PseudoMOP_SSPUSH : Pseudo<(outs), (ins GPRX1X5:$rs2), []>, + PseudoInstExpansion<(MOP_RR_7 X0, X0, GPR:$rs2)>; +let hasSideEffects = 1, mayLoad = 1, mayStore = 0 in +def PseudoMOP_SSPOPCHK : Pseudo<(outs), (ins GPRX1X5:$rs1), []>, + PseudoInstExpansion<(MOP_R_28 X0, GPR:$rs1)>; +} // Predicates = [HasStdExtZimop] + +let Predicates = [HasStdExtZcmop] in { +let Uses = [X1], hasSideEffects = 1, mayLoad = 0, mayStore = 1 in +def PseudoMOP_C_SSPUSH : Pseudo<(outs), (ins), []>, + PseudoInstExpansion<(C_MOP_1)>; +} // Predicates = [HasStdExtZcmop] + //===----------------------------------------------------------------------===/ // Compress Instruction tablegen backend. //===----------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/RISCV/shadowcallstack.ll b/llvm/test/CodeGen/RISCV/shadowcallstack.ll index 03acd9491fed8..5d4ecbf21790a 100644 --- a/llvm/test/CodeGen/RISCV/shadowcallstack.ll +++ b/llvm/test/CodeGen/RISCV/shadowcallstack.ll @@ -427,7 +427,7 @@ define i32 @f3_hw() "hw-shadow-stack" { ; ; RV32-ZICFISS-LABEL: f3_hw: ; RV32-ZICFISS: # %bb.0: -; RV32-ZICFISS-NEXT: sspush ra +; RV32-ZICFISS-NEXT: mop.rr.7 zero, zero, ra ; RV32-ZICFISS-NEXT: addi sp, sp, -16 ; RV32-ZICFISS-NEXT: .cfi_def_cfa_offset 16 ; RV32-ZICFISS-NEXT: sw ra, 12(sp) # 4-byte Folded Spill @@ -437,12 +437,12 @@ define i32 @f3_hw() "hw-shadow-stack" { ; RV32-ZICFISS-NEXT: .cfi_restore ra ; RV32-ZICFISS-NEXT: addi sp, sp, 16 ; RV32-ZICFISS-NEXT: .cfi_def_cfa_offset 0 -; RV32-ZICFISS-NEXT: sspopchk ra +; RV32-ZICFISS-NEXT: mop.r.28 zero, ra ; RV32-ZICFISS-NEXT: ret ; ; RV64-ZICFISS-LABEL: f3_hw: ; RV64-ZICFISS: # %bb.0: -; RV64-ZICFISS-NEXT: sspush ra +; RV64-ZICFISS-NEXT: mop.rr.7 zero, zero, ra ; RV64-ZICFISS-NEXT: addi sp, sp, -16 ; RV64-ZICFISS-NEXT: .cfi_def_cfa_offset 16 ; RV64-ZICFISS-NEXT: sd ra, 8(sp) # 8-byte Folded Spill @@ -452,7 +452,7 @@ define i32 @f3_hw() "hw-shadow-stack" { ; RV64-ZICFISS-NEXT: .cfi_restore ra ; RV64-ZICFISS-NEXT: addi sp, sp, 16 ; RV64-ZICFISS-NEXT: .cfi_def_cfa_offset 0 -; RV64-ZICFISS-NEXT: sspopchk ra +; RV64-ZICFISS-NEXT: mop.r.28 zero, ra ; RV64-ZICFISS-NEXT: ret %res = call i32 @bar() %res1 = add i32 %res, 1 @@ -530,7 +530,7 @@ define i32 @f4_hw() "hw-shadow-stack" { ; ; RV32-ZICFISS-LABEL: f4_hw: ; RV32-ZICFISS: # %bb.0: -; RV32-ZICFISS-NEXT: sspush ra +; RV32-ZICFISS-NEXT: mop.rr.7 zero, zero, ra ; RV32-ZICFISS-NEXT: addi sp, sp, -16 ; RV32-ZICFISS-NEXT: .cfi_def_cfa_offset 16 ; RV32-ZICFISS-NEXT: sw ra, 12(sp) # 4-byte Folded Spill @@ -561,12 +561,12 @@ define i32 @f4_hw() "hw-shadow-stack" { ; RV32-ZICFISS-NEXT: .cfi_restore s2 ; RV32-ZICFISS-NEXT: addi sp, sp, 16 ; RV32-ZICFISS-NEXT: .cfi_def_cfa_offset 0 -; RV32-ZICFISS-NEXT: sspopchk ra +; RV32-ZICFISS-NEXT: mop.r.28 zero, ra ; RV32-ZICFISS-NEXT: ret ; ; RV64-ZICFISS-LABEL: f4_hw: ; RV64-ZICFISS: # %bb.0: -; RV64-ZICFISS-NEXT: sspush ra +; RV64-ZICFISS-NEXT: mop.rr.7 zero, zero, ra ; RV64-ZICFISS-NEXT: addi sp, sp, -32 ; RV64-ZICFISS-NEXT: .cfi_def_cfa_offset 32 ; RV64-ZICFISS-NEXT: sd ra, 24(sp) # 8-byte Folded Spill @@ -597,7 +597,7 @@ define i32 @f4_hw() "hw-shadow-stack" { ; RV64-ZICFISS-NEXT: .cfi_restore s2 ; RV64-ZICFISS-NEXT: addi sp, sp, 32 ; RV64-ZICFISS-NEXT: .cfi_def_cfa_offset 0 -; RV64-ZICFISS-NEXT: sspopchk ra +; RV64-ZICFISS-NEXT: mop.r.28 zero, ra ; RV64-ZICFISS-NEXT: ret %res1 = call i32 @bar() %res2 = call i32 @bar() @@ -630,24 +630,24 @@ define i32 @f5_hw() "hw-shadow-stack" nounwind { ; ; RV32-ZICFISS-LABEL: f5_hw: ; RV32-ZICFISS: # %bb.0: -; RV32-ZICFISS-NEXT: sspush ra +; RV32-ZICFISS-NEXT: mop.rr.7 zero, zero, ra ; RV32-ZICFISS-NEXT: addi sp, sp, -16 ; RV32-ZICFISS-NEXT: sw ra, 12(sp) # 4-byte Folded Spill ; RV32-ZICFISS-NEXT: call bar ; RV32-ZICFISS-NEXT: lw ra, 12(sp) # 4-byte Folded Reload ; RV32-ZICFISS-NEXT: addi sp, sp, 16 -; RV32-ZICFISS-NEXT: sspopchk ra +; RV32-ZICFISS-NEXT: mop.r.28 zero, ra ; RV32-ZICFISS-NEXT: ret ; ; RV64-ZICFISS-LABEL: f5_hw: ; RV64-ZICFISS: # %bb.0: -; RV64-ZICFISS-NEXT: sspush ra +; RV64-ZICFISS-NEXT: mop.rr.7 zero, zero, ra ; RV64-ZICFISS-NEXT: addi sp, sp, -16 ; RV64-ZICFISS-NEXT: sd ra, 8(sp) # 8-byte Folded Spill ; RV64-ZICFISS-NEXT: call bar ; RV64-ZICFISS-NEXT: ld ra, 8(sp) # 8-byte Folded Reload ; RV64-ZICFISS-NEXT: addi sp, sp, 16 -; RV64-ZICFISS-NEXT: sspopchk ra +; RV64-ZICFISS-NEXT: mop.r.28 zero, ra ; RV64-ZICFISS-NEXT: ret %res = call i32 @bar() %res1 = add i32 %res, 1 @@ -734,7 +734,7 @@ define i32 @f3_both() "hw-shadow-stack" shadowcallstack { ; ; RV32-ZICFISS-LABEL: f3_both: ; RV32-ZICFISS: # %bb.0: -; RV32-ZICFISS-NEXT: sspush ra +; RV32-ZICFISS-NEXT: mop.rr.7 zero, zero, ra ; RV32-ZICFISS-NEXT: addi sp, sp, -16 ; RV32-ZICFISS-NEXT: .cfi_def_cfa_offset 16 ; RV32-ZICFISS-NEXT: sw ra, 12(sp) # 4-byte Folded Spill @@ -744,12 +744,12 @@ define i32 @f3_both() "hw-shadow-stack" shadowcallstack { ; RV32-ZICFISS-NEXT: .cfi_restore ra ; RV32-ZICFISS-NEXT: addi sp, sp, 16 ; RV32-ZICFISS-NEXT: .cfi_def_cfa_offset 0 -; RV32-ZICFISS-NEXT: sspopchk ra +; RV32-ZICFISS-NEXT: mop.r.28 zero, ra ; RV32-ZICFISS-NEXT: ret ; ; RV64-ZICFISS-LABEL: f3_both: ; RV64-ZICFISS: # %bb.0: -; RV64-ZICFISS-NEXT: sspush ra +; RV64-ZICFISS-NEXT: mop.rr.7 zero, zero, ra ; RV64-ZICFISS-NEXT: addi sp, sp, -16 ; RV64-ZICFISS-NEXT: .cfi_def_cfa_offset 16 ; RV64-ZICFISS-NEXT: sd ra, 8(sp) # 8-byte Folded Spill @@ -759,7 +759,7 @@ define i32 @f3_both() "hw-shadow-stack" shadowcallstack { ; RV64-ZICFISS-NEXT: .cfi_restore ra ; RV64-ZICFISS-NEXT: addi sp, sp, 16 ; RV64-ZICFISS-NEXT: .cfi_def_cfa_offset 0 -; RV64-ZICFISS-NEXT: sspopchk ra +; RV64-ZICFISS-NEXT: mop.r.28 zero, ra ; RV64-ZICFISS-NEXT: ret %res = call i32 @bar() %res1 = add i32 %res, 1 @@ -849,7 +849,7 @@ define i32 @f4_both() "hw-shadow-stack" shadowcallstack { ; ; RV32-ZICFISS-LABEL: f4_both: ; RV32-ZICFISS: # %bb.0: -; RV32-ZICFISS-NEXT: sspush ra +; RV32-ZICFISS-NEXT: mop.rr.7 zero, zero, ra ; RV32-ZICFISS-NEXT: addi sp, sp, -16 ; RV32-ZICFISS-NEXT: .cfi_def_cfa_offset 16 ; RV32-ZICFISS-NEXT: sw ra, 12(sp) # 4-byte Folded Spill @@ -880,12 +880,12 @@ define i32 @f4_both() "hw-shadow-stack" shadowcallstack { ; RV32-ZICFISS-NEXT: .cfi_restore s2 ; RV32-ZICFISS-NEXT: addi sp, sp, 16 ; RV32-ZICFISS-NEXT: .cfi_def_cfa_offset 0 -; RV32-ZICFISS-NEXT: sspopchk ra +; RV32-ZICFISS-NEXT: mop.r.28 zero, ra ; RV32-ZICFISS-NEXT: ret ; ; RV64-ZICFISS-LABEL: f4_both: ; RV64-ZICFISS: # %bb.0: -; RV64-ZICFISS-NEXT: sspush ra +; RV64-ZICFISS-NEXT: mop.rr.7 zero, zero, ra ; RV64-ZICFISS-NEXT: addi sp, sp, -32 ; RV64-ZICFISS-NEXT: .cfi_def_cfa_offset 32 ; RV64-ZICFISS-NEXT: sd ra, 24(sp) # 8-byte Folded Spill @@ -916,7 +916,7 @@ define i32 @f4_both() "hw-shadow-stack" shadowcallstack { ; RV64-ZICFISS-NEXT: .cfi_restore s2 ; RV64-ZICFISS-NEXT: addi sp, sp, 32 ; RV64-ZICFISS-NEXT: .cfi_def_cfa_offset 0 -; RV64-ZICFISS-NEXT: sspopchk ra +; RV64-ZICFISS-NEXT: mop.r.28 zero, ra ; RV64-ZICFISS-NEXT: ret %res1 = call i32 @bar() %res2 = call i32 @bar() @@ -957,24 +957,24 @@ define i32 @f5_both() "hw-shadow-stack" shadowcallstack nounwind { ; ; RV32-ZICFISS-LABEL: f5_both: ; RV32-ZICFISS: # %bb.0: -; RV32-ZICFISS-NEXT: sspush ra +; RV32-ZICFISS-NEXT: mop.rr.7 zero, zero, ra ; RV32-ZICFISS-NEXT: addi sp, sp, -16 ; RV32-ZICFISS-NEXT: sw ra, 12(sp) # 4-byte Folded Spill ; RV32-ZICFISS-NEXT: call bar ; RV32-ZICFISS-NEXT: lw ra, 12(sp) # 4-byte Folded Reload ; RV32-ZICFISS-NEXT: addi sp, sp, 16 -; RV32-ZICFISS-NEXT: sspopchk ra +; RV32-ZICFISS-NEXT: mop.r.28 zero, ra ; RV32-ZICFISS-NEXT: ret ; ; RV64-ZICFISS-LABEL: f5_both: ; RV64-ZICFISS: # %bb.0: -; RV64-ZICFISS-NEXT: sspush ra +; RV64-ZICFISS-NEXT: mop.rr.7 zero, zero, ra ; RV64-ZICFISS-NEXT: addi sp, sp, -16 ; RV64-ZICFISS-NEXT: sd ra, 8(sp) # 8-byte Folded Spill ; RV64-ZICFISS-NEXT: call bar ; RV64-ZICFISS-NEXT: ld ra, 8(sp) # 8-byte Folded Reload ; RV64-ZICFISS-NEXT: addi sp, sp, 16 -; RV64-ZICFISS-NEXT: sspopchk ra +; RV64-ZICFISS-NEXT: mop.r.28 zero, ra ; RV64-ZICFISS-NEXT: ret %res = call i32 @bar() %res1 = add i32 %res, 1