Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions clang/include/clang/Basic/Builtins.td
Original file line number Diff line number Diff line change
Expand Up @@ -839,12 +839,6 @@ def BuiltinAssumeAligned : Builtin {
let Prototype = "void*(void const*, size_t, ...)";
}

def BuiltinAssumeAlignedCap : Builtin {
let Spellings = ["__builtin_assume_aligned_cap"];
let Attributes = [NoThrow, Const, CustomTypeChecking];
let Prototype = "void* __capability(void const* __capability, size_t, ...)";
}

def BuiltinFree : Builtin {
let Spellings = ["__builtin_free"];
let Attributes = [FunctionWithBuiltinPrefix, NoThrow];
Expand Down
1 change: 0 additions & 1 deletion clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9910,7 +9910,6 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
case Builtin::BI__addressof:
case Builtin::BI__builtin_addressof:
return evaluateLValue(E->getArg(0), Result);
case Builtin::BI__builtin_assume_aligned_cap:
case Builtin::BI__builtin_assume_aligned: {
// We need to be very careful here because: if the pointer does not have the
// asserted alignment, then the behavior is undefined, and undefined
Expand Down
1 change: 0 additions & 1 deletion clang/lib/Basic/Targets/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,6 @@ bool RISCVTargetInfo::hasFeature(StringRef Feature) const {
.Case("32bit", !Is64Bit)
.Case("64bit", Is64Bit)
.Case("experimental", HasExperimental)
.Case("xcheri", HasCheri)
.Default(std::nullopt);
if (Result)
return *Result;
Expand Down
1 change: 0 additions & 1 deletion clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3833,7 +3833,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
FnExpect, {ArgValue, ExpectedValue, Confidence}, "expval");
return RValue::get(Result);
}
case Builtin::BI__builtin_assume_aligned_cap:
case Builtin::BI__builtin_assume_aligned: {
const Expr *Ptr = E->getArg(0);
Value *PtrValue = EmitScalarExpr(Ptr);
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGHLSLRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ GlobalVariable *replaceBuffer(CGHLSLRuntime::Buffer &Buf) {
Buf.LayoutStruct, /*isConstant*/ true,
GlobalValue::LinkageTypes::ExternalLinkage, nullptr,
llvm::formatv("{0}{1}", Buf.Name, Buf.IsCBuffer ? ".cb." : ".tb."),
GlobalValue::NotThreadLocal);
GlobalValue::NotThreadLocal, 0);

return CBGV;
}
Expand Down
53 changes: 50 additions & 3 deletions clang/lib/Driver/ToolChains/Arch/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,59 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
Features.push_back("-relax");
}

// If -mstrict-align, -mno-strict-align, -mscalar-strict-align, or
// -mno-scalar-strict-align is passed, use it. Otherwise, the
// unaligned-scalar-mem is enabled if the CPU supports it or the target is
// Android.
if (const Arg *A = Args.getLastArg(
options::OPT_mno_strict_align, options::OPT_mscalar_strict_align,
options::OPT_mstrict_align, options::OPT_mno_scalar_strict_align)) {
if (A->getOption().matches(options::OPT_mno_strict_align) ||
A->getOption().matches(options::OPT_mno_scalar_strict_align)) {
Features.push_back("+unaligned-scalar-mem");
} else {
Features.push_back("-unaligned-scalar-mem");
}
} else if (CPUFastScalarUnaligned || Triple.isAndroid()) {
Features.push_back("+unaligned-scalar-mem");
}

// If -mstrict-align, -mno-strict-align, -mvector-strict-align, or
// -mno-vector-strict-align is passed, use it. Otherwise, the
// unaligned-vector-mem is enabled if the CPU supports it or the target is
// Android.
if (const Arg *A = Args.getLastArg(
options::OPT_mno_strict_align, options::OPT_mvector_strict_align,
options::OPT_mstrict_align, options::OPT_mno_vector_strict_align)) {
if (A->getOption().matches(options::OPT_mno_strict_align) ||
A->getOption().matches(options::OPT_mno_vector_strict_align)) {
Features.push_back("+unaligned-vector-mem");
} else {
Features.push_back("-unaligned-vector-mem");
}
} else if (CPUFastVectorUnaligned || Triple.isAndroid()) {
Features.push_back("+unaligned-vector-mem");
}

// Now add any that the user explicitly requested on the command line,
// which may override the defaults.
handleTargetFeaturesGroup(D, Triple, Args, Features,
options::OPT_m_riscv_Features_Group);

