Skip to content

Commit

Permalink
[CodeGen] Rework MVT representation of capabilities and add type infe…
Browse files Browse the repository at this point in the history
…rence

This more closely aligns how capabilites are handled with iPTR and iN
types, introducing a new cPTR wildcard and fixed-width cN types that it
maps to, with iPTRAny being iPTR and cPTR. As a result we no longer need
to duplicate patterns for each fixed-width type in certain cases, and
the few upstream MIPS tests we've long marked as XFAIL'ed now pass.

As part of this, a few of the APIs around MVTs have been renamed from
fat pointer terminology to use capability instead. Where relatively
straightforward to do these have then been adopted throughout, but some
are pervasive and have deprecated aliases under the old names, whose
uses should be incrementally reduced.
  • Loading branch information
jrtc27 committed Feb 14, 2024
1 parent f9c0b68 commit 4fa6c51
Show file tree
Hide file tree
Showing 39 changed files with 469 additions and 519 deletions.
6 changes: 3 additions & 3 deletions llvm/include/llvm/CodeGen/TargetLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ class TargetLoweringBase {
uint32_t AS) const {
#endif
if (DL.isFatPointer(AS))
return MVT::getFatPointerVT(DL.getPointerSizeInBits(AS));
return MVT::getCapabilityVT(DL.getPointerSizeInBits(AS));
return MVT::getIntegerVT(DL.getPointerSizeInBits(AS));
}

Expand All @@ -382,7 +382,7 @@ class TargetLoweringBase {
uint32_t AS) const {
#endif
if (DL.isFatPointer(AS))
return MVT::getFatPointerVT(DL.getPointerSizeInBits(AS));
return MVT::getCapabilityVT(DL.getPointerSizeInBits(AS));
return MVT::getIntegerVT(DL.getPointerSizeInBits(AS));
}

