Skip to content

Commit 9c9c454

Browse files
resistorjrtc27
andcommitted
[TableGen, CodeGen, CHERI] Add support for the cPTR wildcard value type.
cPTR is a wildcard CHERI capability value type, used analogously to iPTR. This allows TableGen patterns to abstract over CHERI capability widths. Co-authored-by: Jessica Clarke <[email protected]>
1 parent d976be0 commit 9c9c454

File tree

7 files changed

+76
-8
lines changed

7 files changed

+76
-8
lines changed

llvm/include/llvm/CodeGen/ValueTypes.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,9 @@ def aarch64mfp8 : ValueType<8, 253>; // 8-bit value in FPR (AArch64)
367367
def c64 : VTCheriCapability<64, 254>; // 64-bit CHERI capability value
368368
def c128 : VTCheriCapability<128, 255>; // 128-bit CHERI capability value
369369

370+
// Pseudo valuetype mapped to the current CHERI capability pointer size.
371+
def cPTR : VTAny<503>;
372+
370373
let isNormalValueType = false in {
371374
def token : ValueType<0, 504>; // TokenTy
372375
def MetadataVT : ValueType<0, 505> { // Metadata

llvm/include/llvm/CodeGenTypes/MachineValueType.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,12 @@ namespace llvm {
582582
MVT::LAST_FP_SCALABLE_VECTOR_VALUETYPE,
583583
force_iteration_on_noniterable_enum);
584584
}
585+
586+
static auto cheri_capability_valuetypes() {
587+
return enum_seq_inclusive(MVT::FIRST_CHERI_CAPABILITY_VALUETYPE,
588+
MVT::LAST_CHERI_CAPABILITY_VALUETYPE,
589+
force_iteration_on_noniterable_enum);
590+
}
585591
/// @}
586592
};
587593

llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,8 @@ bool TypeSetByHwMode::intersect(SetType &Out, const SetType &In) {
335335
using WildPartT = std::pair<MVT, std::function<bool(MVT)>>;
336336
static const WildPartT WildParts[] = {
337337
{MVT::iPTR, [](MVT T) { return T.isScalarInteger() || T == MVT::iPTR; }},
338+
{MVT::cPTR,
339+
[](MVT T) { return T.isCheriCapability() || T == MVT::cPTR; }},
338340
};
339341

340342
bool Changed = false;
@@ -816,6 +818,11 @@ void TypeInfer::expandOverloads(TypeSetByHwMode::SetType &Out,
816818
if (Out.count(MVT::pAny)) {
817819
Out.erase(MVT::pAny);
818820
Out.insert(MVT::iPTR);
821+
for (MVT T : MVT::cheri_capability_valuetypes()) {
822+
if (Legal.count(T)) {
823+
Out.insert(MVT::cPTR);
824+
}
825+
}
819826
} else if (Out.count(MVT::iAny)) {
820827
Out.erase(MVT::iAny);
821828
for (MVT T : MVT::integer_valuetypes())
@@ -1647,9 +1654,11 @@ bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode &N,
16471654
case SDTCisVT:
16481655
// Operand must be a particular type.
16491656
return NodeToApply.UpdateNodeType(ResNo, VVT, TP);
1650-
case SDTCisPtrTy:
1651-
// Operand must be same as target pointer type.
1652-
return NodeToApply.UpdateNodeType(ResNo, MVT::iPTR, TP);
1657+
case SDTCisPtrTy: {
1658+
// Operand must be a legal pointer (iPTR, or possibly cPTR) type.
1659+
const auto &PtrTys = TP.getDAGPatterns().getLegalPtrTypes();
1660+
return NodeToApply.UpdateNodeType(ResNo, PtrTys, TP);
1661+
}
16531662
case SDTCisInt:
16541663
// Require it to be one of the legal integer VTs.
16551664
return TI.EnforceInteger(NodeToApply.getExtType(ResNo));
@@ -3260,6 +3269,7 @@ CodeGenDAGPatterns::CodeGenDAGPatterns(const RecordKeeper &R,
32603269
PatternRewriterFn PatternRewriter)
32613270
: Records(R), Target(R), Intrinsics(R),
32623271
LegalVTS(Target.getLegalValueTypes()),
3272+
LegalPtrVTS(ComputeLegalPtrTypes()),
32633273
PatternRewriter(std::move(PatternRewriter)) {
32643274
ParseNodeInfo();
32653275
ParseNodeTransforms();
@@ -3295,6 +3305,36 @@ const Record *CodeGenDAGPatterns::getSDNodeNamed(StringRef Name) const {
32953305
return N;
32963306
}
32973307

3308+
// Compute the subset of iPTR and cPTR legal for each mode, coalescing into the
3309+
// default mode where possible to avoid predicate explosion.
3310+
TypeSetByHwMode CodeGenDAGPatterns::ComputeLegalPtrTypes() const {
3311+
auto LegalPtrsForSet = [](const MachineValueTypeSet &In) {
3312+
MachineValueTypeSet Out;
3313+
Out.insert(MVT::iPTR);
3314+
for (MVT T : MVT::cheri_capability_valuetypes()) {
3315+
if (In.count(T)) {
3316+
Out.insert(MVT::cPTR);
3317+
break;
3318+
}
3319+
}
3320+
return Out;
3321+
};
3322+
3323+
const auto &LegalTypes = getLegalTypes();
3324+
MachineValueTypeSet LegalPtrsDefault =
3325+
LegalPtrsForSet(LegalTypes.get(DefaultMode));
3326+
3327+
TypeSetByHwMode LegalPtrTypes;
3328+
for (const auto &I : LegalTypes) {
3329+
MachineValueTypeSet S = LegalPtrsForSet(I.second);
3330+
if (I.first != DefaultMode && S == LegalPtrsDefault)
3331+
continue;
3332+
LegalPtrTypes.getOrCreate(I.first).insert(S);
3333+
}
3334+
3335+
return LegalPtrTypes;
3336+
}
3337+
32983338
// Parse all of the SDNode definitions for the target, populating SDNodes.
32993339
void CodeGenDAGPatterns::ParseNodeInfo() {
33003340
const CodeGenHwModes &CGH = getTargetInfo().getHwModes();

llvm/utils/TableGen/Common/CodeGenDAGPatterns.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,7 @@ class CodeGenDAGPatterns {
11351135
std::vector<PatternToMatch> PatternsToMatch;
11361136

11371137
TypeSetByHwMode LegalVTS;
1138+
TypeSetByHwMode LegalPtrVTS;
11381139

11391140
using PatternRewriterFn = std::function<void(TreePattern *)>;
11401141
PatternRewriterFn PatternRewriter;
@@ -1148,6 +1149,7 @@ class CodeGenDAGPatterns {
11481149
CodeGenTarget &getTargetInfo() { return Target; }
11491150
const CodeGenTarget &getTargetInfo() const { return Target; }
11501151
const TypeSetByHwMode &getLegalTypes() const { return LegalVTS; }
1152+
const TypeSetByHwMode &getLegalPtrTypes() const { return LegalPtrVTS; }
11511153

11521154
const Record *getSDNodeNamed(StringRef Name) const;
11531155

@@ -1249,6 +1251,7 @@ class CodeGenDAGPatterns {
12491251
}
12501252

12511253
private:
1254+
TypeSetByHwMode ComputeLegalPtrTypes() const;
12521255
void ParseNodeInfo();
12531256
void ParseNodeTransforms();
12541257
void ParseComplexPatterns();

llvm/utils/TableGen/Common/DAGISelMatcher.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,14 @@ static bool TypesAreContradictory(MVT::SimpleValueType T1,
328328
if (T1 == T2)
329329
return false;
330330

331+
if (T1 == MVT::pAny)
332+
return TypesAreContradictory(MVT::iPTR, T2) &&
333+
TypesAreContradictory(MVT::cPTR, T2);
334+
335+
if (T2 == MVT::pAny)
336+
return TypesAreContradictory(T1, MVT::iPTR) &&
337+
TypesAreContradictory(T1, MVT::cPTR);
338+
331339
// If either type is about iPtr, then they don't conflict unless the other
332340
// one is not a scalar integer type.
333341
if (T1 == MVT::iPTR)
@@ -336,7 +344,13 @@ static bool TypesAreContradictory(MVT::SimpleValueType T1,
336344
if (T2 == MVT::iPTR)
337345
return !MVT(T1).isInteger() || MVT(T1).isVector();
338346

339-
// Otherwise, they are two different non-iPTR types, they conflict.
347+
if (T1 == MVT::cPTR)
348+
return !MVT(T2).isCheriCapability() || MVT(T2).isVector();
349+
350+
if (T2 == MVT::cPTR)
351+
return !MVT(T1).isCheriCapability() || MVT(T1).isVector();
352+
353+
// Otherwise, they are two different non-iPTR/cPTR types, they conflict.
340354
return true;
341355
}
342356

llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1426,7 +1426,9 @@ Error OperandMatcher::addTypeCheckPredicate(const TypeSetByHwMode &VTy,
14261426
if (!VTy.isMachineValueType())
14271427
return failUnsupported("unsupported typeset");
14281428

1429-
if (VTy.getMachineValueType() == MVT::iPTR && OperandIsAPointer) {
1429+
if ((VTy.getMachineValueType() == MVT::iPTR ||
1430+
VTy.getMachineValueType() == MVT::cPTR) &&
1431+
OperandIsAPointer) {
14301432
addPredicate<PointerToAnyOperandMatcher>(0);
14311433
return Error::success();
14321434
}

llvm/utils/TableGen/DAGISelMatcherOpt.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -519,9 +519,9 @@ static void FactorScope(std::unique_ptr<Matcher> &MatcherPtr) {
519519
CheckTypeMatcher *CTM = cast_or_null<CheckTypeMatcher>(
520520
FindNodeWithKind(Optn, Matcher::CheckType));
521521
if (!CTM ||
522-
// iPTR checks could alias any other case without us knowing, don't
523-
// bother with them.
524-
CTM->getType() == MVT::iPTR ||
522+
// iPTR/cPTR checks could alias any other case without us knowing,
523+
// don't bother with them.
524+
CTM->getType() == MVT::iPTR || CTM->getType() == MVT::cPTR ||
525525
// SwitchType only works for result #0.
526526
CTM->getResNo() != 0 ||
527527
// If the CheckType isn't at the start of the list, see if we can move

0 commit comments

Comments
 (0)