Skip to content

Commit f9f6bba

Browse files
committed
fixup: Model ZICFILP-func-sig and ZICFILP-unlabeled as real features
1 parent cb9940d commit f9f6bba

17 files changed

+120
-64
lines changed

clang/lib/Driver/ToolChains/Arch/RISCV.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,35 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
176176
Features.push_back("+unaligned-vector-mem");
177177
}
178178

179+
if (const Arg *A = Args.getLastArg(options::OPT_fcf_protection_EQ)) {
180+
const StringRef CFProtection{A->getValue()};
181+
const bool CFProtectionBranch =
182+
CFProtection == "full" || CFProtection == "branch";
183+
if (CFProtectionBranch) {
184+
bool FuncSig;
185+
if (const Arg *SA =
186+
Args.getLastArg(options::OPT_mcf_branch_label_scheme_EQ)) {
187+
const StringRef Scheme{SA->getValue()};
188+
if (Scheme == "unlabeled") {
189+
FuncSig = false;
190+
} else {
191+
assert(Scheme == "func-sig" &&
192+
"-mcf-branch-label-scheme should be either `unlabeled` or "
193+
"`func-sig`");
194+
FuncSig = true;
195+
}
196+
} else {
197+
// `func-sig` is assumed if `-mcf-branch-label-scheme` is not given.
198+
FuncSig = true;
199+
}
200+
201+
if (FuncSig)
202+
Features.push_back("+zicfilp-func-sig");
203+
else
204+
Features.push_back("+zicfilp-unlabeled");
205+
}
206+
}
207+
179208
// Now add any that the user explicitly requested on the command line,
180209
// which may override the defaults.
181210
handleTargetFeaturesGroup(D, Triple, Args, Features,

clang/test/Driver/riscv-features.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,21 @@
8585
// FUCHSIA-SAME: "-target-feature" "+zbb"
8686
// FUCHSIA-SAME: "-target-feature" "+zbs"
8787

88+
// RUN: %clang --target=riscv32 -fcf-protection=full -### %s -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=ZICFILP-FUNC-SIG
89+
// RUN: %clang --target=riscv32 -fcf-protection=full -mcf-branch-label-scheme=func-sig -### %s -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=ZICFILP-FUNC-SIG
90+
// RUN: %clang --target=riscv32 -fcf-protection=full -mcf-branch-label-scheme=unlabeled -### %s -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=ZICFILP-UNLABELED
91+
// RUN: %clang --target=riscv32 -fcf-protection=branch -### %s -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=ZICFILP-FUNC-SIG
92+
// RUN: %clang --target=riscv32 -fcf-protection=branch -mcf-branch-label-scheme=func-sig -### %s -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=ZICFILP-FUNC-SIG
93+
// RUN: %clang --target=riscv32 -fcf-protection=branch -mcf-branch-label-scheme=unlabeled -### %s -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=ZICFILP-UNLABELED
94+
// RUN: %clang --target=riscv64 -fcf-protection=full -### %s -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=ZICFILP-FUNC-SIG
95+
// RUN: %clang --target=riscv64 -fcf-protection=full -mcf-branch-label-scheme=func-sig -### %s -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=ZICFILP-FUNC-SIG
96+
// RUN: %clang --target=riscv64 -fcf-protection=full -mcf-branch-label-scheme=unlabeled -### %s -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=ZICFILP-UNLABELED
97+
// RUN: %clang --target=riscv64 -fcf-protection=branch -### %s -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=ZICFILP-FUNC-SIG
98+
// RUN: %clang --target=riscv64 -fcf-protection=branch -mcf-branch-label-scheme=func-sig -### %s -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=ZICFILP-FUNC-SIG
99+
// RUN: %clang --target=riscv64 -fcf-protection=branch -mcf-branch-label-scheme=unlabeled -### %s -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=ZICFILP-UNLABELED
100+
// ZICFILP-FUNC-SIG-NOT: "-target-feature" "-zicfilp-unlabeled"
101+
// ZICFILP-FUNC-SIG: "-target-feature" "+zicfilp-func-sig"
102+
// ZICFILP-FUNC-SIG-NOT: "-target-feature" "-zicfilp-unlabeled"
103+
// ZICFILP-UNLABELED-NOT: "-target-feature" "-zicfilp-func-sig"
104+
// ZICFILP-UNLABELED: "-target-feature" "+zicfilp-unlabeled"
105+
// ZICFILP-UNLABELED-NOT: "-target-feature" "-zicfilp-func-sig"

llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@ void validate(const Triple &TT, const FeatureBitset &FeatureBits) {
134134
if (FeatureBits[RISCV::Feature32Bit] &&
135135
FeatureBits[RISCV::Feature64Bit])
136136
reportFatalUsageError("RV32 and RV64 can't be combined");
137+
if (FeatureBits[RISCV::FeatureZicfilpFuncSig] &&
138+
FeatureBits[RISCV::FeatureZicfilpUnlabeled])
139+
reportFatalUsageError(
140+
"+zicfilp-func-sig and +zicfilp-unlabeled can't be combined");
137141
}
138142

139143
llvm::Expected<std::unique_ptr<RISCVISAInfo>>

llvm/lib/Target/RISCV/RISCVFeatures.td

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,6 @@ def FeatureStdExtZicfilp
170170
def HasStdExtZicfilp : Predicate<"Subtarget->hasStdExtZicfilp()">,
171171
AssemblerPredicate<(all_of FeatureStdExtZicfilp),
172172
"'Zicfilp' (Landing pad)">;
173-
def HasZicfilpCFI : Predicate<"Subtarget->hasZicfilpCFI()">;
174-
def HasNoZicfilpCFI : Predicate<"!Subtarget->hasZicfilpCFI()">;
175173

176174
def FeatureStdExtZicfiss
177175
: RISCVExperimentalExtension<1, 0, "Shadow stack",
@@ -1802,3 +1800,15 @@ def FeatureTaggedGlobals : SubtargetFeature<"tagged-globals",
18021800
"AllowTaggedGlobals",
18031801
"true", "Use an instruction sequence for taking the address of a global "
18041802
"that allows a memory tag in the upper address bits">;
1803+
1804+
// Zicfilp-based CFI
1805+
def FeatureZicfilpUnlabeled
1806+
: SubtargetFeature<
1807+
"zicfilp-unlabeled", "HasZicfilpUnlabeled", "true",
1808+
"Enforce forward-edge control-flow integrity with ZICFILP-unlabeled">;
1809+
def FeatureZicfilpFuncSig
1810+
: SubtargetFeature<
1811+
"zicfilp-func-sig", "HasZicfilpFuncSig", "true",
1812+
"Enforce forward-edge control-flow integrity with ZICFILP-func-sig">;
1813+
def HasZicfilpCFI : Predicate<"Subtarget->hasZicfilpCFI()">;
1814+
def HasNoZicfilpCFI : Predicate<"!Subtarget->hasZicfilpCFI()">;

llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ bool RISCVIndirectBranchTracking::runOnMachineFunction(MachineFunction &MF) {
7070
const RISCVInstrInfo *TII = Subtarget.getInstrInfo();
7171

7272
if (Subtarget.getZicfilpLabelScheme() !=
73-
RISCVSubtarget::ZicfilpLabelSchemeKind::Unlabeled)
73+
RISCVSubtarget::ZicfilpLabelSchemeEnum::Unlabeled)
7474
reportFatalUsageError(
7575
"only cf-branch-label-scheme=unlabeled is supported for now");
7676

llvm/lib/Target/RISCV/RISCVSubtarget.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,9 @@ RISCVSubtarget::RISCVSubtarget(const Triple &TT, StringRef CPU,
9999
StringRef TuneCPU, StringRef FS,
100100
StringRef ABIName, unsigned RVVVectorBitsMin,
101101
unsigned RVVVectorBitsMax,
102-
RISCVSubtarget::ZicfilpLabelSchemeKind Zicfilp,
103102
const TargetMachine &TM)
104103
: RISCVGenSubtargetInfo(TT, CPU, TuneCPU, FS),
105104
RVVVectorBitsMin(RVVVectorBitsMin), RVVVectorBitsMax(RVVVectorBitsMax),
106-
ZicfilpLabelScheme(Zicfilp),
107105
FrameLowering(
108106
initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),
109107
InstrInfo(*this), RegInfo(getHwMode()), TLInfo(TM, *this) {

llvm/lib/Target/RISCV/RISCVSubtarget.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,8 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
9292
};
9393
// clang-format on
9494

95-
enum class ZicfilpLabelSchemeKind {
95+
enum class ZicfilpLabelSchemeEnum {
9696
Disabled,
97-
EnabledUnknown,
9897
Unlabeled,
9998
FuncSig,
10099
};
@@ -115,7 +114,6 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
115114
unsigned RVVVectorBitsMax;
116115
uint8_t MaxInterleaveFactor = 2;
117116
RISCVABI::ABI TargetABI = RISCVABI::ABI_Unknown;
118-
const ZicfilpLabelSchemeKind ZicfilpLabelScheme;
119117
std::bitset<RISCV::NUM_TARGET_REGS> UserReservedRegister;
120118
const RISCVTuneInfoTable::RISCVTuneInfo *TuneInfo;
121119

@@ -136,9 +134,7 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
136134
// Initializes the data members to match that of the specified triple.
137135
RISCVSubtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU,
138136
StringRef FS, StringRef ABIName, unsigned RVVVectorBitsMin,
139-
unsigned RVVVectorLMULMax,
140-
ZicfilpLabelSchemeKind ZicfilpLabelScheme,
141-
const TargetMachine &TM);
137+
unsigned RVVVectorLMULMax, const TargetMachine &TM);
142138