Expand Down Expand Up @@ -3477,7 +3477,7 @@ class TargetLoweringBase {
bool EnableExtLdPromotion;

/// The type to use for CHERI capabilities (if supported)
/// Should be one of iFATPTR64/128/256
/// Should be one of c64/c128/c256
MVT CapType = MVT();

/// Whether the CHERI capability type supports precise bounds for any
Expand Down
12 changes: 8 additions & 4 deletions llvm/include/llvm/CodeGen/ValueTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,15 @@ namespace llvm {
return isSimple() ? V.isInteger() : isExtendedInteger();
}

/// Return true if this is a fat pointer type.
bool isFatPointer() const {
return isSimple() ? V.isFatPointer() : false;
/// Return true if this is a capability type.
bool isCapability() const {
// TODO: isExtendedCapability?
return isSimple() ? V.isCapability() : false;
}

/// Return true if this is a capability type. Deprecated.
bool isFatPointer() const { return isCapability(); }

/// Return true if this is an integer, but not a vector.
bool isScalarInteger() const {
return isSimple() ? V.isScalarInteger() : isExtendedScalarInteger();
Expand Down Expand Up @@ -213,7 +217,7 @@ namespace llvm {
/// Return true if this is an overloaded type for TableGen.
bool isOverloaded() const {
return (V == MVT::iAny || V == MVT::fAny || V == MVT::vAny ||
V == MVT::iPTRAny || V == MVT::iFATPTRAny);
V == MVT::iPTRAny);
}

/// Return true if the bit size is a multiple of 8.
Expand Down
11 changes: 6 additions & 5 deletions llvm/include/llvm/CodeGen/ValueTypes.td
Original file line number Diff line number Diff line change
Expand Up @@ -226,11 +226,12 @@ def externref : ValueType<0, 182>; // WebAssembly's externref type
def x86amx : ValueType<8192, 183>; // X86 AMX value
def i64x8 : ValueType<512, 184>; // 8 Consecutive GPRs (AArch64)

def iFATPTR64 : ValueType<64, !add(i64x8.Value, 1)>; // 64-bit fat pointer.
def iFATPTR128: ValueType<128, !add(iFATPTR64.Value, 1)>; // 128-bit fat pointer.
def iFATPTR256: ValueType<256, !add(iFATPTR128.Value, 1)>; // 256-bit fat pointer.
def iFATPTR512: ValueType<512, !add(iFATPTR256.Value, 1)>; // 512-bit fat pointer.
def iFATPTRAny: ValueType<0, !add(iFATPTR512.Value, 1)>; // Any fat pointer.
def c64 : ValueType<64, !add(i64x8.Value, 1)>; // 64-bit capability value
def c128 : ValueType<128, !add(c64.Value, 1)>; // 128-bit capability value
def c256 : ValueType<256, !add(c128.Value, 1)>; // 256-bit capability value

// Pseudo valuetype mapped to the current capability pointer size.
def cPTR : ValueType<0, 247>;

def token : ValueType<0, 248>; // TokenTy
def MetadataVT : ValueType<0, 249>; // Metadata
Expand Down
6 changes: 3 additions & 3 deletions llvm/include/llvm/IR/Intrinsics.td
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@ class LLVMAnyPointerType<LLVMType elty>
let isAny = true;
}

class LLVMFatPointerType<LLVMType elty>
: LLVMType<iFATPTRAny>{
class LLVMCapabilityType<LLVMType elty>
: LLVMType<cPTR>{
LLVMType ElTy = elty;
}

Expand Down Expand Up @@ -261,7 +261,7 @@ def llvm_ppcf128_ty : LLVMType<ppcf128>;
def llvm_ptr_ty : LLVMPointerType<llvm_i8_ty>; // i8*
def llvm_ptrptr_ty : LLVMPointerType<llvm_ptr_ty>; // i8**
def llvm_anyptr_ty : LLVMAnyPointerType<llvm_i8_ty>; // (space)i8*
def llvm_fatptr_ty : LLVMFatPointerType<llvm_i8_ty>; // (space)i8*
def llvm_cap_ty : LLVMCapabilityType<llvm_i8_ty>; // (space)i8*
def llvm_anyptrptr_ty : LLVMAnyPointerType<llvm_ptr_ty>; // i8*(space)*
def llvm_empty_ty : LLVMType<OtherVT>; // { }
def llvm_descriptor_ty : LLVMPointerType<llvm_empty_ty>; // { }*
Expand Down
92 changes: 46 additions & 46 deletions llvm/include/llvm/IR/IntrinsicsCHERICap.td
Original file line number Diff line number Diff line change
Expand Up @@ -14,150 +14,150 @@

def int_cheri_cap_length_get :
Intrinsic<[llvm_anyint_ty],
[llvm_fatptr_ty],
[llvm_cap_ty],
[IntrNoMem, IntrWillReturn]>;
def int_cheri_cap_base_get :
Intrinsic<[llvm_anyint_ty],
[llvm_fatptr_ty],
[llvm_cap_ty],
[IntrNoMem, IntrWillReturn]>;

def int_cheri_cap_perms_and :
Intrinsic<[llvm_fatptr_ty],
[llvm_fatptr_ty, llvm_anyint_ty],
Intrinsic<[llvm_cap_ty],
[llvm_cap_ty, llvm_anyint_ty],
[IntrNoMem, IntrWillReturn]>;
def int_cheri_cap_perms_get :
Intrinsic<[llvm_anyint_ty],
[llvm_fatptr_ty],
[llvm_cap_ty],
[IntrNoMem, IntrWillReturn]>;
def int_cheri_cap_flags_set :
Intrinsic<[llvm_fatptr_ty],
[llvm_fatptr_ty, llvm_anyint_ty],
Intrinsic<[llvm_cap_ty],
[llvm_cap_ty, llvm_anyint_ty],
[IntrNoMem, IntrWillReturn]>;
def int_cheri_cap_flags_get :
Intrinsic<[llvm_anyint_ty],
[llvm_fatptr_ty],
[llvm_cap_ty],
[IntrNoMem, IntrWillReturn]>;
def int_cheri_cap_high_set :
Intrinsic<[llvm_fatptr_ty],
[llvm_fatptr_ty, llvm_anyint_ty],
Intrinsic<[llvm_cap_ty],
[llvm_cap_ty, llvm_anyint_ty],
[IntrNoMem, IntrWillReturn]>;
def int_cheri_cap_high_get :
Intrinsic<[llvm_anyint_ty],
[llvm_fatptr_ty],
[llvm_cap_ty],
[IntrNoMem, IntrWillReturn]>;
def int_cheri_cap_bounds_set :
Intrinsic<[llvm_fatptr_ty],
[llvm_fatptr_ty, llvm_anyint_ty],
Intrinsic<[llvm_cap_ty],
[llvm_cap_ty, llvm_anyint_ty],
[IntrNoMem, IntrWillReturn]>;
def int_cheri_cap_bounds_set_exact :
Intrinsic<[llvm_fatptr_ty],
[llvm_fatptr_ty, llvm_anyint_ty],
Intrinsic<[llvm_cap_ty],
[llvm_cap_ty, llvm_anyint_ty],
[IntrNoMem, IntrWillReturn]>;
def int_cheri_cap_type_get :
Intrinsic<[llvm_anyint_ty],
[llvm_fatptr_ty],
[llvm_cap_ty],
[IntrNoMem, IntrWillReturn]>;
def int_cheri_cap_tag_get :
ClangBuiltin<"__builtin_cheri_tag_get">,
Intrinsic<[llvm_i1_ty],
[llvm_fatptr_ty],
[llvm_cap_ty],
[IntrNoMem, IntrWillReturn]>;
def int_cheri_cap_sealed_get :
ClangBuiltin<"__builtin_cheri_sealed_get">,
Intrinsic<[llvm_i1_ty],
[llvm_fatptr_ty],
[llvm_cap_ty],
[IntrNoMem, IntrWillReturn]>;

def int_cheri_cap_tag_clear :
ClangBuiltin<"__builtin_cheri_tag_clear">,
Intrinsic<[llvm_fatptr_ty],
[llvm_fatptr_ty],
Intrinsic<[llvm_cap_ty],
[llvm_cap_ty],
[IntrNoMem, IntrWillReturn]>;

def int_cheri_cap_seal :
ClangBuiltin<"__builtin_cheri_seal">,
Intrinsic<[llvm_fatptr_ty],
[llvm_fatptr_ty, llvm_fatptr_ty],
Intrinsic<[llvm_cap_ty],
[llvm_cap_ty, llvm_cap_ty],
[IntrNoMem, IntrWillReturn]>;
def int_cheri_cap_conditional_seal :
ClangBuiltin<"__builtin_cheri_conditional_seal">,
Intrinsic<[llvm_fatptr_ty],
[llvm_fatptr_ty, llvm_fatptr_ty],
Intrinsic<[llvm_cap_ty],
[llvm_cap_ty, llvm_cap_ty],
[IntrNoMem, IntrWillReturn]>;
def int_cheri_cap_unseal :
ClangBuiltin<"__builtin_cheri_unseal">,
Intrinsic<[llvm_fatptr_ty],
[llvm_fatptr_ty, llvm_fatptr_ty],
Intrinsic<[llvm_cap_ty],
[llvm_cap_ty, llvm_cap_ty],
[IntrNoMem, IntrWillReturn]>;
def int_cheri_cap_seal_entry:
ClangBuiltin<"__builtin_cheri_seal_entry">,
Intrinsic<[llvm_fatptr_ty], [llvm_fatptr_ty],
Intrinsic<[llvm_cap_ty], [llvm_cap_ty],
[IntrNoMem, IntrWillReturn]>;

def int_cheri_cap_perms_check :
Intrinsic<[], [llvm_fatptr_ty, llvm_anyint_ty],
Intrinsic<[], [llvm_cap_ty, llvm_anyint_ty],
[IntrNoMem, IntrHasSideEffects, IntrWillReturn]>;
def int_cheri_cap_type_check :
ClangBuiltin<"__builtin_cheri_type_check">,
Intrinsic<[], [llvm_fatptr_ty, llvm_fatptr_ty],
Intrinsic<[], [llvm_cap_ty, llvm_cap_ty],
[IntrNoMem, IntrHasSideEffects, IntrWillReturn]>;
def int_cheri_cap_subset_test:
ClangBuiltin<"__builtin_cheri_subset_test">,
Intrinsic<[llvm_i1_ty], [llvm_fatptr_ty, llvm_fatptr_ty], [IntrNoMem, IntrWillReturn]>;
Intrinsic<[llvm_i1_ty], [llvm_cap_ty, llvm_cap_ty], [IntrNoMem, IntrWillReturn]>;
def int_cheri_cap_equal_exact:
ClangBuiltin<"__builtin_cheri_equal_exact">,
Intrinsic<[llvm_i1_ty], [llvm_fatptr_ty, llvm_fatptr_ty], [IntrNoMem, IntrWillReturn]>;
Intrinsic<[llvm_i1_ty], [llvm_cap_ty, llvm_cap_ty], [IntrNoMem, IntrWillReturn]>;

def int_cheri_stack_cap_get :
ClangBuiltin<"__builtin_cheri_stack_get">,
Intrinsic<[llvm_fatptr_ty], [], [IntrNoMem, IntrWillReturn]>;
Intrinsic<[llvm_cap_ty], [], [IntrNoMem, IntrWillReturn]>;
def int_cheri_ddc_get :
ClangBuiltin<"__builtin_cheri_global_data_get">,
Intrinsic<[llvm_fatptr_ty], [], [IntrNoMem, IntrWillReturn]>;
Intrinsic<[llvm_cap_ty], [], [IntrNoMem, IntrWillReturn]>;
def int_cheri_pcc_get :
ClangBuiltin<"__builtin_cheri_program_counter_get">,
Intrinsic<[llvm_fatptr_ty], [], [IntrNoMem, IntrWillReturn]>;
Intrinsic<[llvm_cap_ty], [], [IntrNoMem, IntrWillReturn]>;

////////////////////////////////////////////////////////////////////////////////
// Offset-related intrinsics
////////////////////////////////////////////////////////////////////////////////

def int_cheri_cap_offset_set:
Intrinsic<[llvm_fatptr_ty], [llvm_fatptr_ty, llvm_anyint_ty], [IntrNoMem, IntrWillReturn]>;
Intrinsic<[llvm_cap_ty], [llvm_cap_ty, llvm_anyint_ty], [IntrNoMem, IntrWillReturn]>;
def int_cheri_cap_offset_get:
Intrinsic<[llvm_anyint_ty], [llvm_fatptr_ty], [IntrNoMem, IntrWillReturn]>;
Intrinsic<[llvm_anyint_ty], [llvm_cap_ty], [IntrNoMem, IntrWillReturn]>;
def int_cheri_cap_diff:
Intrinsic<[llvm_anyint_ty], [llvm_fatptr_ty,llvm_fatptr_ty], [IntrNoMem, IntrWillReturn]>;
Intrinsic<[llvm_anyint_ty], [llvm_cap_ty,llvm_cap_ty], [IntrNoMem, IntrWillReturn]>;

////////////////////////////////////////////////////////////////////////////////
// Pointer / capability interoperation intrinsics
////////////////////////////////////////////////////////////////////////////////
def int_cheri_cap_address_get:
Intrinsic<[llvm_anyint_ty], [llvm_fatptr_ty], [IntrNoMem, IntrWillReturn]>;
Intrinsic<[llvm_anyint_ty], [llvm_cap_ty], [IntrNoMem, IntrWillReturn]>;
def int_cheri_cap_address_set:
Intrinsic<[llvm_fatptr_ty], [llvm_fatptr_ty, llvm_anyint_ty], [IntrNoMem, IntrWillReturn]>;
Intrinsic<[llvm_cap_ty], [llvm_cap_ty, llvm_anyint_ty], [IntrNoMem, IntrWillReturn]>;


def int_cheri_cap_to_pointer:
Intrinsic<[llvm_anyint_ty], [llvm_fatptr_ty, llvm_fatptr_ty], [IntrNoMem, IntrWillReturn]>;
Intrinsic<[llvm_anyint_ty], [llvm_cap_ty, llvm_cap_ty], [IntrNoMem, IntrWillReturn]>;
def int_cheri_cap_from_pointer:
Intrinsic<[llvm_fatptr_ty], [llvm_fatptr_ty, llvm_anyint_ty], [IntrNoMem, IntrWillReturn]>;
Intrinsic<[llvm_cap_ty], [llvm_cap_ty, llvm_anyint_ty], [IntrNoMem, IntrWillReturn]>;

////////////////////////////////////////////////////////////////////////////////
// Building capabilities from untagged data
////////////////////////////////////////////////////////////////////////////////
def int_cheri_cap_build:
ClangBuiltin<"__builtin_cheri_cap_build">,
Intrinsic<[llvm_fatptr_ty], [llvm_fatptr_ty, llvm_fatptr_ty], [IntrNoMem, IntrWillReturn]>;
Intrinsic<[llvm_cap_ty], [llvm_cap_ty, llvm_cap_ty], [IntrNoMem, IntrWillReturn]>;
def int_cheri_cap_type_copy:
ClangBuiltin<"__builtin_cheri_cap_type_copy">,
Intrinsic<[llvm_fatptr_ty], [llvm_fatptr_ty, llvm_fatptr_ty], [IntrNoMem, IntrWillReturn]>;
Intrinsic<[llvm_cap_ty], [llvm_cap_ty, llvm_cap_ty], [IntrNoMem, IntrWillReturn]>;

////////////////////////////////////////////////////////////////////////////////
// Tag memory accessor functions
////////////////////////////////////////////////////////////////////////////////
def int_cheri_cap_load_tags:
Intrinsic<[llvm_anyint_ty], [llvm_fatptr_ty], [IntrReadMem]>;
Intrinsic<[llvm_anyint_ty], [llvm_cap_ty], [IntrReadMem]>;

/// Round length to compressed capability precision:
def int_cheri_round_representable_length :
Expand All @@ -177,6 +177,6 @@ def int_cheri_representable_alignment_mask :
/// NB: They *only* has this additional meaning at the IR level; at the DAG and
/// MIR levels they cannot be assumed safe like at the IR level.
def int_cheri_bounded_stack_cap :
Intrinsic<[llvm_fatptr_ty], [llvm_fatptr_ty, llvm_anyint_ty], [IntrNoMem, IntrWillReturn]>;
Intrinsic<[llvm_cap_ty], [llvm_cap_ty, llvm_anyint_ty], [IntrNoMem, IntrWillReturn]>;
def int_cheri_bounded_stack_cap_dynamic :
Intrinsic<[llvm_fatptr_ty], [llvm_fatptr_ty, llvm_anyint_ty], [IntrNoMem, IntrWillReturn]>;
Intrinsic<[llvm_cap_ty], [llvm_cap_ty, llvm_anyint_ty], [IntrNoMem, IntrWillReturn]>;
16 changes: 8 additions & 8 deletions llvm/include/llvm/IR/IntrinsicsMips.td
Original file line number Diff line number Diff line change
Expand Up @@ -1792,33 +1792,33 @@ def int_mips_cap_cause_set :
Intrinsic<[], [llvm_i64_ty], []>;
def int_mips_captable_get :
ClangBuiltin<"__builtin_mips_cheri_get_captable">,
Intrinsic<[llvm_fatptr_ty], [], [IntrNoMem]>;
Intrinsic<[llvm_cap_ty], [], [IntrNoMem]>;
def int_mips_idc_get :
GCCBuiltinAlias<"__builtin_mips_cheri_get_invoke_data_cap">,
ClangBuiltin<"__builtin_mips_cheri_invoke_data_cap_get">,
Intrinsic<[llvm_fatptr_ty], [], [IntrNoMem]>;
Intrinsic<[llvm_cap_ty], [], [IntrNoMem]>;
def int_mips_kr1c_get :
GCCBuiltinAlias<"__builtin_mips_cheri_get_kernel_cap1">,
ClangBuiltin<"__builtin_mips_cheri_kernel_cap1_get">,
Intrinsic<[llvm_fatptr_ty], [], [IntrNoMem]>;
Intrinsic<[llvm_cap_ty], [], [IntrNoMem]>;
def int_mips_kr2c_get :
GCCBuiltinAlias<"__builtin_mips_cheri_get_kernel_cap2">,
ClangBuiltin<"__builtin_mips_cheri_kernel_cap2_get">,
Intrinsic<[llvm_fatptr_ty], [], [IntrNoMem]>;
Intrinsic<[llvm_cap_ty], [], [IntrNoMem]>;
def int_mips_kcc_get :
GCCBuiltinAlias<"__builtin_mips_cheri_get_kernel_code_cap">,
ClangBuiltin<"__builtin_mips_cheri_kernel_code_cap_get">,
Intrinsic<[llvm_fatptr_ty], [], [IntrNoMem]>;
Intrinsic<[llvm_cap_ty], [], [IntrNoMem]>;
def int_mips_kdc_get :
GCCBuiltinAlias<"__builtin_mips_cheri_get_kernel_data_cap">,
ClangBuiltin<"__builtin_mips_cheri_kernel_data_cap_get">,
Intrinsic<[llvm_fatptr_ty], [], [IntrNoMem]>;
Intrinsic<[llvm_cap_ty], [], [IntrNoMem]>;
def int_mips_epcc_get :
GCCBuiltinAlias<"__builtin_mips_cheri_get_exception_program_counter_cap">,
ClangBuiltin<"__builtin_mips_cheri_exception_program_counter_cap_get">,
Intrinsic<[llvm_fatptr_ty], [], [IntrNoMem]>;
Intrinsic<[llvm_cap_ty], [], [IntrNoMem]>;

def int_mips_stack_to_cap :
Intrinsic<[llvm_fatptr_ty], [llvm_fatptr_ty], [IntrNoMem]>;
Intrinsic<[llvm_cap_ty], [llvm_cap_ty], [IntrNoMem]>;

}
Loading

0 comments on commit 4fa6c51

Please sign in to comment.