aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp271
1 files changed, 223 insertions, 48 deletions
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp b/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp
index 2673e4a5cee7..2b2e23f1e5d7 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -31,6 +31,7 @@
#include "clang/AST/StmtObjC.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/CodeGenOptions.h"
+#include "clang/Basic/TargetBuiltins.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/CodeGen/CGFunctionInfo.h"
#include "clang/Frontend/FrontendDiagnostic.h"
@@ -52,6 +53,10 @@
using namespace clang;
using namespace CodeGen;
+namespace llvm {
+extern cl::opt<bool> EnableSingleByteCoverage;
+} // namespace llvm
+
/// shouldEmitLifetimeMarkers - Decide whether we need emit the life-time
/// markers.
static bool shouldEmitLifetimeMarkers(const CodeGenOptions &CGOpts,
@@ -86,6 +91,8 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)
CodeGenFunction::~CodeGenFunction() {
assert(LifetimeExtendedCleanupStack.empty() && "failed to emit a cleanup");
+ assert(DeferredDeactivationCleanupStack.empty() &&
+ "missed to deactivate a cleanup");
if (getLangOpts().OpenMP && CurFn)
CGM.getOpenMPRuntime().functionFinished(*this);
@@ -188,26 +195,47 @@ CodeGenFunction::CGFPOptionsRAII::~CGFPOptionsRAII() {
CGF.Builder.setDefaultConstrainedRounding(OldRounding);
}
-LValue CodeGenFunction::MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T) {
+static LValue
+makeNaturalAlignAddrLValue(llvm::Value *V, QualType T, bool ForPointeeType,
+ bool MightBeSigned, CodeGenFunction &CGF,
+ KnownNonNull_t IsKnownNonNull = NotKnownNonNull) {
LValueBaseInfo BaseInfo;
TBAAAccessInfo TBAAInfo;
- CharUnits Alignment = CGM.getNaturalTypeAlignment(T, &BaseInfo, &TBAAInfo);
- Address Addr(V, ConvertTypeForMem(T), Alignment);
- return LValue::MakeAddr(Addr, T, getContext(), BaseInfo, TBAAInfo);
+ CharUnits Alignment =
+ CGF.CGM.getNaturalTypeAlignment(T, &BaseInfo, &TBAAInfo, ForPointeeType);
+ Address Addr =
+ MightBeSigned
+ ? CGF.makeNaturalAddressForPointer(V, T, Alignment, false, nullptr,
+ nullptr, IsKnownNonNull)
+ : Address(V, CGF.ConvertTypeForMem(T), Alignment, IsKnownNonNull);
+ return CGF.MakeAddrLValue(Addr, T, BaseInfo, TBAAInfo);
+}
+
+LValue
+CodeGenFunction::MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T,
+ KnownNonNull_t IsKnownNonNull) {
+ return ::makeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ false,
+ /*MightBeSigned*/ true, *this,
+ IsKnownNonNull);
}
-/// Given a value of type T* that may not be to a complete object,
-/// construct an l-value with the natural pointee alignment of T.
LValue
CodeGenFunction::MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T) {
- LValueBaseInfo BaseInfo;
- TBAAAccessInfo TBAAInfo;
- CharUnits Align = CGM.getNaturalTypeAlignment(T, &BaseInfo, &TBAAInfo,
- /* forPointeeType= */ true);
- Address Addr(V, ConvertTypeForMem(T), Align);
- return MakeAddrLValue(Addr, T, BaseInfo, TBAAInfo);
+ return ::makeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ true,
+ /*MightBeSigned*/ true, *this);
}
+LValue CodeGenFunction::MakeNaturalAlignRawAddrLValue(llvm::Value *V,
+ QualType T) {
+ return ::makeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ false,
+ /*MightBeSigned*/ false, *this);
+}
+
+LValue CodeGenFunction::MakeNaturalAlignPointeeRawAddrLValue(llvm::Value *V,
+ QualType T) {
+ return ::makeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ true,
+ /*MightBeSigned*/ false, *this);
+}
llvm::Type *CodeGenFunction::ConvertTypeForMem(QualType T) {
return CGM.getTypes().ConvertTypeForMem(T);
@@ -217,6 +245,11 @@ llvm::Type *CodeGenFunction::ConvertType(QualType T) {
return CGM.getTypes().ConvertType(T);
}
+llvm::Type *CodeGenFunction::convertTypeForLoadStore(QualType ASTTy,
+ llvm::Type *LLVMTy) {
+ return CGM.getTypes().convertTypeForLoadStore(ASTTy, LLVMTy);
+}
+
TypeEvaluationKind CodeGenFunction::getEvaluationKind(QualType type) {
type = type.getCanonicalType();
while (true) {
@@ -262,6 +295,7 @@ TypeEvaluationKind CodeGenFunction::getEvaluationKind(QualType type) {
case Type::Record:
case Type::ObjCObject:
case Type::ObjCInterface:
+ case Type::ArrayParameter:
return TEK_Aggregate;
// We operate on atomic values according to their underlying type.
@@ -331,6 +365,16 @@ static void EmitIfUsed(CodeGenFunction &CGF, llvm::BasicBlock *BB) {
void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
assert(BreakContinueStack.empty() &&
"mismatched push/pop in break/continue stack!");
+ assert(LifetimeExtendedCleanupStack.empty() &&
+ "mismatched push/pop of cleanups in EHStack!");
+ assert(DeferredDeactivationCleanupStack.empty() &&
+ "mismatched activate/deactivate of cleanups!");
+
+ if (CGM.shouldEmitConvergenceTokens()) {
+ ConvergenceTokenStack.pop_back();
+ assert(ConvergenceTokenStack.empty() &&
+ "mismatched push/pop in convergence stack!");
+ }
bool OnlySimpleReturnStmts = NumSimpleReturnExprs > 0
&& NumSimpleReturnExprs == NumReturnExprs
@@ -520,7 +564,8 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
ReturnBlock.getBlock()->eraseFromParent();
}
if (ReturnValue.isValid()) {
- auto *RetAlloca = dyn_cast<llvm::AllocaInst>(ReturnValue.getPointer());
+ auto *RetAlloca =
+ dyn_cast<llvm::AllocaInst>(ReturnValue.emitRawPointer(*this));
if (RetAlloca && RetAlloca->use_empty()) {
RetAlloca->eraseFromParent();
ReturnValue = Address::invalid();
@@ -790,6 +835,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
if (SanOpts.has(SanitizerKind::Thread))
Fn->addFnAttr(llvm::Attribute::SanitizeThread);
+ if (SanOpts.has(SanitizerKind::NumericalStability))
+ Fn->addFnAttr(llvm::Attribute::SanitizeNumericalStability);
if (SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory))
Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
}
@@ -806,7 +853,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
// .cxx_destruct, __destroy_helper_block_ and all of their calees at run time.
if (SanOpts.has(SanitizerKind::Thread)) {
if (const auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
- IdentifierInfo *II = OMD->getSelector().getIdentifierInfoForSlot(0);
+ const IdentifierInfo *II = OMD->getSelector().getIdentifierInfoForSlot(0);
if (OMD->getMethodFamily() == OMF_dealloc ||
OMD->getMethodFamily() == OMF_initialize ||
(OMD->getSelector().isUnarySelector() && II->isStr(".cxx_destruct"))) {
@@ -831,6 +878,17 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
FD->getBody()->getStmtClass() == Stmt::CoroutineBodyStmtClass)
SanOpts.Mask &= ~SanitizerKind::Null;
+ // Add pointer authentication attributes.
+ const CodeGenOptions &CodeGenOpts = CGM.getCodeGenOpts();
+ if (CodeGenOpts.PointerAuth.ReturnAddresses)
+ Fn->addFnAttr("ptrauth-returns");
+ if (CodeGenOpts.PointerAuth.FunctionPointers)
+ Fn->addFnAttr("ptrauth-calls");
+ if (CodeGenOpts.PointerAuth.AuthTraps)
+ Fn->addFnAttr("ptrauth-auth-traps");
+ if (CodeGenOpts.PointerAuth.IndirectGotos)
+ Fn->addFnAttr("ptrauth-indirect-gotos");
+
// Apply xray attributes to the function (as a string, for now)
bool AlwaysXRayAttr = false;
if (const auto *XRayAttr = D ? D->getAttr<XRayInstrumentAttr>() : nullptr) {
@@ -937,6 +995,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
if (D && D->hasAttr<NoProfileFunctionAttr>())
Fn->addFnAttr(llvm::Attribute::NoProfile);
+ if (D && D->hasAttr<HybridPatchableAttr>())
+ Fn->addFnAttr(llvm::Attribute::HybridPatchable);
+
if (D) {
// Function attributes take precedence over command line flags.
if (auto *A = D->getAttr<FunctionReturnThunksAttr>()) {
@@ -957,6 +1018,11 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
EmitKernelMetadata(FD, Fn);
}
+ if (FD && FD->hasAttr<ClspvLibclcBuiltinAttr>()) {
+ Fn->setMetadata("clspv_libclc_builtin",
+ llvm::MDNode::get(getLLVMContext(), {}));
+ }
+
// If we are checking function types, emit a function type signature as
// prologue data.
if (FD && SanOpts.has(SanitizerKind::Function)) {
@@ -974,7 +1040,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
// return value. Initialize the flag to 'true' and refine it in EmitParmDecl.
if (SanOpts.has(SanitizerKind::NullabilityReturn)) {
auto Nullability = FnRetTy->getNullability();
- if (Nullability && *Nullability == NullabilityKind::NonNull) {
+ if (Nullability && *Nullability == NullabilityKind::NonNull &&
+ !FnRetTy->isRecordType()) {
if (!(SanOpts.has(SanitizerKind::ReturnsNonnullAttribute) &&
CurCodeDecl && CurCodeDecl->getAttr<ReturnsNonNullAttr>()))
RetValNullabilityPrecondition =
@@ -1117,13 +1184,14 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
auto AI = CurFn->arg_begin();
if (CurFnInfo->getReturnInfo().isSRetAfterThis())
++AI;
- ReturnValue =
- Address(&*AI, ConvertType(RetTy),
- CurFnInfo->getReturnInfo().getIndirectAlign(), KnownNonNull);
+ ReturnValue = makeNaturalAddressForPointer(
+ &*AI, RetTy, CurFnInfo->getReturnInfo().getIndirectAlign(), false,
+ nullptr, nullptr, KnownNonNull);
if (!CurFnInfo->getReturnInfo().getIndirectByVal()) {
- ReturnValuePointer = CreateDefaultAlignTempAlloca(
- ReturnValue.getPointer()->getType(), "result.ptr");
- Builder.CreateStore(ReturnValue.getPointer(), ReturnValuePointer);
+ ReturnValuePointer =
+ CreateDefaultAlignTempAlloca(ReturnValue.getType(), "result.ptr");
+ Builder.CreateStore(ReturnValue.emitRawPointer(*this),
+ ReturnValuePointer);
}
} else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::InAlloca &&
!hasScalarEvaluationKind(CurFnInfo->getReturnType())) {
@@ -1184,8 +1252,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
// or contains the address of the enclosing object).
LValue ThisFieldLValue = EmitLValueForLambdaField(LambdaThisCaptureField);
if (!LambdaThisCaptureField->getType()->isPointerType()) {
- // If the enclosing object was captured by value, just use its address.
- CXXThisValue = ThisFieldLValue.getAddress(*this).getPointer();
+ // If the enclosing object was captured by value, just use its
+ // address. Sign this pointer.
+ CXXThisValue = ThisFieldLValue.getPointer(*this);
} else {
// Load the lvalue pointed to by the field, since '*this' was captured
// by reference.
@@ -1252,6 +1321,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
if (CurFuncDecl)
if (const auto *VecWidth = CurFuncDecl->getAttr<MinVectorWidthAttr>())
LargestVectorWidth = VecWidth->getVectorWidth();
+
+ if (CGM.shouldEmitConvergenceTokens())
+ ConvergenceTokenStack.push_back(getOrEmitConvergenceEntryToken(CurFn));
}
void CodeGenFunction::EmitFunctionBody(const Stmt *Body) {
@@ -1270,7 +1342,10 @@ void CodeGenFunction::EmitFunctionBody(const Stmt *Body) {
void CodeGenFunction::EmitBlockWithFallThrough(llvm::BasicBlock *BB,
const Stmt *S) {
llvm::BasicBlock *SkipCountBB = nullptr;
- if (HaveInsertPoint() && CGM.getCodeGenOpts().hasProfileClangInstr()) {
+ // Do not skip over the instrumentation when single byte coverage mode is
+ // enabled.
+ if (HaveInsertPoint() && CGM.getCodeGenOpts().hasProfileClangInstr() &&
+ !llvm::EnableSingleByteCoverage) {
// When instrumenting for profiling, the fallthrough to certain
// statements needs to skip over the instrumentation code so that we
// get an accurate count.
@@ -1353,6 +1428,8 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
FunctionArgList Args;
QualType ResTy = BuildFunctionArgList(GD, Args);
+ CGM.getTargetCodeGenInfo().checkFunctionABI(CGM, FD);
+
if (FD->isInlineBuiltinDeclaration()) {
// When generating code for a builtin with an inline declaration, use a
// mangled name to hold the actual body, while keeping an external
@@ -1441,6 +1518,8 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
// Ensure that the function adheres to the forward progress guarantee, which
// is required by certain optimizations.
+ // In C++11 and up, the attribute will be removed if the body contains a
+ // trivial empty loop.
if (checkIfFunctionMustProgress())
CurFn->addFnAttr(llvm::Attribute::MustProgress);
@@ -2002,8 +2081,9 @@ static void emitNonZeroVLAInit(CodeGenFunction &CGF, QualType baseType,
= llvm::ConstantInt::get(CGF.IntPtrTy, baseSize.getQuantity());
Address begin = dest.withElementType(CGF.Int8Ty);
- llvm::Value *end = Builder.CreateInBoundsGEP(
- begin.getElementType(), begin.getPointer(), sizeInChars, "vla.end");
+ llvm::Value *end = Builder.CreateInBoundsGEP(begin.getElementType(),
+ begin.emitRawPointer(CGF),
+ sizeInChars, "vla.end");
llvm::BasicBlock *originBB = CGF.Builder.GetInsertBlock();
llvm::BasicBlock *loopBB = CGF.createBasicBlock("vla-init.loop");
@@ -2014,7 +2094,7 @@ static void emitNonZeroVLAInit(CodeGenFunction &CGF, QualType baseType,
CGF.EmitBlock(loopBB);
llvm::PHINode *cur = Builder.CreatePHI(begin.getType(), 2, "vla.cur");
- cur->addIncoming(begin.getPointer(), originBB);
+ cur->addIncoming(begin.emitRawPointer(CGF), originBB);
CharUnits curAlign =
dest.getAlignment().alignmentOfArrayElement(baseSize);
@@ -2179,8 +2259,8 @@ llvm::Value *CodeGenFunction::emitArrayLength(const ArrayType *origArrayType,
dyn_cast<llvm::ArrayType>(addr.getElementType());
while (llvmArrayType) {
assert(isa<ConstantArrayType>(arrayType));
- assert(cast<ConstantArrayType>(arrayType)->getSize().getZExtValue()
- == llvmArrayType->getNumElements());
+ assert(cast<ConstantArrayType>(arrayType)->getZExtSize() ==
+ llvmArrayType->getNumElements());
gepIndices.push_back(zero);
countFromCLAs *= llvmArrayType->getNumElements();
@@ -2198,8 +2278,7 @@ llvm::Value *CodeGenFunction::emitArrayLength(const ArrayType *origArrayType,
// as some other type (probably a packed struct). Compute the array
// size, and just emit the 'begin' expression as a bitcast.
while (arrayType) {
- countFromCLAs *=
- cast<ConstantArrayType>(arrayType)->getSize().getZExtValue();
+ countFromCLAs *= cast<ConstantArrayType>(arrayType)->getZExtSize();
eltType = arrayType->getElementType();
arrayType = getContext().getAsArrayType(eltType);
}
@@ -2208,10 +2287,10 @@ llvm::Value *CodeGenFunction::emitArrayLength(const ArrayType *origArrayType,
addr = addr.withElementType(baseType);
} else {
// Create the actual GEP.
- addr = Address(Builder.CreateInBoundsGEP(
- addr.getElementType(), addr.getPointer(), gepIndices, "array.begin"),
- ConvertTypeForMem(eltType),
- addr.getAlignment());
+ addr = Address(Builder.CreateInBoundsGEP(addr.getElementType(),
+ addr.emitRawPointer(*this),
+ gepIndices, "array.begin"),
+ ConvertTypeForMem(eltType), addr.getAlignment());
}
baseType = eltType;
@@ -2339,6 +2418,7 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
type = cast<MemberPointerType>(ty)->getPointeeType();
break;
+ case Type::ArrayParameter:
case Type::ConstantArray:
case Type::IncompleteArray:
// Losing element qualification here is fine.
@@ -2399,6 +2479,7 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
case Type::BTFTagAttributed:
case Type::SubstTemplateTypeParm:
case Type::MacroQualified:
+ case Type::CountAttributed:
// Keep walking after single level desugaring.
type = type.getSingleStepDesugaredType(getContext());
break;
@@ -2407,6 +2488,7 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
case Type::Decltype:
case Type::Auto:
case Type::DeducedTemplateSpecialization:
+ case Type::PackIndexing:
// Stop walking: nothing to do.
return;
@@ -2429,11 +2511,11 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
Address CodeGenFunction::EmitVAListRef(const Expr* E) {
if (getContext().getBuiltinVaListType()->isArrayType())
return EmitPointerWithAlignment(E);
- return EmitLValue(E).getAddress(*this);
+ return EmitLValue(E).getAddress();
}
Address CodeGenFunction::EmitMSVAListRef(const Expr *E) {
- return EmitLValue(E).getAddress(*this);
+ return EmitLValue(E).getAddress();
}
void CodeGenFunction::EmitDeclRefExprDbgValue(const DeclRefExpr *E,
@@ -2550,7 +2632,7 @@ void CodeGenFunction::EmitVarAnnotations(const VarDecl *D, llvm::Value *V) {
Address CodeGenFunction::EmitFieldAnnotations(const FieldDecl *D,
Address Addr) {
assert(D->hasAttr<AnnotateAttr>() && "no annotate attribute");
- llvm::Value *V = Addr.getPointer();
+ llvm::Value *V = Addr.emitRawPointer(*this);
llvm::Type *VTy = V->getType();
auto *PTy = dyn_cast<llvm::PointerType>(VTy);
unsigned AS = PTy ? PTy->getAddressSpace() : 0;
@@ -2586,7 +2668,6 @@ CodeGenFunction::SanitizerScope::~SanitizerScope() {
void CodeGenFunction::InsertHelper(llvm::Instruction *I,
const llvm::Twine &Name,
- llvm::BasicBlock *BB,
llvm::BasicBlock::iterator InsertPt) const {
LoopStack.InsertHelper(I);
if (IsSanitizerScope)
@@ -2594,17 +2675,35 @@ void CodeGenFunction::InsertHelper(llvm::Instruction *I,
}
void CGBuilderInserter::InsertHelper(
- llvm::Instruction *I, const llvm::Twine &Name, llvm::BasicBlock *BB,
+ llvm::Instruction *I, const llvm::Twine &Name,
llvm::BasicBlock::iterator InsertPt) const {
- llvm::IRBuilderDefaultInserter::InsertHelper(I, Name, BB, InsertPt);
+ llvm::IRBuilderDefaultInserter::InsertHelper(I, Name, InsertPt);
if (CGF)
- CGF->InsertHelper(I, Name, BB, InsertPt);
+ CGF->InsertHelper(I, Name, InsertPt);
}
// Emits an error if we don't have a valid set of target features for the
// called function.
void CodeGenFunction::checkTargetFeatures(const CallExpr *E,
const FunctionDecl *TargetDecl) {
+ // SemaChecking cannot handle below x86 builtins because they have different
+ // parameter ranges with different TargetAttribute of caller.
+ if (CGM.getContext().getTargetInfo().getTriple().isX86()) {
+ unsigned BuiltinID = TargetDecl->getBuiltinID();
+ if (BuiltinID == X86::BI__builtin_ia32_cmpps ||
+ BuiltinID == X86::BI__builtin_ia32_cmpss ||
+ BuiltinID == X86::BI__builtin_ia32_cmppd ||
+ BuiltinID == X86::BI__builtin_ia32_cmpsd) {
+ const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurCodeDecl);
+ llvm::StringMap<bool> TargetFetureMap;
+ CGM.getContext().getFunctionFeatureMap(TargetFetureMap, FD);
+ llvm::APSInt Result =
+ *(E->getArg(2)->getIntegerConstantExpr(CGM.getContext()));
+ if (Result.getSExtValue() > 7 && !TargetFetureMap.lookup("avx"))
+ CGM.getDiags().Report(E->getBeginLoc(), diag::err_builtin_needs_feature)
+ << TargetDecl->getDeclName() << "avx";
+ }
+ }
return checkTargetFeatures(E->getBeginLoc(), TargetDecl);
}
@@ -2707,11 +2806,8 @@ void CodeGenFunction::EmitKCFIOperandBundle(
llvm::Value *CodeGenFunction::FormAArch64ResolverCondition(
const MultiVersionResolverOption &RO) {
llvm::SmallVector<StringRef, 8> CondFeatures;
- for (const StringRef &Feature : RO.Conditions.Features) {
- // Form condition for features which are not yet enabled in target
- if (!getContext().getTargetInfo().hasFeature(Feature))
- CondFeatures.push_back(Feature);
- }
+ for (const StringRef &Feature : RO.Conditions.Features)
+ CondFeatures.push_back(Feature);
if (!CondFeatures.empty()) {
return EmitAArch64CpuSupports(CondFeatures);
}
@@ -2879,7 +2975,7 @@ void CodeGenFunction::emitAlignmentAssumptionCheck(
SourceLocation SecondaryLoc, llvm::Value *Alignment,
llvm::Value *OffsetValue, llvm::Value *TheCheck,
llvm::Instruction *Assumption) {
- assert(Assumption && isa<llvm::CallInst>(Assumption) &&
+ assert(isa_and_nonnull<llvm::CallInst>(Assumption) &&
cast<llvm::CallInst>(Assumption)->getCalledOperand() ==
llvm::Intrinsic::getDeclaration(
Builder.GetInsertBlock()->getParent()->getParent(),
@@ -2969,3 +3065,82 @@ llvm::Value *CodeGenFunction::emitBoolVecConversion(llvm::Value *SrcVec,
return Builder.CreateShuffleVector(SrcVec, ShuffleMask, Name);
}
+
+void CodeGenFunction::EmitPointerAuthOperandBundle(
+ const CGPointerAuthInfo &PointerAuth,
+ SmallVectorImpl<llvm::OperandBundleDef> &Bundles) {
+ if (!PointerAuth.isSigned())
+ return;
+
+ auto *Key = Builder.getInt32(PointerAuth.getKey());
+
+ llvm::Value *Discriminator = PointerAuth.getDiscriminator();
+ if (!Discriminator)
+ Discriminator = Builder.getSize(0);
+
+ llvm::Value *Args[] = {Key, Discriminator};
+ Bundles.emplace_back("ptrauth", Args);
+}
+
+static llvm::Value *EmitPointerAuthCommon(CodeGenFunction &CGF,
+ const CGPointerAuthInfo &PointerAuth,
+ llvm::Value *Pointer,
+ unsigned IntrinsicID) {
+ if (!PointerAuth)
+ return Pointer;
+
+ auto Key = CGF.Builder.getInt32(PointerAuth.getKey());
+
+ llvm::Value *Discriminator = PointerAuth.getDiscriminator();
+ if (!Discriminator) {
+ Discriminator = CGF.Builder.getSize(0);
+ }
+
+ // Convert the pointer to intptr_t before signing it.
+ auto OrigType = Pointer->getType();
+ Pointer = CGF.Builder.CreatePtrToInt(Pointer, CGF.IntPtrTy);
+
+ // call i64 @llvm.ptrauth.sign.i64(i64 %pointer, i32 %key, i64 %discriminator)
+ auto Intrinsic = CGF.CGM.getIntrinsic(IntrinsicID);
+ Pointer = CGF.EmitRuntimeCall(Intrinsic, {Pointer, Key, Discriminator});
+
+ // Convert back to the original type.
+ Pointer = CGF.Builder.CreateIntToPtr(Pointer, OrigType);
+ return Pointer;
+}
+
+llvm::Value *
+CodeGenFunction::EmitPointerAuthSign(const CGPointerAuthInfo &PointerAuth,
+ llvm::Value *Pointer) {
+ if (!PointerAuth.shouldSign())
+ return Pointer;
+ return EmitPointerAuthCommon(*this, PointerAuth, Pointer,
+ llvm::Intrinsic::ptrauth_sign);
+}
+
+static llvm::Value *EmitStrip(CodeGenFunction &CGF,
+ const CGPointerAuthInfo &PointerAuth,
+ llvm::Value *Pointer) {
+ auto StripIntrinsic = CGF.CGM.getIntrinsic(llvm::Intrinsic::ptrauth_strip);
+
+ auto Key = CGF.Builder.getInt32(PointerAuth.getKey());
+ // Convert the pointer to intptr_t before signing it.
+ auto OrigType = Pointer->getType();
+ Pointer = CGF.EmitRuntimeCall(
+ StripIntrinsic, {CGF.Builder.CreatePtrToInt(Pointer, CGF.IntPtrTy), Key});
+ return CGF.Builder.CreateIntToPtr(Pointer, OrigType);
+}
+
+llvm::Value *
+CodeGenFunction::EmitPointerAuthAuth(const CGPointerAuthInfo &PointerAuth,
+ llvm::Value *Pointer) {
+ if (PointerAuth.shouldStrip()) {
+ return EmitStrip(*this, PointerAuth, Pointer);
+ }
+ if (!PointerAuth.shouldAuth()) {
+ return Pointer;
+ }
+
+ return EmitPointerAuthCommon(*this, PointerAuth, Pointer,
+ llvm::Intrinsic::ptrauth_auth);
+}