143139
~RISCVSubtarget() override;
144140

@@ -197,11 +193,15 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
197193
return HasStdExtZfhmin || HasStdExtZfbfmin;
198194
}
199195

200-
ZicfilpLabelSchemeKind getZicfilpLabelScheme() const {
201-
return ZicfilpLabelScheme;
196+
ZicfilpLabelSchemeEnum getZicfilpLabelScheme() const {
197+
if (hasZicfilpFuncSig())
198+
return ZicfilpLabelSchemeEnum::FuncSig;
199+
if (hasZicfilpUnlabeled())
200+
return ZicfilpLabelSchemeEnum::Unlabeled;
201+
return ZicfilpLabelSchemeEnum::Disabled;
202202
}
203203
bool hasZicfilpCFI() const {
204-
return getZicfilpLabelScheme() != ZicfilpLabelSchemeKind::Disabled;
204+
return getZicfilpLabelScheme() != ZicfilpLabelSchemeEnum::Disabled;
205205
}
206206

207207
bool hasConditionalMoveFusion() const {

llvm/lib/Target/RISCV/RISCVTargetMachine.cpp

Lines changed: 31 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@
1717
#include "RISCVTargetObjectFile.h"
1818
#include "RISCVTargetTransformInfo.h"
1919
#include "TargetInfo/RISCVTargetInfo.h"
20-
#include "llvm/ADT/STLForwardCompat.h"
2120
#include "llvm/ADT/StringRef.h"
22-
#include "llvm/ADT/StringSwitch.h"
2321
#include "llvm/Analysis/TargetTransformInfo.h"
2422
#include "llvm/CodeGen/GlobalISel/CSEInfo.h"
2523
#include "llvm/CodeGen/GlobalISel/IRTranslator.h"
@@ -46,7 +44,6 @@
4644
#include "llvm/Transforms/Scalar.h"
4745
#include "llvm/Transforms/Vectorize/EVLIndVarSimplify.h"
4846
#include "llvm/Transforms/Vectorize/LoopIdiomVectorize.h"
49-
#include <cassert>
5047
#include <optional>
5148
using namespace llvm;
5249

@@ -253,36 +250,9 @@ RISCVTargetMachine::getSubtargetImpl(const Function &F) const {
253250
RVVBitsMax =
254251
llvm::bit_floor((RVVBitsMax < 64 || RVVBitsMax > 65536) ? 0 : RVVBitsMax);
255252

256-
using ZicfilpLabelSchemeKind = RISCVSubtarget::ZicfilpLabelSchemeKind;
257-
ZicfilpLabelSchemeKind ZicfilpLabelScheme = ZicfilpLabelSchemeKind::Disabled;
258-
if (const Module *const M = F.getParent()) {
259-
if (const Metadata *const Flag = M->getModuleFlag("cf-protection-branch");
260-
Flag && !mdconst::extract<ConstantInt>(Flag)->isZero()) {
261-
StringRef CFBranchLabelScheme;
262-
if (const Metadata *const MD = M->getModuleFlag("cf-branch-label-scheme"))
263-
CFBranchLabelScheme = cast<MDString>(MD)->getString();
264-
else
265-
report_fatal_error("missing cf-branch-label-scheme module flag");
266-
267-
// See clang::getCFBranchLabelSchemeFlagVal() for possible
268-
// CFBranchLabelScheme
269-
ZicfilpLabelScheme =
270-
StringSwitch<ZicfilpLabelSchemeKind>(CFBranchLabelScheme)
271-
.Case("unlabeled", ZicfilpLabelSchemeKind::Unlabeled)
272-
.Case("func-sig", ZicfilpLabelSchemeKind::FuncSig)
273-
.Default(ZicfilpLabelSchemeKind::EnabledUnknown);
274-
assert(ZicfilpLabelScheme != ZicfilpLabelSchemeKind::EnabledUnknown);
275-
}
276-
}
277-
278253
SmallString<512> Key;
279-
{
280-
raw_svector_ostream OS(Key);
281-
OS << "RVVMin" << RVVBitsMin << "RVVMax" << RVVBitsMax;
282-
if (ZicfilpLabelScheme != ZicfilpLabelSchemeKind::Disabled)
283-
OS << "ZicfilpLabelSchemeKind" << to_underlying(ZicfilpLabelScheme);
284-
OS << CPU << TuneCPU << FS;
285-
}
254+
raw_svector_ostream(Key) << "RVVMin" << RVVBitsMin << "RVVMax" << RVVBitsMax
255+
<< CPU << TuneCPU << FS;
286256
auto &I = SubtargetMap[Key];
287257
if (!I) {
288258
// This needs to be done before we create a new subtarget since any
@@ -299,9 +269,35 @@ RISCVTargetMachine::getSubtargetImpl(const Function &F) const {
299269
}
300270
ABIName = ModuleTargetABI->getString();
301271
}
302-
I = std::make_unique<RISCVSubtarget>(TargetTriple, CPU, TuneCPU, FS,
303-
ABIName, RVVBitsMin, RVVBitsMax,
304-
ZicfilpLabelScheme, *this);
272+
I = std::make_unique<RISCVSubtarget>(
273+
TargetTriple, CPU, TuneCPU, FS, ABIName, RVVBitsMin, RVVBitsMax, *this);
274+
275+
const Module &M = *F.getParent();
276+
if (const Metadata *CF = M.getModuleFlag("cf-protection-branch");
277+
CF && !mdconst::extract<ConstantInt>(CF)->isZero()) {
278+
StringRef LabelScheme;
279+
if (const Metadata *MD = M.getModuleFlag("cf-branch-label-scheme")) {
280+
LabelScheme = cast<MDString>(MD)->getString();
281+
if (LabelScheme != "func-sig" && LabelScheme != "unlabeled")
282+
reportFatalUsageError("cf-branch-label-scheme=" + LabelScheme +
283+
" module flag is unsupported");
284+
} else {
285+
reportFatalUsageError("missing cf-branch-label-scheme module flag");
286+
}
287+
288+
using ZicfilpLabelSchemeEnum = RISCVSubtarget::ZicfilpLabelSchemeEnum;
289+
const ZicfilpLabelSchemeEnum SupportedScheme = I->getZicfilpLabelScheme();
290+
if ((SupportedScheme != ZicfilpLabelSchemeEnum::FuncSig &&
291+
LabelScheme == "func-sig") ||
292+
(SupportedScheme != ZicfilpLabelSchemeEnum::Unlabeled &&
293+
LabelScheme == "unlabeled"))
294+
reportFatalUsageError(
295+
"require target feature (+zicfilp-" + LabelScheme +
296+
") to handle cf-branch-label-scheme=" + LabelScheme +
297+
" module flag");
298+
} else if (I->hasZicfilpCFI()) {
299+
reportFatalUsageError("require cf-protection-branch != 0 module flag");
300+
}
305301
}
306302
return I.get();
307303
}

llvm/test/CodeGen/RISCV/features-info.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,8 @@
263263
; CHECK-NEXT: ziccif - 'Ziccif' (Main Memory Supports Instruction Fetch with Atomicity Requirement).
264264
; CHECK-NEXT: zicclsm - 'Zicclsm' (Main Memory Supports Misaligned Loads/Stores).
265265
; CHECK-NEXT: ziccrse - 'Ziccrse' (Main Memory Supports Forward Progress on LR/SC Sequences).
266+
; CHECK-NEXT: zicfilp-func-sig - Enforce forward-edge control-flow integrity with ZICFILP-func-sig.
267+
; CHECK-NEXT: zicfilp-unlabeled - Enforce forward-edge control-flow integrity with ZICFILP-unlabeled.
266268
; CHECK-NEXT: zicntr - 'Zicntr' (Base Counters and Timers).
267269
; CHECK-NEXT: zicond - 'Zicond' (Integer Conditional Operations).
268270
; CHECK-NEXT: zicsr - 'Zicsr' (CSRs).

llvm/test/CodeGen/RISCV/jumptable-swguarded.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
; RUN: llc -mtriple riscv32 < %s | FileCheck %s
2-
; RUN: llc -mtriple riscv64 < %s | FileCheck %s
1+
; RUN: llc -mtriple riscv32 -mattr=+zicfilp-unlabeled < %s | FileCheck %s
2+
; RUN: llc -mtriple riscv64 -mattr=+zicfilp-unlabeled < %s | FileCheck %s
33

44
; Test using t2 to jump table branch.
55
define void @above_threshold(i32 signext %in, ptr %out) nounwind {

0 commit comments

Comments
 (0)