Skip to content

Commit 59090aa

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 df91cde commit 59090aa

File tree

5 files changed

+146
-1
lines changed

5 files changed

+146
-1
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21547,6 +21547,20 @@ MCPhysReg RVVArgDispatcher::getNextPhysReg() {
2154721547
return AllocatedPhysRegs[CurIdx++];
2154821548
}
2154921549

21550+
SDValue RISCVTargetLowering::expandIndirectJTBranch(const SDLoc &dl,
21551+
SDValue Value, SDValue Addr,
21552+
int JTI,
21553+
SelectionDAG &DAG) const {
21554+
if (Subtarget.hasStdExtZicfilp()) {
21555+
// When Zicfilp enabled, we need to use software guarded branch for jump
21556+
// table branch.
21557+
SDValue JTInfo = DAG.getJumpTableDebugInfo(JTI, Value, dl);
21558+
return DAG.getNode(RISCVISD::SW_GUARDED_BRIND, dl, MVT::Other, JTInfo,
21559+
Addr);
21560+
}
21561+
return TargetLowering::expandIndirectJTBranch(dl, Value, Addr, JTI, DAG);
21562+
}
21563+
2155021564
namespace llvm::RISCVVIntrinsicsTable {
2155121565

2155221566
#define GET_RISCVVIntrinsicsTable_IMPL

llvm/lib/Target/RISCV/RISCVISelLowering.h

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

403+
/// Software guarded BRIND node. Operand 0 is the chain operand and
404+
/// operand 1 is the target address.
405+
SW_GUARDED_BRIND,
406+
403407
// FP to 32 bit int conversions for RV64. These are used to keep track of the
404408
// result being sign extended to 64 bit. These saturate out of range inputs.
405409
STRICT_FCVT_W_RV64 = ISD::FIRST_TARGET_STRICTFP_OPCODE,
@@ -869,6 +873,10 @@ class RISCVTargetLowering : public TargetLowering {
869873

870874
bool supportKCFIBundles() const override { return true; }
871875

876+
SDValue expandIndirectJTBranch(const SDLoc &dl, SDValue Value, SDValue Addr,
877+
int JTI, SelectionDAG &DAG) const override;
878+
879+
872880
MachineInstr *EmitKCFICheck(MachineBasicBlock &MBB,
873881
MachineBasicBlock::instr_iterator &MBBI,
874882
const TargetInstrInfo *TII) const override;

llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def SDT_RISCVIntBinOpW : SDTypeProfile<1, 2, [
4646
def SDT_RISCVIntShiftDOpW : SDTypeProfile<1, 3, [
4747
SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<0, i64>, SDTCisVT<3, i64>
4848
]>;
49+
def SDT_RISCVSWGuardedBrind : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;
4950

5051
// Target-independent nodes, but with target-specific formats.
5152
def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_CallSeqStart,
@@ -69,6 +70,8 @@ def riscv_brcc : SDNode<"RISCVISD::BR_CC", SDT_RISCVBrCC,
6970
def riscv_tail : SDNode<"RISCVISD::TAIL", SDT_RISCVCall,
7071
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
7172
SDNPVariadic]>;
73+
def riscv_sw_guarded_brind : SDNode<"RISCVISD::SW_GUARDED_BRIND",
74+
SDT_RISCVSWGuardedBrind, [SDNPHasChain]>;
7275
def riscv_sllw : SDNode<"RISCVISD::SLLW", SDT_RISCVIntBinOpW>;
7376
def riscv_sraw : SDNode<"RISCVISD::SRAW", SDT_RISCVIntBinOpW>;
7477
def riscv_srlw : SDNode<"RISCVISD::SRLW", SDT_RISCVIntBinOpW>;
@@ -1454,16 +1457,23 @@ def PseudoBRIND : Pseudo<(outs), (ins GPRJALR:$rs1, simm12:$imm12), []>,
14541457
PseudoInstExpansion<(JALR X0, GPR:$rs1, simm12:$imm12)>;
14551458

14561459
let Predicates = [HasStdExtZicfilp],
1457-
isBarrier = 1, isBranch = 1, isIndirectBranch = 1, isTerminator = 1 in
1460+
isBarrier = 1, isBranch = 1, isIndirectBranch = 1, isTerminator = 1 in {
14581461
def PseudoBRINDNonX7 : Pseudo<(outs), (ins GPRJALRNonX7:$rs1, simm12:$imm12), []>,
14591462
PseudoInstExpansion<(JALR X0, GPR:$rs1, simm12:$imm12)>;
1463+
def PseudoBRINDX7 : Pseudo<(outs), (ins GPRX7:$rs1, simm12:$imm12), []>,
1464+
PseudoInstExpansion<(JALR X0, GPR:$rs1, simm12:$imm12)>;
1465+
}
14601466

14611467
// For Zicfilp, need to avoid using X7/T2 for indirect branches which need
14621468
// landing pad.
14631469
let Predicates = [HasStdExtZicfilp] in {
14641470
def : Pat<(brind GPRJALRNonX7:$rs1), (PseudoBRINDNonX7 GPRJALRNonX7:$rs1, 0)>;
14651471
def : Pat<(brind (add GPRJALRNonX7:$rs1, simm12:$imm12)),
14661472
(PseudoBRINDNonX7 GPRJALRNonX7:$rs1, simm12:$imm12)>;
1473+
1474+
def : Pat<(riscv_sw_guarded_brind GPRX7:$rs1), (PseudoBRINDX7 GPRX7:$rs1, 0)>;
1475+
def : Pat<(riscv_sw_guarded_brind (add GPRX7:$rs1, simm12:$imm12)),
1476+
(PseudoBRINDX7 GPRX7:$rs1, simm12:$imm12)>;
14671477
}
14681478

14691479
let Predicates = [NoStdExtZicfilp] in {
@@ -1916,6 +1926,12 @@ def : Pat<(binop_allwusers<add> GPR:$rs1, (AddiPair:$rs2)),
19161926
(AddiPairImmSmall AddiPair:$rs2))>;
19171927
}
19181928

1929+
let Predicates = [HasStdExtZicfilp] in {
1930+
def : Pat<(riscv_sw_guarded_brind GPRX7:$rs1), (PseudoBRINDX7 GPRX7:$rs1, 0)>;
1931+
def : Pat<(riscv_sw_guarded_brind (add GPRX7:$rs1, simm12:$imm12)),
1932+
(PseudoBRINDX7 GPRX7:$rs1, simm12:$imm12)>;
1933+
}
1934+
19191935
//===----------------------------------------------------------------------===//
19201936
// Experimental RV64 i32 legalization patterns.
19211937
//===----------------------------------------------------------------------===//

llvm/lib/Target/RISCV/RISCVRegisterInfo.td

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

168168
def GPRNoX0X2 : GPRRegisterClass<(sub GPR, X0, X2)>;
169169

170+
def GPRX7 : GPRRegisterClass<(add X7)>;
171+
170172
// Don't use X1 or X5 for JALR since that is a hint to pop the return address
171173
// stack on some microarchitectures. Also remove the reserved registers X0, X2,
172174
// 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: # %bb5
25+
; CHECK-NEXT: li a0, 100
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: # %bb2
34+
; CHECK-NEXT: li a0, 3
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: # %bb5
59+
; NO-ZICFILP-NEXT: li a0, 100
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: # %bb2
68+
; NO-ZICFILP-NEXT: li a0, 3
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)