[llvm] 0f13cae - [CodeGen, CHERI] Add capability types to MVT. (#156616)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 11 02:44:35 PDT 2025
Author: Owen Anderson
Date: 2025-09-11T17:44:30+08:00
New Revision: 0f13cae7ff1b0efe37e1f1a2d6cdda48803b44ca
URL: https://github.com/llvm/llvm-project/commit/0f13cae7ff1b0efe37e1f1a2d6cdda48803b44ca
DIFF: https://github.com/llvm/llvm-project/commit/0f13cae7ff1b0efe37e1f1a2d6cdda48803b44ca.diff
LOG: [CodeGen, CHERI] Add capability types to MVT. (#156616)
This adds value types for representing capability types, enabling their use in instruction selection and other parts of the backend.
These types are distinguished from each other only by size. This is sufficient, at least today, because no existing CHERI configuration supports multiple capability sizes simultaneously. Hybrid configurations supporting intermixed integral pointers and capabilities do exist, and are one of the reasons why these value types are needed beyond existing integral types.
Co-authored-by: David Chisnall <theraven at theravensnest.org>
Co-authored-by: Jessica Clarke <jrtc27 at jrtc27.com>
Added:
Modified:
llvm/include/llvm/CodeGen/ValueTypes.h
llvm/include/llvm/CodeGen/ValueTypes.td
llvm/include/llvm/CodeGenTypes/MachineValueType.h
llvm/lib/CodeGen/ValueTypes.cpp
llvm/utils/TableGen/Basic/VTEmitter.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/ValueTypes.h b/llvm/include/llvm/CodeGen/ValueTypes.h
index 43aaa2bcfc222..a91d14af0b204 100644
--- a/llvm/include/llvm/CodeGen/ValueTypes.h
+++ b/llvm/include/llvm/CodeGen/ValueTypes.h
@@ -228,6 +228,11 @@ namespace llvm {
return isSimple() ? V.is2048BitVector() : isExtended2048BitVector();
}
+ /// Return true if this is a capability type.
+ bool isCheriCapability() const {
+ return isSimple() ? V.isCheriCapability() : false;
+ }
+
/// Return true if this is an overloaded type for TableGen.
bool isOverloaded() const {
return (V == MVT::iAny || V == MVT::fAny || V == MVT::vAny ||
diff --git a/llvm/include/llvm/CodeGen/ValueTypes.td b/llvm/include/llvm/CodeGen/ValueTypes.td
index b06158d85f510..44edec98d20f3 100644
--- a/llvm/include/llvm/CodeGen/ValueTypes.td
+++ b/llvm/include/llvm/CodeGen/ValueTypes.td
@@ -28,6 +28,7 @@ class ValueType<int size, int value> {
// Indicates this VT should be included in the
// [FIRST_VALUETYPE,LAST_VALUETYPE] range.
bit isNormalValueType = true;
+ bit isCheriCapability = false;
}
class VTAny<int value> : ValueType<0, value> {
@@ -65,6 +66,10 @@ class VTVecTup<int size, int nf, ValueType dummy_elt, int value>
let isRISCVVecTuple = true;
}
+class VTCheriCapability<int size, int value> : ValueType<size, value> {
+ let isCheriCapability = true;
+}
+
defset list<ValueType> ValueTypes = {
def OtherVT : ValueType<0, 1> { // "Other" value
@@ -357,6 +362,11 @@ def amdgpuBufferStridedPointer : ValueType<192, 252>;
def aarch64mfp8 : ValueType<8, 253>; // 8-bit value in FPR (AArch64)
+// CHERI capabilities. Pointer-like values that carry additional metadata
+// for enforcing safety guarantees on CHERI-enabled targets.
+def c64 : VTCheriCapability<64, 254>; // 64-bit CHERI capability value
+def c128 : VTCheriCapability<128, 255>; // 128-bit CHERI capability value
+
let isNormalValueType = false in {
def token : ValueType<0, 504>; // TokenTy
def MetadataVT : ValueType<0, 505> { // Metadata
diff --git a/llvm/include/llvm/CodeGenTypes/MachineValueType.h b/llvm/include/llvm/CodeGenTypes/MachineValueType.h
index 389bae209f406..321fb6b601868 100644
--- a/llvm/include/llvm/CodeGenTypes/MachineValueType.h
+++ b/llvm/include/llvm/CodeGenTypes/MachineValueType.h
@@ -178,6 +178,12 @@ namespace llvm {
return (isFixedLengthVector() && getFixedSizeInBits() == 2048);
}
+ /// Return true if this is a CHERI capability type.
+ bool isCheriCapability() const {
+ return (SimpleTy >= MVT::FIRST_CHERI_CAPABILITY_VALUETYPE) &&
+ (SimpleTy <= MVT::LAST_CHERI_CAPABILITY_VALUETYPE);
+ }
+
/// Return true if this is an overloaded type for TableGen.
bool isOverloaded() const {
switch (SimpleTy) {
diff --git a/llvm/lib/CodeGen/ValueTypes.cpp b/llvm/lib/CodeGen/ValueTypes.cpp
index 10970b719fcae..0743c92c5b95b 100644
--- a/llvm/lib/CodeGen/ValueTypes.cpp
+++ b/llvm/lib/CodeGen/ValueTypes.cpp
@@ -176,6 +176,8 @@ std::string EVT::getEVTString() const {
return "i" + utostr(getSizeInBits());
if (isFloatingPoint())
return "f" + utostr(getSizeInBits());
+ if (isCheriCapability())
+ return "c" + utostr(getSizeInBits());
llvm_unreachable("Invalid EVT!");
case MVT::bf16: return "bf16";
case MVT::ppcf128: return "ppcf128";
diff --git a/llvm/utils/TableGen/Basic/VTEmitter.cpp b/llvm/utils/TableGen/Basic/VTEmitter.cpp
index 040f37c3a5e1e..c6b4d0b56c02b 100644
--- a/llvm/utils/TableGen/Basic/VTEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/VTEmitter.cpp
@@ -132,6 +132,7 @@ void VTEmitter::run(raw_ostream &OS) {
bool IsVector = VT->getValueAsBit("isVector");
bool IsScalable = VT->getValueAsBit("isScalable");
bool IsRISCVVecTuple = VT->getValueAsBit("isRISCVVecTuple");
+ bool IsCheriCapability = VT->getValueAsBit("isCheriCapability");
int64_t NF = VT->getValueAsInt("NF");
bool IsNormalValueType = VT->getValueAsBit("isNormalValueType");
int64_t NElem = IsVector ? VT->getValueAsInt("nElem") : 0;
@@ -152,6 +153,7 @@ void VTEmitter::run(raw_ostream &OS) {
UpdateVTRange("INTEGER_VALUETYPE", Name, IsInteger && !IsVector);
UpdateVTRange("FP_VALUETYPE", Name, IsFP && !IsVector);
UpdateVTRange("VALUETYPE", Name, IsNormalValueType);
+ UpdateVTRange("CHERI_CAPABILITY_VALUETYPE", Name, IsCheriCapability);
// clang-format off
OS << " GET_VT_ATTR("
More information about the llvm-commits
mailing list