Skip to content

Commit c468929

Browse files
author
Yeting Kuo
committed
[RISCV] Use software guarded branch for indirect jump table branch.
When Zicfilp enabled, indirect jump table branch should be a software guarded branch.
1 parent 59c3dca commit c468929

File tree

5 files changed

+145
-0
lines changed

5 files changed

+145
-0
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18741,6 +18741,20 @@ unsigned RISCVTargetLowering::getCustomCtpopCost(EVT VT,
1874118741
return isCtpopFast(VT) ? 0 : 1;
1874218742
}
1874318743

18744+
SDValue RISCVTargetLowering::expandIndirectJTBranch(const SDLoc &dl,
18745+
SDValue Value, SDValue Addr,
18746+
int JTI,
18747+
SelectionDAG &DAG) const {
18748+
if (Subtarget.hasStdExtZicfilp()) {
18749+
// When Zicfilp enabled, we need to use software guarded branch for jump
18750+
// table branch.
18751+
SDValue JTInfo = DAG.getJumpTableDebugInfo(JTI, Value, dl);
18752+
return DAG.getNode(RISCVISD::SW_GUARDED_BRIND, dl, MVT::Other, JTInfo,
18753+
Addr);
18754+
}
18755+
return TargetLowering::expandIndirectJTBranch(dl, Value, Addr, JTI, DAG);
18756+
}
18757+
1874418758
namespace llvm::RISCVVIntrinsicsTable {
1874518759

1874618760
#define GET_RISCVVIntrinsicsTable_IMPL

llvm/lib/Target/RISCV/RISCVISelLowering.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,10 @@ enum NodeType : unsigned {
387387
CZERO_EQZ, // vt.maskc for XVentanaCondOps.
388388
CZERO_NEZ, // vt.maskcn for XVentanaCondOps.
389389

390+
/// Software guarded BRIND node. Operand 0 is the chain operand and
391+
/// operand 1 is the target address.
392+
SW_GUARDED_BRIND,
393+
390394
// FP to 32 bit int conversions for RV64. These are used to keep track of the
391395
// result being sign extended to 64 bit. These saturate out of range inputs.
392396
STRICT_FCVT_W_RV64 = ISD::FIRST_TARGET_STRICTFP_OPCODE,
@@ -815,6 +819,10 @@ class RISCVTargetLowering : public TargetLowering {
815819

816820
bool supportKCFIBundles() const override { return true; }
817821

822+
SDValue expandIndirectJTBranch(const SDLoc &dl, SDValue Value, SDValue Addr,
823+
int JTI, SelectionDAG &DAG) const override;
824+
825+
818826
MachineInstr *EmitKCFICheck(MachineBasicBlock &MBB,
819827
MachineBasicBlock::instr_iterator &MBBI,
820828
const TargetInstrInfo *TII) const override;

llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ def SDT_RISCVIntBinOpW : SDTypeProfile<1, 2, [
4444
def SDT_RISCVIntShiftDOpW : SDTypeProfile<1, 3, [
4545
SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<0, i64>, SDTCisVT<3, i64>
4646
]>;
47+
def SDT_RISCVSWGuardedBrind : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;
4748

4849
// Target-independent nodes, but with target-specific formats.
4950
def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_CallSeqStart,
@@ -67,6 +68,8 @@ def riscv_brcc : SDNode<"RISCVISD::BR_CC", SDT_RISCVBrCC,
6768
def riscv_tail : SDNode<"RISCVISD::TAIL", SDT_RISCVCall,
6869
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
6970
SDNPVariadic]>;
71+
def riscv_sw_guarded_brind : SDNode<"RISCVISD::SW_GUARDED_BRIND",
72+
SDT_RISCVSWGuardedBrind, [SDNPHasChain]>;
7073
def riscv_sllw : SDNode<"RISCVISD::SLLW", SDT_RISCVIntBinOpW>;
7174
def riscv_sraw : SDNode<"RISCVISD::SRAW", SDT_RISCVIntBinOpW>;
7275
def riscv_srlw : SDNode<"RISCVISD::SRLW", SDT_RISCVIntBinOpW>;
@@ -1554,6 +1557,13 @@ let isBarrier = 1, isBranch = 1, isIndirectBranch = 1, isTerminator = 1 in
15541557
def PseudoBRIND : Pseudo<(outs), (ins GPRJALR:$rs1, simm12:$imm12), []>,
15551558
PseudoInstExpansion<(JALR X0, GPR:$rs1, simm12:$imm12)>;
15561559

1560+
let Predicates = [HasStdExtZicfilp] in {
1561+
let isBarrier = 1, isBranch = 1, isIndirectBranch = 1, isTerminator = 1 in
1562+
def PseudoBRINDX7 : Pseudo<(outs), (ins GPRX7:$rs1, simm12:$imm12), []>,
1563+
PseudoInstExpansion<(JALR X0, GPR:$rs1, simm12:$imm12)>;
1564+
1565+
}
1566+
15571567
def : Pat<(brind GPRJALR:$rs1), (PseudoBRIND GPRJALR:$rs1, 0)>;
15581568
def : Pat<(brind (add GPRJALR:$rs1, simm12:$imm12)),
15591569
(PseudoBRIND GPRJALR:$rs1, simm12:$imm12)>;
@@ -1945,6 +1955,12 @@ def : Pat<(binop_allwusers<add> GPR:$rs1, (AddiPair:$rs2)),
19451955
(AddiPairImmSmall AddiPair:$rs2))>;
19461956
}
19471957

1958+
let Predicates = [HasStdExtZicfilp] in {
1959+
def : Pat<(riscv_sw_guarded_brind GPRX7:$rs1), (PseudoBRINDX7 GPRX7:$rs1, 0)>;
1960+
def : Pat<(riscv_sw_guarded_brind (add GPRX7:$rs1, simm12:$imm12)),
1961+
(PseudoBRINDX7 GPRX7:$rs1, simm12:$imm12)>;
1962+
}
1963+
19481964
//===----------------------------------------------------------------------===//
19491965
// Standard extensions
19501966
//===----------------------------------------------------------------------===//

llvm/lib/Target/RISCV/RISCVRegisterInfo.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ def GPRNoX0 : GPRRegisterClass<(sub GPR, X0)>;
142142

143143
def GPRNoX0X2 : GPRRegisterClass<(sub GPR, X0, X2)>;
144144

145+
def GPRX7 : GPRRegisterClass<(add X7)>;
146+
145147
// Don't use X1 or X5 for JALR since that is a hint to pop the return address
146148
// stack on some microarchitectures. Also remove the reserved registers X0, X2,
147149
// X3, and X4 as it reduces the number of register classes that get synthesized
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple riscv32 -mattr=+experimental-zicfilp < %s | FileCheck %s
3+
; RUN: llc -mtriple riscv64 -mattr=+experimental-zicfilp < %s | FileCheck %s
4+
; RUN: llc -mtriple riscv32 < %s | FileCheck %s --check-prefix=NO-ZICFILP
5+
; RUN: llc -mtriple riscv64 < %s | FileCheck %s --check-prefix=NO-ZICFILP
6+
7+
; Test using t2 to jump table branch.
8+
define void @above_threshold(i32 signext %in, ptr %out) nounwind {
9+
; CHECK-LABEL: above_threshold:
10+
; CHECK: # %bb.0: # %entry
11+
; CHECK-NEXT: addi a0, a0, -1
12+
; CHECK-NEXT: li a2, 5
13+
; CHECK-NEXT: bltu a2, a0, .LBB0_9
14+
; CHECK-NEXT: # %bb.1: # %entry
15+
; CHECK-NEXT: slli a0, a0, 2
16+
; CHECK-NEXT: lui a2, %hi(.LJTI0_0)
17+
; CHECK-NEXT: addi a2, a2, %lo(.LJTI0_0)
18+
; CHECK-NEXT: add a0, a0, a2
19+
; CHECK-NEXT: lw t2, 0(a0)
20+
; CHECK-NEXT: jr t2
21+
; CHECK-NEXT: .LBB0_2: # %bb1
22+
; CHECK-NEXT: li a0, 4
23+
; CHECK-NEXT: j .LBB0_8
24+
; CHECK-NEXT: .LBB0_3: # %bb2
25+
; CHECK-NEXT: li a0, 3
26+
; CHECK-NEXT: j .LBB0_8
27+
; CHECK-NEXT: .LBB0_4: # %bb3
28+
; CHECK-NEXT: li a0, 2
29+
; CHECK-NEXT: j .LBB0_8
30+
; CHECK-NEXT: .LBB0_5: # %bb4
31+
; CHECK-NEXT: li a0, 1
32+
; CHECK-NEXT: j .LBB0_8
33+
; CHECK-NEXT: .LBB0_6: # %bb5
34+
; CHECK-NEXT: li a0, 100
35+
; CHECK-NEXT: j .LBB0_8
36+
; CHECK-NEXT: .LBB0_7: # %bb6
37+
; CHECK-NEXT: li a0, 200
38+
; CHECK-NEXT: .LBB0_8: # %exit
39+
; CHECK-NEXT: sw a0, 0(a1)
40+
; CHECK-NEXT: .LBB0_9: # %exit
41+
; CHECK-NEXT: ret
42+
;
43+
; NO-ZICFILP-LABEL: above_threshold:
44+
; NO-ZICFILP: # %bb.0: # %entry
45+
; NO-ZICFILP-NEXT: addi a0, a0, -1
46+
; NO-ZICFILP-NEXT: li a2, 5
47+
; NO-ZICFILP-NEXT: bltu a2, a0, .LBB0_9
48+
; NO-ZICFILP-NEXT: # %bb.1: # %entry
49+
; NO-ZICFILP-NEXT: slli a0, a0, 2
50+
; NO-ZICFILP-NEXT: lui a2, %hi(.LJTI0_0)
51+
; NO-ZICFILP-NEXT: addi a2, a2, %lo(.LJTI0_0)
52+
; NO-ZICFILP-NEXT: add a0, a0, a2
53+
; NO-ZICFILP-NEXT: lw a0, 0(a0)
54+
; NO-ZICFILP-NEXT: jr a0
55+
; NO-ZICFILP-NEXT: .LBB0_2: # %bb1
56+
; NO-ZICFILP-NEXT: li a0, 4
57+
; NO-ZICFILP-NEXT: j .LBB0_8
58+
; NO-ZICFILP-NEXT: .LBB0_3: # %bb2
59+
; NO-ZICFILP-NEXT: li a0, 3
60+
; NO-ZICFILP-NEXT: j .LBB0_8
61+
; NO-ZICFILP-NEXT: .LBB0_4: # %bb3
62+
; NO-ZICFILP-NEXT: li a0, 2
63+
; NO-ZICFILP-NEXT: j .LBB0_8
64+
; NO-ZICFILP-NEXT: .LBB0_5: # %bb4
65+
; NO-ZICFILP-NEXT: li a0, 1
66+
; NO-ZICFILP-NEXT: j .LBB0_8
67+
; NO-ZICFILP-NEXT: .LBB0_6: # %bb5
68+
; NO-ZICFILP-NEXT: li a0, 100
69+
; NO-ZICFILP-NEXT: j .LBB0_8
70+
; NO-ZICFILP-NEXT: .LBB0_7: # %bb6
71+
; NO-ZICFILP-NEXT: li a0, 200
72+
; NO-ZICFILP-NEXT: .LBB0_8: # %exit
73+
; NO-ZICFILP-NEXT: sw a0, 0(a1)
74+
; NO-ZICFILP-NEXT: .LBB0_9: # %exit
75+
; NO-ZICFILP-NEXT: ret
76+
entry:
77+
switch i32 %in, label %exit [
78+
i32 1, label %bb1
79+
i32 2, label %bb2
80+
i32 3, label %bb3
81+
i32 4, label %bb4
82+
i32 5, label %bb5
83+
i32 6, label %bb6
84+
]
85+
bb1:
86+
store i32 4, ptr %out
87+
br label %exit
88+
bb2:
89+
store i32 3, ptr %out
90+
br label %exit
91+
bb3:
92+
store i32 2, ptr %out
93+
br label %exit
94+
bb4:
95+
store i32 1, ptr %out
96+
br label %exit
97+
bb5:
98+
store i32 100, ptr %out
99+
br label %exit
100+
bb6:
101+
store i32 200, ptr %out
102+
br label %exit
103+
exit:
104+
ret void
105+
}

0 commit comments

Comments
 (0)