Skip to content

Commit 0644909

Browse files
authored
[RISCV] Avoid using x7/t2 for indirect branches which need landing pad. (#68292)
When Zicfilp enabled, this avoids selecting indirect jumps to PseudoBRIND/PseudoCALLIndirect/PseudoTAILIndirect, since they may uses X7 as rs1 and be identified as a software guarded jump. There is an another PR #66762 to use software guarded jump for jumptable branch.
1 parent 3d65bd9 commit 0644909

File tree

5 files changed

+86
-3
lines changed

5 files changed

+86
-3
lines changed

llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,9 @@ RISCVRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
117117
case RISCV::GPRNoX0RegClassID:
118118
case RISCV::GPRNoX0X2RegClassID:
119119
case RISCV::GPRJALRRegClassID:
120+
case RISCV::GPRJALRNonX7RegClassID:
120121
case RISCV::GPRTCRegClassID:
122+
case RISCV::GPRTCNonX7RegClassID:
121123
case RISCV::GPRC_and_GPRTCRegClassID:
122124
case RISCV::GPRCRegClassID:
123125
case RISCV::GPRC_and_SR07RegClassID:

llvm/lib/Target/RISCV/RISCVFeatures.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ def FeatureStdExtZicfilp
156156
def HasStdExtZicfilp : Predicate<"Subtarget->hasStdExtZicfilp()">,
157157
AssemblerPredicate<(all_of FeatureStdExtZicfilp),
158158
"'Zicfilp' (Landing pad)">;
159+
def NoStdExtZicfilp : Predicate<"!Subtarget->hasStdExtZicfilp()">,
160+
AssemblerPredicate<(all_of (not FeatureStdExtZicfilp))>;
159161

160162
def FeatureStdExtZicfiss
161163
: RISCVExperimentalExtension<"zicfiss", 0, 4,

llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,13 +1448,29 @@ let isBarrier = 1, isBranch = 1, isTerminator = 1 in
14481448
def PseudoBR : Pseudo<(outs), (ins simm21_lsb0_jal:$imm20), [(br bb:$imm20)]>,
14491449
PseudoInstExpansion<(JAL X0, simm21_lsb0_jal:$imm20)>;
14501450

1451-
let isBarrier = 1, isBranch = 1, isIndirectBranch = 1, isTerminator = 1 in
1451+
let Predicates = [NoStdExtZicfilp],
1452+
isBarrier = 1, isBranch = 1, isIndirectBranch = 1, isTerminator = 1 in
14521453
def PseudoBRIND : Pseudo<(outs), (ins GPRJALR:$rs1, simm12:$imm12), []>,
14531454
PseudoInstExpansion<(JALR X0, GPR:$rs1, simm12:$imm12)>;
14541455

1456+
let Predicates = [HasStdExtZicfilp],
1457+
isBarrier = 1, isBranch = 1, isIndirectBranch = 1, isTerminator = 1 in
1458+
def PseudoBRINDNonX7 : Pseudo<(outs), (ins GPRJALRNonX7:$rs1, simm12:$imm12), []>,
1459+
PseudoInstExpansion<(JALR X0, GPR:$rs1, simm12:$imm12)>;
1460+
1461+
// For Zicfilp, need to avoid using X7/T2 for indirect branches which need
1462+
// landing pad.
1463+
let Predicates = [HasStdExtZicfilp] in {
1464+
def : Pat<(brind GPRJALRNonX7:$rs1), (PseudoBRINDNonX7 GPRJALRNonX7:$rs1, 0)>;
1465+
def : Pat<(brind (add GPRJALRNonX7:$rs1, simm12:$imm12)),
1466+
(PseudoBRINDNonX7 GPRJALRNonX7:$rs1, simm12:$imm12)>;
1467+
}
1468+
1469+
let Predicates = [NoStdExtZicfilp] in {
14551470
def : Pat<(brind GPRJALR:$rs1), (PseudoBRIND GPRJALR:$rs1, 0)>;
14561471
def : Pat<(brind (add GPRJALR:$rs1, simm12:$imm12)),
14571472
(PseudoBRIND GPRJALR:$rs1, simm12:$imm12)>;
1473+
}
14581474

14591475
// PseudoCALLReg is a generic pseudo instruction for calls which will eventually
14601476
// expand to auipc and jalr while encoding, with any given register used as the
@@ -1484,10 +1500,16 @@ def : Pat<(riscv_call texternalsym:$func), (PseudoCALL texternalsym:$func)>;
14841500
def : Pat<(riscv_sret_glue), (SRET (XLenVT X0), (XLenVT X0))>;
14851501
def : Pat<(riscv_mret_glue), (MRET (XLenVT X0), (XLenVT X0))>;
14861502

1487-
let isCall = 1, Defs = [X1] in
1503+
let isCall = 1, Defs = [X1] in {
1504+
let Predicates = [NoStdExtZicfilp] in
14881505
def PseudoCALLIndirect : Pseudo<(outs), (ins GPRJALR:$rs1),
14891506
[(riscv_call GPRJALR:$rs1)]>,
14901507
PseudoInstExpansion<(JALR X1, GPR:$rs1, 0)>;
1508+
let Predicates = [HasStdExtZicfilp] in
1509+
def PseudoCALLIndirectNonX7 : Pseudo<(outs), (ins GPRJALRNonX7:$rs1),
1510+
[(riscv_call GPRJALRNonX7:$rs1)]>,
1511+
PseudoInstExpansion<(JALR X1, GPR:$rs1, 0)>;
1512+
}
14911513

14921514
let isBarrier = 1, isReturn = 1, isTerminator = 1 in
14931515
def PseudoRET : Pseudo<(outs), (ins), [(riscv_ret_glue)]>,
@@ -1502,10 +1524,16 @@ def PseudoTAIL : Pseudo<(outs), (ins call_symbol:$dst), [],
15021524
"tail", "$dst">,
15031525
Sched<[WriteIALU, WriteJalr, ReadJalr]>;
15041526

1505-
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [X2] in
1527+
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [X2] in {
1528+
let Predicates = [NoStdExtZicfilp] in
15061529
def PseudoTAILIndirect : Pseudo<(outs), (ins GPRTC:$rs1),
15071530
[(riscv_tail GPRTC:$rs1)]>,
15081531
PseudoInstExpansion<(JALR X0, GPR:$rs1, 0)>;
1532+
let Predicates = [HasStdExtZicfilp] in
1533+
def PseudoTAILIndirectNonX7 : Pseudo<(outs), (ins GPRTCNonX7:$rs1),
1534+
[(riscv_tail GPRTCNonX7:$rs1)]>,
1535+
PseudoInstExpansion<(JALR X0, GPR:$rs1, 0)>;
1536+
}
15091537

15101538
def : Pat<(riscv_tail (iPTR tglobaladdr:$dst)),
15111539
(PseudoTAIL tglobaladdr:$dst)>;

llvm/lib/Target/RISCV/RISCVRegisterInfo.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ def GPRNoX0X2 : GPRRegisterClass<(sub GPR, X0, X2)>;
173173
// by tablegen.
174174
def GPRJALR : GPRRegisterClass<(sub GPR, (sequence "X%u", 0, 5))>;
175175

176+
def GPRJALRNonX7 : GPRRegisterClass<(sub GPRJALR, X7)>;
177+
176178
def GPRC : GPRRegisterClass<(add (sequence "X%u", 10, 15),
177179
(sequence "X%u", 8, 9))>;
178180

@@ -183,6 +185,7 @@ def GPRC : GPRRegisterClass<(add (sequence "X%u", 10, 15),
183185
def GPRTC : GPRRegisterClass<(add (sequence "X%u", 6, 7),
184186
(sequence "X%u", 10, 17),
185187
(sequence "X%u", 28, 31))>;
188+
def GPRTCNonX7 : GPRRegisterClass<(sub GPRTC, X7)>;
186189

187190
def SP : GPRRegisterClass<(add X2)>;
188191

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3
2+
; RUN: llc -mtriple=riscv64 -stop-after=finalize-isel < %s | FileCheck %s
3+
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zicfilp -stop-after=finalize-isel < %s | FileCheck -check-prefixes=ZICFILP %s
4+
5+
@brind.arr = internal unnamed_addr constant [2 x ptr] [ptr blockaddress(@brind, %5), ptr blockaddress(@brind, %8)], align 8
6+
@x = dso_local global i32 0, align 4
7+
8+
define void @brind(i32 noundef signext %0) {
9+
; CHECK-LABEL: name: brind
10+
; CHECK: PseudoBRIND killed [[VAR:%.*]], 0
11+
; ZICFILP-LABEL: name: brind
12+
; ZICFILP: PseudoBRINDNonX7 killed [[VAR:%.*]], 0
13+
%2 = sext i32 %0 to i64
14+
%3 = getelementptr inbounds [2 x ptr], ptr @brind.arr, i64 0, i64 %2
15+
%4 = load ptr, ptr %3, align 8
16+
indirectbr ptr %4, [label %5, label %8]
17+
18+
5: ; preds = %1
19+
%6 = load i32, ptr @x, align 4
20+
%7 = add nsw i32 %6, 2
21+
store i32 %7, ptr @x, align 4
22+
br label %8
23+
24+
8: ; preds = %5, %1
25+
%9 = load i32, ptr @x, align 4
26+
%10 = add nsw i32 %9, 1
27+
store i32 %10, ptr @x, align 4
28+
ret void
29+
}
30+
31+
define i32 @indirect_call(ptr %0) {
32+
; CHECK-LABEL: name: indirect_call
33+
; CHECK: PseudoCALLIndirect
34+
; ZICFILP-LABEL: name: indirect_call
35+
; ZICFILP: PseudoCALLIndirectNonX7
36+
call void %0()
37+
ret i32 0
38+
}
39+
40+
41+
define void @indirect_tail(ptr %0) {
42+
; CHECK-LABEL: name: indirect_tail
43+
; CHECK: PseudoTAILIndirect
44+
; ZICFILP-LABEL: name: indirect_tail
45+
; ZICFILP: PseudoTAILIndirectNonX7
46+
tail call void %0()
47+
ret void
48+
}

0 commit comments

Comments
 (0)