if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
bool IsPureCapability = isCheriPurecapABIName(A->getValue());
if (IsPureCapability) {
if (llvm::find(Features, "+xcheri") == Features.end()) {
D.Diag(diag::err_riscv_invalid_abi) << A->getValue()
<< "pure capability ABI requires xcheri extension to be specified";
auto ISAInfo = llvm::RISCVISAInfo::parseFeatures(
Triple.isArch32Bit() ? 32 : 64,
std::vector<std::string>(Features.begin(), Features.end()));
if (!ISAInfo) {
handleAllErrors(ISAInfo.takeError(), [&](llvm::StringError &ErrMsg) {
D.Diag(diag::err_invalid_feature_combination) << ErrMsg.getMessage();
});
} else if (!(*ISAInfo)->hasExtension("xcheri")) {
D.Diag(diag::err_riscv_invalid_abi)
<< A->getValue()
<< "pure capability ABI requires xcheri extension to be specified";
return;
}
Features.push_back("+cap-mode");
Expand Down
16 changes: 7 additions & 9 deletions clang/lib/Headers/cheri_init_globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,13 @@ __attribute__((weak)) extern void *__capability __cap_table_end;
* position-dependent executables.
*/
#ifdef CHERI_INIT_GLOBALS_USE_OFFSET
#define cgetaddr_or_offset "cgetoffset"
#define csetaddr_or_offset "csetoffset"
#define cheri_address_or_offset_get(_cap) __builtin_cheri_offset_get((_cap))
#define cheri_address_or_offset_set(_cap, _val) \
__builtin_cheri_offset_set((_cap), (_val))
#else
#define cgetaddr_or_offset "cgetaddr"
#define csetaddr_or_offset "csetaddr"
#define cheri_address_or_offset_get(_cap) __builtin_cheri_address_get((_cap))
#define cheri_address_or_offset_set(_cap, _val) \
__builtin_cheri_address_set((_cap), (_val))
#endif
Expand Down Expand Up @@ -219,13 +219,11 @@ cheri_init_globals_3(void *__capability data_cap,
"lla %1, __stop___cap_relocs\n\t"
: "=r"(start_addr), "=r"(stop_addr));
#else
void *__capability tmp;
__asm__ (
"cllc %2, __start___cap_relocs\n\t"
cgetaddr_or_offset " %0, %2\n\t"
"cllc %2, __stop___cap_relocs\n\t"
cgetaddr_or_offset " %1, %2\n\t"
:"=r"(start_addr), "=r"(stop_addr), "=&C"(tmp));
__asm__("cllc %0, __start___cap_relocs\n\t"
"cllc %1, __stop___cap_relocs\n\t"
: "=C"(start_relocs), "=C"(stop_relocs));
start_addr = cheri_address_or_offset_get(start_relocs);
stop_addr = cheri_address_or_offset_get(stop_relocs);
#endif
#else
#error Unknown architecture
Expand Down
28 changes: 25 additions & 3 deletions clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2060,7 +2060,8 @@ bool Sema::CheckTSBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
}
}

static bool checkBuiltinArgument(Sema &S, CallExpr *E, unsigned ArgIndex);
static bool checkBuiltinArgument(Sema &S, CallExpr *E, unsigned ArgIndex,
bool OverloadForHybrid = false);

