Skip to content

Commit 9bbf22c

Browse files
authored
[RISCV] Loosen the requirement of shadow stack codegen to Zimop (#152251)
Zicfiss (Shadow Stack) instructions are implemented using the encoding space defined in the "Zimop" May-Be-Operations Extension, where the instruction behaviors turn into NOP if Zimop is implemented but the redefining extension does not present. This means we can safely loosen the codegen requirement of shadow stack to Zimop, in that those processors with Zimop but no Zicfiss can still execute the instructions without problem. This patch add new pseudo instructions to model MOPs that are expanded into Zicfiss instructios, and change to emit them in the codegen
1 parent 8d35bcc commit 9bbf22c

File tree

4 files changed

+57
-29
lines changed

4 files changed

+57
-29
lines changed

llvm/lib/Target/RISCV/RISCVFrameLowering.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,14 @@ static void emitSCSPrologue(MachineFunction &MF, MachineBasicBlock &MBB,
106106
MachineBasicBlock::iterator MI,
107107
const DebugLoc &DL) {
108108
const auto &STI = MF.getSubtarget<RISCVSubtarget>();
109+
// We check Zimop instead of (Zimop || Zcmop) to determine whether HW shadow
110+
// stack is available despite the fact that sspush/sspopchk both have a
111+
// compressed form, because if only Zcmop is available, we would need to
112+
// reserve X5 due to c.sspopchk only takes X5 and we currently do not support
113+
// using X5 as the return address register.
114+
// However, we can still aggressively use c.sspush x1 if zcmop is available.
109115
bool HasHWShadowStack = MF.getFunction().hasFnAttribute("hw-shadow-stack") &&
110-
STI.hasStdExtZicfiss();
116+
STI.hasStdExtZimop();
111117
bool HasSWShadowStack =
112118
MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack);
113119
if (!HasHWShadowStack && !HasSWShadowStack)
@@ -124,7 +130,12 @@ static void emitSCSPrologue(MachineFunction &MF, MachineBasicBlock &MBB,
124130

125131
const RISCVInstrInfo *TII = STI.getInstrInfo();
126132
if (HasHWShadowStack) {
127-
BuildMI(MBB, MI, DL, TII->get(RISCV::SSPUSH)).addReg(RAReg);
133+
if (STI.hasStdExtZcmop()) {
134+
static_assert(RAReg == RISCV::X1, "C.SSPUSH only accepts X1");
135+
BuildMI(MBB, MI, DL, TII->get(RISCV::PseudoMOP_C_SSPUSH));
136+
} else {
137+
BuildMI(MBB, MI, DL, TII->get(RISCV::PseudoMOP_SSPUSH)).addReg(RAReg);
138+
}
128139
return;
129140
}
130141

@@ -172,7 +183,7 @@ static void emitSCSEpilogue(MachineFunction &MF, MachineBasicBlock &MBB,
172183
const DebugLoc &DL) {
173184
const auto &STI = MF.getSubtarget<RISCVSubtarget>();
174185
bool HasHWShadowStack = MF.getFunction().hasFnAttribute("hw-shadow-stack") &&
175-
STI.hasStdExtZicfiss();
186+
STI.hasStdExtZimop();
176187
bool HasSWShadowStack =
177188
MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack);
178189
if (!HasHWShadowStack && !HasSWShadowStack)
@@ -186,7 +197,7 @@ static void emitSCSEpilogue(MachineFunction &MF, MachineBasicBlock &MBB,
186197

187198
const RISCVInstrInfo *TII = STI.getInstrInfo();
188199
if (HasHWShadowStack) {
189-
BuildMI(MBB, MI, DL, TII->get(RISCV::SSPOPCHK)).addReg(RAReg);
200+
BuildMI(MBB, MI, DL, TII->get(RISCV::PseudoMOP_SSPOPCHK)).addReg(RAReg);
190201
return;
191202
}
192203

llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2328,7 +2328,6 @@ include "RISCVInstrInfoZalasr.td"
23282328
include "RISCVInstrInfoZimop.td"
23292329
include "RISCVInstrInfoZicbo.td"
23302330
include "RISCVInstrInfoZicond.td"
2331-
include "RISCVInstrInfoZicfiss.td"
23322331
include "RISCVInstrInfoZilsd.td"
23332332

23342333
// Scalar FP
@@ -2357,6 +2356,9 @@ include "RISCVInstrInfoZc.td"
23572356
include "RISCVInstrInfoZcmop.td"
23582357
include "RISCVInstrInfoZclsd.td"
23592358

2359+
// Control Flow Integriy, this requires Zimop/Zcmop
2360+
include "RISCVInstrInfoZicfiss.td"
2361+
23602362
// Short Forward Branch
23612363
include "RISCVInstrInfoSFB.td"
23622364

llvm/lib/Target/RISCV/RISCVInstrInfoZicfiss.td

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,21 @@ defm SSAMOSWAP_W : AMO_rr_aq_rl<0b01001, 0b010, "ssamoswap.w">;
6262
let Predicates = [HasStdExtZicfiss, IsRV64] in
6363
defm SSAMOSWAP_D : AMO_rr_aq_rl<0b01001, 0b011, "ssamoswap.d">;
6464

65+
let Predicates = [HasStdExtZimop] in {
66+
let hasSideEffects = 1, mayLoad = 0, mayStore = 1 in
67+
def PseudoMOP_SSPUSH : Pseudo<(outs), (ins GPRX1X5:$rs2), []>,
68+
PseudoInstExpansion<(MOP_RR_7 X0, X0, GPR:$rs2)>;
69+
let hasSideEffects = 1, mayLoad = 1, mayStore = 0 in
70+
def PseudoMOP_SSPOPCHK : Pseudo<(outs), (ins GPRX1X5:$rs1), []>,
71+
PseudoInstExpansion<(MOP_R_28 X0, GPR:$rs1)>;
72+
} // Predicates = [HasStdExtZimop]
73+
74+
let Predicates = [HasStdExtZcmop] in {
75+
let Uses = [X1], hasSideEffects = 1, mayLoad = 0, mayStore = 1 in
76+
def PseudoMOP_C_SSPUSH : Pseudo<(outs), (ins), []>,
77+
PseudoInstExpansion<(C_MOP_1)>;
78+
} // Predicates = [HasStdExtZcmop]
79+
6580
//===----------------------------------------------------------------------===/
6681
// Compress Instruction tablegen backend.
6782
//===----------------------------------------------------------------------===//

llvm/test/CodeGen/RISCV/shadowcallstack.ll

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ define i32 @f3_hw() "hw-shadow-stack" {
427427
;
428428
; RV32-ZICFISS-LABEL: f3_hw:
429429
; RV32-ZICFISS: # %bb.0:
430-
; RV32-ZICFISS-NEXT: sspush ra
430+
; RV32-ZICFISS-NEXT: mop.rr.7 zero, zero, ra
431431
; RV32-ZICFISS-NEXT: addi sp, sp, -16
432432
; RV32-ZICFISS-NEXT: .cfi_def_cfa_offset 16
433433
; RV32-ZICFISS-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
@@ -437,12 +437,12 @@ define i32 @f3_hw() "hw-shadow-stack" {
437437
; RV32-ZICFISS-NEXT: .cfi_restore ra
438438
; RV32-ZICFISS-NEXT: addi sp, sp, 16
439439
; RV32-ZICFISS-NEXT: .cfi_def_cfa_offset 0
440-
; RV32-ZICFISS-NEXT: sspopchk ra
440+
; RV32-ZICFISS-NEXT: mop.r.28 zero, ra
441441
; RV32-ZICFISS-NEXT: ret
442442
;
443443
; RV64-ZICFISS-LABEL: f3_hw:
444444
; RV64-ZICFISS: # %bb.0:
445-
; RV64-ZICFISS-NEXT: sspush ra
445+
; RV64-ZICFISS-NEXT: mop.rr.7 zero, zero, ra
446446
; RV64-ZICFISS-NEXT: addi sp, sp, -16
447447
; RV64-ZICFISS-NEXT: .cfi_def_cfa_offset 16
448448
; RV64-ZICFISS-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
@@ -452,7 +452,7 @@ define i32 @f3_hw() "hw-shadow-stack" {
452452
; RV64-ZICFISS-NEXT: .cfi_restore ra
453453
; RV64-ZICFISS-NEXT: addi sp, sp, 16
454454
; RV64-ZICFISS-NEXT: .cfi_def_cfa_offset 0
455-
; RV64-ZICFISS-NEXT: sspopchk ra
455+
; RV64-ZICFISS-NEXT: mop.r.28 zero, ra
456456
; RV64-ZICFISS-NEXT: ret
457457
%res = call i32 @bar()
458458
%res1 = add i32 %res, 1
@@ -530,7 +530,7 @@ define i32 @f4_hw() "hw-shadow-stack" {
530530
;
531531
; RV32-ZICFISS-LABEL: f4_hw:
532532
; RV32-ZICFISS: # %bb.0:
533-
; RV32-ZICFISS-NEXT: sspush ra
533+
; RV32-ZICFISS-NEXT: mop.rr.7 zero, zero, ra
534534
; RV32-ZICFISS-NEXT: addi sp, sp, -16
535535
; RV32-ZICFISS-NEXT: .cfi_def_cfa_offset 16
536536
; RV32-ZICFISS-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
@@ -561,12 +561,12 @@ define i32 @f4_hw() "hw-shadow-stack" {
561561
; RV32-ZICFISS-NEXT: .cfi_restore s2
562562
; RV32-ZICFISS-NEXT: addi sp, sp, 16
563563
; RV32-ZICFISS-NEXT: .cfi_def_cfa_offset 0
564-
; RV32-ZICFISS-NEXT: sspopchk ra
564+
; RV32-ZICFISS-NEXT: mop.r.28 zero, ra
565565
; RV32-ZICFISS-NEXT: ret
566566
;
567567
; RV64-ZICFISS-LABEL: f4_hw:
568568
; RV64-ZICFISS: # %bb.0:
569-
; RV64-ZICFISS-NEXT: sspush ra
569+
; RV64-ZICFISS-NEXT: mop.rr.7 zero, zero, ra
570570
; RV64-ZICFISS-NEXT: addi sp, sp, -32
571571
; RV64-ZICFISS-NEXT: .cfi_def_cfa_offset 32
572572
; RV64-ZICFISS-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
@@ -597,7 +597,7 @@ define i32 @f4_hw() "hw-shadow-stack" {
597597
; RV64-ZICFISS-NEXT: .cfi_restore s2
598598
; RV64-ZICFISS-NEXT: addi sp, sp, 32
599599
; RV64-ZICFISS-NEXT: .cfi_def_cfa_offset 0
600-
; RV64-ZICFISS-NEXT: sspopchk ra
600+
; RV64-ZICFISS-NEXT: mop.r.28 zero, ra
601601
; RV64-ZICFISS-NEXT: ret
602602
%res1 = call i32 @bar()
603603
%res2 = call i32 @bar()
@@ -630,24 +630,24 @@ define i32 @f5_hw() "hw-shadow-stack" nounwind {
630630
;
631631
; RV32-ZICFISS-LABEL: f5_hw:
632632
; RV32-ZICFISS: # %bb.0:
633-
; RV32-ZICFISS-NEXT: sspush ra
633+
; RV32-ZICFISS-NEXT: mop.rr.7 zero, zero, ra
634634
; RV32-ZICFISS-NEXT: addi sp, sp, -16
635635
; RV32-ZICFISS-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
636636
; RV32-ZICFISS-NEXT: call bar
637637
; RV32-ZICFISS-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
638638
; RV32-ZICFISS-NEXT: addi sp, sp, 16
639-
; RV32-ZICFISS-NEXT: sspopchk ra
639+
; RV32-ZICFISS-NEXT: mop.r.28 zero, ra
640640
; RV32-ZICFISS-NEXT: ret
641641
;
642642
; RV64-ZICFISS-LABEL: f5_hw:
643643
; RV64-ZICFISS: # %bb.0:
644-
; RV64-ZICFISS-NEXT: sspush ra
644+
; RV64-ZICFISS-NEXT: mop.rr.7 zero, zero, ra
645645
; RV64-ZICFISS-NEXT: addi sp, sp, -16
646646
; RV64-ZICFISS-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
647647
; RV64-ZICFISS-NEXT: call bar
648648
; RV64-ZICFISS-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
649649
; RV64-ZICFISS-NEXT: addi sp, sp, 16
650-
; RV64-ZICFISS-NEXT: sspopchk ra
650+
; RV64-ZICFISS-NEXT: mop.r.28 zero, ra
651651
; RV64-ZICFISS-NEXT: ret
652652
%res = call i32 @bar()
653653
%res1 = add i32 %res, 1
@@ -734,7 +734,7 @@ define i32 @f3_both() "hw-shadow-stack" shadowcallstack {
734734
;
735735
; RV32-ZICFISS-LABEL: f3_both:
736736
; RV32-ZICFISS: # %bb.0:
737-
; RV32-ZICFISS-NEXT: sspush ra
737+
; RV32-ZICFISS-NEXT: mop.rr.7 zero, zero, ra
738738
; RV32-ZICFISS-NEXT: addi sp, sp, -16
739739
; RV32-ZICFISS-NEXT: .cfi_def_cfa_offset 16
740740
; RV32-ZICFISS-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
@@ -744,12 +744,12 @@ define i32 @f3_both() "hw-shadow-stack" shadowcallstack {
744744
; RV32-ZICFISS-NEXT: .cfi_restore ra
745745
; RV32-ZICFISS-NEXT: addi sp, sp, 16
746746
; RV32-ZICFISS-NEXT: .cfi_def_cfa_offset 0
747-
; RV32-ZICFISS-NEXT: sspopchk ra
747+
; RV32-ZICFISS-NEXT: mop.r.28 zero, ra
748748
; RV32-ZICFISS-NEXT: ret
749749
;
750750
; RV64-ZICFISS-LABEL: f3_both:
751751
; RV64-ZICFISS: # %bb.0:
752-
; RV64-ZICFISS-NEXT: sspush ra
752+
; RV64-ZICFISS-NEXT: mop.rr.7 zero, zero, ra
753753
; RV64-ZICFISS-NEXT: addi sp, sp, -16
754754
; RV64-ZICFISS-NEXT: .cfi_def_cfa_offset 16
755755
; RV64-ZICFISS-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
@@ -759,7 +759,7 @@ define i32 @f3_both() "hw-shadow-stack" shadowcallstack {
759759
; RV64-ZICFISS-NEXT: .cfi_restore ra
760760
; RV64-ZICFISS-NEXT: addi sp, sp, 16
761761
; RV64-ZICFISS-NEXT: .cfi_def_cfa_offset 0
762-
; RV64-ZICFISS-NEXT: sspopchk ra
762+
; RV64-ZICFISS-NEXT: mop.r.28 zero, ra
763763
; RV64-ZICFISS-NEXT: ret
764764
%res = call i32 @bar()
765765
%res1 = add i32 %res, 1
@@ -849,7 +849,7 @@ define i32 @f4_both() "hw-shadow-stack" shadowcallstack {
849849
;
850850
; RV32-ZICFISS-LABEL: f4_both:
851851
; RV32-ZICFISS: # %bb.0:
852-
; RV32-ZICFISS-NEXT: sspush ra
852+
; RV32-ZICFISS-NEXT: mop.rr.7 zero, zero, ra
853853
; RV32-ZICFISS-NEXT: addi sp, sp, -16
854854
; RV32-ZICFISS-NEXT: .cfi_def_cfa_offset 16
855855
; RV32-ZICFISS-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
@@ -880,12 +880,12 @@ define i32 @f4_both() "hw-shadow-stack" shadowcallstack {
880880
; RV32-ZICFISS-NEXT: .cfi_restore s2
881881
; RV32-ZICFISS-NEXT: addi sp, sp, 16
882882
; RV32-ZICFISS-NEXT: .cfi_def_cfa_offset 0
883-
; RV32-ZICFISS-NEXT: sspopchk ra
883+
; RV32-ZICFISS-NEXT: mop.r.28 zero, ra
884884
; RV32-ZICFISS-NEXT: ret
885885
;
886886
; RV64-ZICFISS-LABEL: f4_both:
887887
; RV64-ZICFISS: # %bb.0:
888-
; RV64-ZICFISS-NEXT: sspush ra
888+
; RV64-ZICFISS-NEXT: mop.rr.7 zero, zero, ra
889889
; RV64-ZICFISS-NEXT: addi sp, sp, -32
890890
; RV64-ZICFISS-NEXT: .cfi_def_cfa_offset 32
891891
; RV64-ZICFISS-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
@@ -916,7 +916,7 @@ define i32 @f4_both() "hw-shadow-stack" shadowcallstack {
916916
; RV64-ZICFISS-NEXT: .cfi_restore s2
917917
; RV64-ZICFISS-NEXT: addi sp, sp, 32
918918
; RV64-ZICFISS-NEXT: .cfi_def_cfa_offset 0
919-
; RV64-ZICFISS-NEXT: sspopchk ra
919+
; RV64-ZICFISS-NEXT: mop.r.28 zero, ra
920920
; RV64-ZICFISS-NEXT: ret
921921
%res1 = call i32 @bar()
922922
%res2 = call i32 @bar()
@@ -957,24 +957,24 @@ define i32 @f5_both() "hw-shadow-stack" shadowcallstack nounwind {
957957
;
958958
; RV32-ZICFISS-LABEL: f5_both:
959959
; RV32-ZICFISS: # %bb.0:
960-
; RV32-ZICFISS-NEXT: sspush ra
960+
; RV32-ZICFISS-NEXT: mop.rr.7 zero, zero, ra
961961
; RV32-ZICFISS-NEXT: addi sp, sp, -16
962962
; RV32-ZICFISS-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
963963
; RV32-ZICFISS-NEXT: call bar
964964
; RV32-ZICFISS-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
965965
; RV32-ZICFISS-NEXT: addi sp, sp, 16
966-
; RV32-ZICFISS-NEXT: sspopchk ra
966+
; RV32-ZICFISS-NEXT: mop.r.28 zero, ra
967967
; RV32-ZICFISS-NEXT: ret
968968
;
969969
; RV64-ZICFISS-LABEL: f5_both:
970970
; RV64-ZICFISS: # %bb.0:
971-
; RV64-ZICFISS-NEXT: sspush ra
971+
; RV64-ZICFISS-NEXT: mop.rr.7 zero, zero, ra
972972
; RV64-ZICFISS-NEXT: addi sp, sp, -16
973973
; RV64-ZICFISS-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
974974
; RV64-ZICFISS-NEXT: call bar
975975
; RV64-ZICFISS-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
976976
; RV64-ZICFISS-NEXT: addi sp, sp, 16
977-
; RV64-ZICFISS-NEXT: sspopchk ra
977+
; RV64-ZICFISS-NEXT: mop.r.28 zero, ra
978978
; RV64-ZICFISS-NEXT: ret
979979
%res = call i32 @bar()
980980
%res1 = add i32 %res, 1

0 commit comments

Comments
 (0)