// Check if \p Ty is a valid type for the elementwise math builtins. If it is
// not a valid type, emit an error message and return true. Otherwise return
Expand Down Expand Up @@ -2374,7 +2375,6 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
return ExprError();
break;
case Builtin::BI__builtin_assume_aligned:
case Builtin::BI__builtin_assume_aligned_cap:
if (BuiltinAssumeAligned(TheCall))
return ExprError();
break;
Expand Down Expand Up @@ -4585,7 +4585,8 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,
/// them.
///
/// Returns true on error.
static bool checkBuiltinArgument(Sema &S, CallExpr *E, unsigned ArgIndex) {
static bool checkBuiltinArgument(Sema &S, CallExpr *E, unsigned ArgIndex,
bool OverloadForHybrid) {
FunctionDecl *Fn = E->getDirectCallee();
assert(Fn && "builtin call without direct callee!");

Expand All @@ -4594,6 +4595,18 @@ static bool checkBuiltinArgument(Sema &S, CallExpr *E, unsigned ArgIndex) {
InitializedEntity::InitializeParameter(S.Context, Param);

ExprResult Arg = E->getArg(ArgIndex);
if (OverloadForHybrid) {
assert(Param->getType()->isPointerType());
// In CHERI hybrid mode we have to update the argument to a
// capability-qualified type ensure that we don't get an initialization
// error.
if (Arg.get()->getType()->isCapabilityPointerType() &&
!Param->getType()->isCapabilityPointerType()) {
QualType PtrTy = S.Context.getPointerType(
Param->getType()->getPointeeType(), PIK_Capability);
Entity = InitializedEntity::InitializeParameter(S.Context, PtrTy, false);
}
}
Arg = S.PerformCopyInitialization(Entity, SourceLocation(), Arg);
if (Arg.isInvalid())
return true;
Expand Down Expand Up @@ -5704,7 +5717,16 @@ bool Sema::BuiltinAssumeAligned(CallExpr *TheCall) {
<< TheCall->getSourceRange();
return true;
}
if (checkBuiltinArgument(*this, TheCall, 0, /*OverloadForHybrid=*/true))
return true;
TheCall->setArg(0, FirstArgResult.get());
// We may also have to update the return type since this intrinsic is
// overloaded for hybrid mode.
if (const auto *PtrTy =
FirstArgResult.get()->getType()->getAs<PointerType>())
TheCall->setType(
Context.getPointerType(TheCall->getType()->getPointeeType(),
PtrTy->getPointerInterpretation()));
}

// The alignment must be a constant integer.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,6 @@ bool BuiltinFunctionChecker::evalCall(const CallEvent &Call,
case Builtin::BI__builtin_expect:
case Builtin::BI__builtin_expect_with_probability:
case Builtin::BI__builtin_assume_aligned:
case Builtin::BI__builtin_assume_aligned_cap:
case Builtin::BI__builtin_addressof:
case Builtin::BI__builtin_function_start: {
// For __builtin_unpredictable, __builtin_expect,
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGen/cheri/assume-aligned.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,5 @@ int* assume_aligned_ptr(void* ptr) {
// PURECAP-NEXT: ret ptr addrspace(200) [[TMP0]]
//
int* __capability assume_aligned_cap(void* __capability ptr) {
return __builtin_assume_aligned_cap(ptr, 4);
return __builtin_assume_aligned(ptr, 4);
}
34 changes: 0 additions & 34 deletions clang/test/CodeGen/cheri/bn_x931p-crash.c

This file was deleted.

2 changes: 1 addition & 1 deletion clang/test/CodeGen/cheri/csetbounds-stats-subobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ void test_subobject_addrof_global() {
}

void test_subobject_addrof_assume_aligned(struct Nested * __capability cap) {
struct Nested * __capability cap2 = __builtin_assume_aligned_cap(cap, 4096);
struct Nested * __capability cap2 = __builtin_assume_aligned(cap, 4096);
do_stuff_with_int_capability(&cap2->a);
// HYBRID-CSV-NEXT: 0,4,o,"{{.+}}/csetbounds-stats-subobject.c:[[@LINE-1]]:32","Add subobject bounds","addrof operator on int"
// PURECAP-CSV-NEXT: 0,4,o,"{{.+}}/csetbounds-stats-subobject.c:[[@LINE-2]]:32","Add subobject bounds","addrof operator on int"
Expand Down
2 changes: 2 additions & 0 deletions libunwind/src/CompartmentInfo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
#ifndef __COMPARTMENT_INFO_HPP__
#define __COMPARTMENT_INFO_HPP__

#ifdef _LIBUNWIND_HAS_CHERI_LIB_C18N
#include <link.h>
#endif

namespace libunwind {

Expand Down
2 changes: 1 addition & 1 deletion libunwind/src/DwarfInstructions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pc_t pc,
// __unw_step_stage2 is not used for cross unwinding, so we use
// __aarch64__ rather than LIBUNWIND_TARGET_AARCH64 to make sure we are
// building for AArch64 natively.
#if defined(__aarch64__)
#if defined(__aarch64__) && !defined(__CHERI_PURE_CAPABILITY__)
if (stage2 && cieInfo.mteTaggedFrame) {
pint_t sp = registers.getSP();
pint_t p = sp;
Expand Down
2 changes: 1 addition & 1 deletion lld/ELF/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -829,7 +829,7 @@ static CapTableScopePolicy getCapTableScope(opt::InputArgList &args) {

static CapRelocsMode getLocalCapRelocsMode(opt::InputArgList &args) {
auto *arg =
args.getLastArg(OPT_local_caprelocs_cbuildcap, OPT_local_caprelocs_elf,
args.getLastArg(OPT_local_caprelocs_legacy, OPT_local_caprelocs_elf,
OPT_local_caprelocs_cbuildcap);
if (!arg) // TODO: change default to CBuildCap (at least for non-PIC)
return CapRelocsMode::Legacy;
Expand Down
26 changes: 14 additions & 12 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6008,15 +6008,15 @@ SDValue RISCVTargetLowering::lowerVPCttzElements(SDValue Op,
/// `cfromptr(auth, addr)` is `addr ? csetaddr(auth, addr) : 0` which is
/// semantic change but it is consistent with Morello when CCTLR.DDCBO==0.
static SDValue emitCFromPtrReplacement(SelectionDAG &DAG, const SDLoc &DL,
SDValue Base, SDValue IntVal,
EVT CLenVT) {
SDValue AsCap = DAG.getNode(
ISD::INTRINSIC_WO_CHAIN, DL, CLenVT,
DAG.getConstant(Intrinsic::cheri_cap_address_set, DL, MVT::i64), Base,
IntVal);
return DAG.getSelectCC(DL, IntVal,
DAG.getConstant(0, DL, IntVal.getValueType()), AsCap,
DAG.getNullCapability(DL), ISD::SETNE);
SDValue Base, SDValue IntVal, EVT CLenVT,
EVT XLenVT) {
SDValue AsCap =
DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, CLenVT,
DAG.getConstant(Intrinsic::cheri_cap_address_set, DL, XLenVT),
Base, IntVal);
return DAG.getSelectCC(DL, IntVal,
DAG.getConstant(0, DL, IntVal.getValueType()), AsCap,
DAG.getNullCapability(DL), ISD::SETNE);
}

/// The CToPtr instruction is deprecated and will be removed. This function
Expand Down Expand Up @@ -6919,7 +6919,8 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
}
SDLoc DL(Op);
EVT CLenVT = Op.getValueType();
auto GetDDC = DAG.getConstant(Intrinsic::cheri_ddc_get, DL, MVT::i64);
MVT XLenVT = Subtarget.getXLenVT();
auto GetDDC = DAG.getConstant(Intrinsic::cheri_ddc_get, DL, XLenVT);
auto DDC = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, CapType, GetDDC);
// It would be nice if we could just use SetAddr on DDC, but for
// consistency between constant inttoptr and non-constant inttoptr
Expand All @@ -6928,7 +6929,7 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
// getting different values for inttoptr with a constant zero argument and
// inttoptr with a variable that happens to be zero (the latter should not
// result in a tagged value).
return emitCFromPtrReplacement(DAG, DL, DDC, Op0, CLenVT);
return emitCFromPtrReplacement(DAG, DL, DDC, Op0, CLenVT, XLenVT);
}
return Op;
}
Expand Down Expand Up @@ -10066,7 +10067,8 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
// Expand CFromPtr if the dedicated instruction has been removed.
if (Subtarget.hasCheriISAv9Semantics()) {
return emitCFromPtrReplacement(DAG, DL, Op.getOperand(1),
Op.getOperand(2), Op.getValueType());
Op.getOperand(2), Op.getValueType(),
XLenVT);
}
break;
case Intrinsic::cheri_cap_to_pointer:
Expand Down
7 changes: 6 additions & 1 deletion llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,12 @@ static std::string computeDataLayout(const Triple &TT, StringRef FS,

StringRef CapTypes = "";
StringRef PurecapOptions = "";
if (llvm::is_contained(llvm::split(FS, ','), "+xcheri")) {
unsigned XLen = TT.isArch64Bit() ? 64 : 32;
std::vector<std::string> Features;
if (!FS.empty())
llvm::append_range(Features, llvm::split(FS, ','));
auto ISAInfo = cantFail(llvm::RISCVISAInfo::parseFeatures(XLen, Features));
if (ISAInfo->hasExtension("xcheri")) {
if (TT.isArch64Bit())
CapTypes = "-pf200:128:128:128:64";
else
Expand Down
6 changes: 4 additions & 2 deletions llvm/unittests/IR/MetadataTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4545,7 +4545,8 @@ TEST_F(DIArgListTest, UpdatesOnRAUW) {
ConstantAsMetadata *CI =
ConstantAsMetadata::get(ConstantInt::get(Context, APInt(8, 0)));
std::unique_ptr<GlobalVariable> GV0(
new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage, nullptr, "",
GlobalVariable::NotThreadLocal, 0));
auto *MD0 = ValueAsMetadata::get(GV0.get());

SmallVector<ValueAsMetadata *, 2> VMs;
Expand All @@ -4556,7 +4557,8 @@ TEST_F(DIArgListTest, UpdatesOnRAUW) {
EXPECT_EQ(AL->getArgs()[1], MD0);

std::unique_ptr<GlobalVariable> GV1(
new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage, nullptr, "",
GlobalVariable::NotThreadLocal, 0));
auto *MD1 = ValueAsMetadata::get(GV1.get());
GV0->replaceAllUsesWith(GV1.get());
EXPECT_EQ(AL->getArgs()[0], CI);
Expand Down