1ec2b103cSEd Schouten //===--- CodeGenFunction.cpp - Emit LLVM Code from ASTs for a Function ----===//
2ec2b103cSEd Schouten //
322989816SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
422989816SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
522989816SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ec2b103cSEd Schouten //
7ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
8ec2b103cSEd Schouten //
9ec2b103cSEd Schouten // This coordinates the per-function state used while generating code.
10ec2b103cSEd Schouten //
11ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
12ec2b103cSEd Schouten
13ec2b103cSEd Schouten #include "CodeGenFunction.h"
1445b53394SDimitry Andric #include "CGBlocks.h"
1536981b17SDimitry Andric #include "CGCUDARuntime.h"
163d1dcd9bSDimitry Andric #include "CGCXXABI.h"
17706b4fc4SDimitry Andric #include "CGCleanup.h"
18ec2b103cSEd Schouten #include "CGDebugInfo.h"
19e3b55780SDimitry Andric #include "CGHLSLRuntime.h"
209f4dbff6SDimitry Andric #include "CGOpenMPRuntime.h"
21809500fcSDimitry Andric #include "CodeGenModule.h"
229f4dbff6SDimitry Andric #include "CodeGenPGO.h"
23bfef3995SDimitry Andric #include "TargetInfo.h"
24ec2b103cSEd Schouten #include "clang/AST/ASTContext.h"
25ef2abedbSDimitry Andric #include "clang/AST/ASTLambda.h"
26706b4fc4SDimitry Andric #include "clang/AST/Attr.h"
27ec2b103cSEd Schouten #include "clang/AST/Decl.h"
28ec2b103cSEd Schouten #include "clang/AST/DeclCXX.h"
29b60736ecSDimitry Andric #include "clang/AST/Expr.h"
3034d02d0bSRoman Divacky #include "clang/AST/StmtCXX.h"
3117c7957fSDimitry Andric #include "clang/AST/StmtObjC.h"
3245b53394SDimitry Andric #include "clang/Basic/Builtins.h"
33676fbe81SDimitry Andric #include "clang/Basic/CodeGenOptions.h"
34ac9a064cSDimitry Andric #include "clang/Basic/TargetBuiltins.h"
35809500fcSDimitry Andric #include "clang/Basic/TargetInfo.h"
36bfef3995SDimitry Andric #include "clang/CodeGen/CGFunctionInfo.h"
37676fbe81SDimitry Andric #include "clang/Frontend/FrontendDiagnostic.h"
38b60736ecSDimitry Andric #include "llvm/ADT/ArrayRef.h"
39cfca06d7SDimitry Andric #include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
40809500fcSDimitry Andric #include "llvm/IR/DataLayout.h"
41461a67faSDimitry Andric #include "llvm/IR/Dominators.h"
42706b4fc4SDimitry Andric #include "llvm/IR/FPEnv.h"
43706b4fc4SDimitry Andric #include "llvm/IR/IntrinsicInst.h"
44809500fcSDimitry Andric #include "llvm/IR/Intrinsics.h"
45809500fcSDimitry Andric #include "llvm/IR/MDBuilder.h"
46809500fcSDimitry Andric #include "llvm/IR/Operator.h"
47b60736ecSDimitry Andric #include "llvm/Support/CRC.h"
487fa27ce4SDimitry Andric #include "llvm/Support/xxhash.h"
49b60736ecSDimitry Andric #include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
50461a67faSDimitry Andric #include "llvm/Transforms/Utils/PromoteMemToReg.h"
51e3b55780SDimitry Andric #include <optional>
52c0981da4SDimitry Andric
53ec2b103cSEd Schouten using namespace clang;
54ec2b103cSEd Schouten using namespace CodeGen;
55ec2b103cSEd Schouten
56ac9a064cSDimitry Andric namespace llvm {
57ac9a064cSDimitry Andric extern cl::opt<bool> EnableSingleByteCoverage;
58ac9a064cSDimitry Andric } // namespace llvm
59ac9a064cSDimitry Andric
60bab175ecSDimitry Andric /// shouldEmitLifetimeMarkers - Decide whether we need emit the life-time
61bab175ecSDimitry Andric /// markers.
shouldEmitLifetimeMarkers(const CodeGenOptions & CGOpts,const LangOptions & LangOpts)62bab175ecSDimitry Andric static bool shouldEmitLifetimeMarkers(const CodeGenOptions &CGOpts,
63bab175ecSDimitry Andric const LangOptions &LangOpts) {
64fdc82ccbSDimitry Andric if (CGOpts.DisableLifetimeMarkers)
65fdc82ccbSDimitry Andric return false;
66fdc82ccbSDimitry Andric
67519fc96cSDimitry Andric // Sanitizers may use markers.
68519fc96cSDimitry Andric if (CGOpts.SanitizeAddressUseAfterScope ||
69519fc96cSDimitry Andric LangOpts.Sanitize.has(SanitizerKind::HWAddress) ||
70519fc96cSDimitry Andric LangOpts.Sanitize.has(SanitizerKind::Memory))
717442d6faSDimitry Andric return true;
727442d6faSDimitry Andric
73bab175ecSDimitry Andric // For now, only in optimized builds.
74bab175ecSDimitry Andric return CGOpts.OptimizationLevel != 0;
75bab175ecSDimitry Andric }
76bab175ecSDimitry Andric
CodeGenFunction(CodeGenModule & cgm,bool suppressNewContext)7756d91b49SDimitry Andric CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)
786a037251SDimitry Andric : CodeGenTypeCache(cgm), CGM(cgm), Target(cgm.getTarget()),
7945b53394SDimitry Andric Builder(cgm, cgm.getModule().getContext(), llvm::ConstantFolder(),
809f4dbff6SDimitry Andric CGBuilderInserterTy(this)),
81cfca06d7SDimitry Andric SanOpts(CGM.getLangOpts().Sanitize), CurFPFeatures(CGM.getLangOpts()),
82cfca06d7SDimitry Andric DebugInfo(CGM.getModuleDebugInfo()), PGO(cgm),
83cfca06d7SDimitry Andric ShouldEmitLifetimeMarkers(
84cfca06d7SDimitry Andric shouldEmitLifetimeMarkers(CGM.getCodeGenOpts(), CGM.getLangOpts())) {
8556d91b49SDimitry Andric if (!suppressNewContext)
863d1dcd9bSDimitry Andric CGM.getCXXABI().getMangleContext().startNewFunction();
87344a3780SDimitry Andric EHStack.setCGF(this);
88809500fcSDimitry Andric
89cfca06d7SDimitry Andric SetFastMathFlags(CurFPFeatures);
90ec2b103cSEd Schouten }
91ec2b103cSEd Schouten
~CodeGenFunction()92dbe13110SDimitry Andric CodeGenFunction::~CodeGenFunction() {
93bfef3995SDimitry Andric assert(LifetimeExtendedCleanupStack.empty() && "failed to emit a cleanup");
94ac9a064cSDimitry Andric assert(DeferredDeactivationCleanupStack.empty() &&
95ac9a064cSDimitry Andric "missed to deactivate a cleanup");
96bfef3995SDimitry Andric
97d1b6c770SDimitry Andric if (getLangOpts().OpenMP && CurFn)
985e20cdd8SDimitry Andric CGM.getOpenMPRuntime().functionFinished(*this);
99dbe13110SDimitry Andric
100cfca06d7SDimitry Andric // If we have an OpenMPIRBuilder we want to finalize functions (incl.
101cfca06d7SDimitry Andric // outlining etc) at some point. Doing it once the function codegen is done
102cfca06d7SDimitry Andric // seems to be a reasonable spot. We do it here, as opposed to the deletion
103cfca06d7SDimitry Andric // time of the CodeGenModule, because we have to ensure the IR has not yet
104cfca06d7SDimitry Andric // been "emitted" to the outside, thus, modifications are still sensible.
105344a3780SDimitry Andric if (CGM.getLangOpts().OpenMPIRBuilder && CurFn)
106344a3780SDimitry Andric CGM.getOpenMPRuntime().getOMPBuilder().finalize(CurFn);
107706b4fc4SDimitry Andric }
108706b4fc4SDimitry Andric
109706b4fc4SDimitry Andric // Map the LangOption for exception behavior into
110706b4fc4SDimitry Andric // the corresponding enum in the IR.
111cfca06d7SDimitry Andric llvm::fp::ExceptionBehavior
ToConstrainedExceptMD(LangOptions::FPExceptionModeKind Kind)112cfca06d7SDimitry Andric clang::ToConstrainedExceptMD(LangOptions::FPExceptionModeKind Kind) {
113706b4fc4SDimitry Andric
114706b4fc4SDimitry Andric switch (Kind) {
115706b4fc4SDimitry Andric case LangOptions::FPE_Ignore: return llvm::fp::ebIgnore;
116706b4fc4SDimitry Andric case LangOptions::FPE_MayTrap: return llvm::fp::ebMayTrap;
117706b4fc4SDimitry Andric case LangOptions::FPE_Strict: return llvm::fp::ebStrict;
118145449b1SDimitry Andric default:
119706b4fc4SDimitry Andric llvm_unreachable("Unsupported FP Exception Behavior");
120706b4fc4SDimitry Andric }
121145449b1SDimitry Andric }
122706b4fc4SDimitry Andric
SetFastMathFlags(FPOptions FPFeatures)123cfca06d7SDimitry Andric void CodeGenFunction::SetFastMathFlags(FPOptions FPFeatures) {
124cfca06d7SDimitry Andric llvm::FastMathFlags FMF;
125cfca06d7SDimitry Andric FMF.setAllowReassoc(FPFeatures.getAllowFPReassociate());
126cfca06d7SDimitry Andric FMF.setNoNaNs(FPFeatures.getNoHonorNaNs());
127cfca06d7SDimitry Andric FMF.setNoInfs(FPFeatures.getNoHonorInfs());
128cfca06d7SDimitry Andric FMF.setNoSignedZeros(FPFeatures.getNoSignedZero());
129cfca06d7SDimitry Andric FMF.setAllowReciprocal(FPFeatures.getAllowReciprocal());
130cfca06d7SDimitry Andric FMF.setApproxFunc(FPFeatures.getAllowApproxFunc());
131cfca06d7SDimitry Andric FMF.setAllowContract(FPFeatures.allowFPContractAcrossStatement());
132cfca06d7SDimitry Andric Builder.setFastMathFlags(FMF);
13345b53394SDimitry Andric }
13445b53394SDimitry Andric
CGFPOptionsRAII(CodeGenFunction & CGF,const Expr * E)135cfca06d7SDimitry Andric CodeGenFunction::CGFPOptionsRAII::CGFPOptionsRAII(CodeGenFunction &CGF,
136b60736ecSDimitry Andric const Expr *E)
137b60736ecSDimitry Andric : CGF(CGF) {
138b60736ecSDimitry Andric ConstructorHelper(E->getFPFeaturesInEffect(CGF.getLangOpts()));
139b60736ecSDimitry Andric }
140b60736ecSDimitry Andric
CGFPOptionsRAII(CodeGenFunction & CGF,FPOptions FPFeatures)141b60736ecSDimitry Andric CodeGenFunction::CGFPOptionsRAII::CGFPOptionsRAII(CodeGenFunction &CGF,
142cfca06d7SDimitry Andric FPOptions FPFeatures)
143b60736ecSDimitry Andric : CGF(CGF) {
144b60736ecSDimitry Andric ConstructorHelper(FPFeatures);
145b60736ecSDimitry Andric }
146b60736ecSDimitry Andric
ConstructorHelper(FPOptions FPFeatures)147b60736ecSDimitry Andric void CodeGenFunction::CGFPOptionsRAII::ConstructorHelper(FPOptions FPFeatures) {
148b60736ecSDimitry Andric OldFPFeatures = CGF.CurFPFeatures;
149cfca06d7SDimitry Andric CGF.CurFPFeatures = FPFeatures;
150461a67faSDimitry Andric
151b60736ecSDimitry Andric OldExcept = CGF.Builder.getDefaultConstrainedExcept();
152b60736ecSDimitry Andric OldRounding = CGF.Builder.getDefaultConstrainedRounding();
153b60736ecSDimitry Andric
154cfca06d7SDimitry Andric if (OldFPFeatures == FPFeatures)
155cfca06d7SDimitry Andric return;
156cfca06d7SDimitry Andric
157cfca06d7SDimitry Andric FMFGuard.emplace(CGF.Builder);
158cfca06d7SDimitry Andric
159145449b1SDimitry Andric llvm::RoundingMode NewRoundingBehavior = FPFeatures.getRoundingMode();
160cfca06d7SDimitry Andric CGF.Builder.setDefaultConstrainedRounding(NewRoundingBehavior);
161cfca06d7SDimitry Andric auto NewExceptionBehavior =
162cfca06d7SDimitry Andric ToConstrainedExceptMD(static_cast<LangOptions::FPExceptionModeKind>(
163145449b1SDimitry Andric FPFeatures.getExceptionMode()));
164cfca06d7SDimitry Andric CGF.Builder.setDefaultConstrainedExcept(NewExceptionBehavior);
165cfca06d7SDimitry Andric
166cfca06d7SDimitry Andric CGF.SetFastMathFlags(FPFeatures);
167cfca06d7SDimitry Andric
168cfca06d7SDimitry Andric assert((CGF.CurFuncDecl == nullptr || CGF.Builder.getIsFPConstrained() ||
169cfca06d7SDimitry Andric isa<CXXConstructorDecl>(CGF.CurFuncDecl) ||
170cfca06d7SDimitry Andric isa<CXXDestructorDecl>(CGF.CurFuncDecl) ||
171cfca06d7SDimitry Andric (NewExceptionBehavior == llvm::fp::ebIgnore &&
172cfca06d7SDimitry Andric NewRoundingBehavior == llvm::RoundingMode::NearestTiesToEven)) &&
173cfca06d7SDimitry Andric "FPConstrained should be enabled on entire function");
174cfca06d7SDimitry Andric
175cfca06d7SDimitry Andric auto mergeFnAttrValue = [&](StringRef Name, bool Value) {
176cfca06d7SDimitry Andric auto OldValue =
177344a3780SDimitry Andric CGF.CurFn->getFnAttribute(Name).getValueAsBool();
178cfca06d7SDimitry Andric auto NewValue = OldValue & Value;
179cfca06d7SDimitry Andric if (OldValue != NewValue)
180cfca06d7SDimitry Andric CGF.CurFn->addFnAttr(Name, llvm::toStringRef(NewValue));
181cfca06d7SDimitry Andric };
182cfca06d7SDimitry Andric mergeFnAttrValue("no-infs-fp-math", FPFeatures.getNoHonorInfs());
183cfca06d7SDimitry Andric mergeFnAttrValue("no-nans-fp-math", FPFeatures.getNoHonorNaNs());
184cfca06d7SDimitry Andric mergeFnAttrValue("no-signed-zeros-fp-math", FPFeatures.getNoSignedZero());
185e3b55780SDimitry Andric mergeFnAttrValue(
186e3b55780SDimitry Andric "unsafe-fp-math",
187e3b55780SDimitry Andric FPFeatures.getAllowFPReassociate() && FPFeatures.getAllowReciprocal() &&
188e3b55780SDimitry Andric FPFeatures.getAllowApproxFunc() && FPFeatures.getNoSignedZero() &&
189e3b55780SDimitry Andric FPFeatures.allowFPContractAcrossStatement());
19045b53394SDimitry Andric }
19145b53394SDimitry Andric
~CGFPOptionsRAII()192cfca06d7SDimitry Andric CodeGenFunction::CGFPOptionsRAII::~CGFPOptionsRAII() {
193cfca06d7SDimitry Andric CGF.CurFPFeatures = OldFPFeatures;
194b60736ecSDimitry Andric CGF.Builder.setDefaultConstrainedExcept(OldExcept);
195b60736ecSDimitry Andric CGF.Builder.setDefaultConstrainedRounding(OldRounding);
19645b53394SDimitry Andric }
19745b53394SDimitry Andric
198ac9a064cSDimitry Andric static LValue
makeNaturalAlignAddrLValue(llvm::Value * V,QualType T,bool ForPointeeType,bool MightBeSigned,CodeGenFunction & CGF,KnownNonNull_t IsKnownNonNull=NotKnownNonNull)199ac9a064cSDimitry Andric makeNaturalAlignAddrLValue(llvm::Value *V, QualType T, bool ForPointeeType,
200ac9a064cSDimitry Andric bool MightBeSigned, CodeGenFunction &CGF,
201ac9a064cSDimitry Andric KnownNonNull_t IsKnownNonNull = NotKnownNonNull) {
202aa803409SDimitry Andric LValueBaseInfo BaseInfo;
203461a67faSDimitry Andric TBAAAccessInfo TBAAInfo;
204ac9a064cSDimitry Andric CharUnits Alignment =
205ac9a064cSDimitry Andric CGF.CGM.getNaturalTypeAlignment(T, &BaseInfo, &TBAAInfo, ForPointeeType);
206ac9a064cSDimitry Andric Address Addr =
207ac9a064cSDimitry Andric MightBeSigned
208ac9a064cSDimitry Andric ? CGF.makeNaturalAddressForPointer(V, T, Alignment, false, nullptr,
209ac9a064cSDimitry Andric nullptr, IsKnownNonNull)
210ac9a064cSDimitry Andric : Address(V, CGF.ConvertTypeForMem(T), Alignment, IsKnownNonNull);
211ac9a064cSDimitry Andric return CGF.MakeAddrLValue(Addr, T, BaseInfo, TBAAInfo);
21245b53394SDimitry Andric }
21345b53394SDimitry Andric
214ac9a064cSDimitry Andric LValue
MakeNaturalAlignAddrLValue(llvm::Value * V,QualType T,KnownNonNull_t IsKnownNonNull)215ac9a064cSDimitry Andric CodeGenFunction::MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T,
216ac9a064cSDimitry Andric KnownNonNull_t IsKnownNonNull) {
217ac9a064cSDimitry Andric return ::makeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ false,
218ac9a064cSDimitry Andric /*MightBeSigned*/ true, *this,
219ac9a064cSDimitry Andric IsKnownNonNull);
220ac9a064cSDimitry Andric }
221ac9a064cSDimitry Andric
22245b53394SDimitry Andric LValue
MakeNaturalAlignPointeeAddrLValue(llvm::Value * V,QualType T)22345b53394SDimitry Andric CodeGenFunction::MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T) {
224ac9a064cSDimitry Andric return ::makeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ true,
225ac9a064cSDimitry Andric /*MightBeSigned*/ true, *this);
22645b53394SDimitry Andric }
22745b53394SDimitry Andric
MakeNaturalAlignRawAddrLValue(llvm::Value * V,QualType T)228ac9a064cSDimitry Andric LValue CodeGenFunction::MakeNaturalAlignRawAddrLValue(llvm::Value *V,
229ac9a064cSDimitry Andric QualType T) {
230ac9a064cSDimitry Andric return ::makeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ false,
231ac9a064cSDimitry Andric /*MightBeSigned*/ false, *this);
232ac9a064cSDimitry Andric }
233ac9a064cSDimitry Andric
MakeNaturalAlignPointeeRawAddrLValue(llvm::Value * V,QualType T)234ac9a064cSDimitry Andric LValue CodeGenFunction::MakeNaturalAlignPointeeRawAddrLValue(llvm::Value *V,
235ac9a064cSDimitry Andric QualType T) {
236ac9a064cSDimitry Andric return ::makeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ true,
237ac9a064cSDimitry Andric /*MightBeSigned*/ false, *this);
238ac9a064cSDimitry Andric }
239ec2b103cSEd Schouten
ConvertTypeForMem(QualType T)240180abc3dSDimitry Andric llvm::Type *CodeGenFunction::ConvertTypeForMem(QualType T) {
241ec2b103cSEd Schouten return CGM.getTypes().ConvertTypeForMem(T);
242ec2b103cSEd Schouten }
243ec2b103cSEd Schouten
ConvertType(QualType T)244180abc3dSDimitry Andric llvm::Type *CodeGenFunction::ConvertType(QualType T) {
245ec2b103cSEd Schouten return CGM.getTypes().ConvertType(T);
246ec2b103cSEd Schouten }
247ec2b103cSEd Schouten
convertTypeForLoadStore(QualType ASTTy,llvm::Type * LLVMTy)248ac9a064cSDimitry Andric llvm::Type *CodeGenFunction::convertTypeForLoadStore(QualType ASTTy,
249ac9a064cSDimitry Andric llvm::Type *LLVMTy) {
250ac9a064cSDimitry Andric return CGM.getTypes().convertTypeForLoadStore(ASTTy, LLVMTy);
251ac9a064cSDimitry Andric }
252ac9a064cSDimitry Andric
getEvaluationKind(QualType type)253809500fcSDimitry Andric TypeEvaluationKind CodeGenFunction::getEvaluationKind(QualType type) {
254809500fcSDimitry Andric type = type.getCanonicalType();
255809500fcSDimitry Andric while (true) {
256809500fcSDimitry Andric switch (type->getTypeClass()) {
25729cafa66SDimitry Andric #define TYPE(name, parent)
25829cafa66SDimitry Andric #define ABSTRACT_TYPE(name, parent)
25929cafa66SDimitry Andric #define NON_CANONICAL_TYPE(name, parent) case Type::name:
26029cafa66SDimitry Andric #define DEPENDENT_TYPE(name, parent) case Type::name:
26129cafa66SDimitry Andric #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(name, parent) case Type::name:
262519fc96cSDimitry Andric #include "clang/AST/TypeNodes.inc"
26329cafa66SDimitry Andric llvm_unreachable("non-canonical or dependent type in IR-generation");
26429cafa66SDimitry Andric
2656a037251SDimitry Andric case Type::Auto:
2667442d6faSDimitry Andric case Type::DeducedTemplateSpecialization:
2677442d6faSDimitry Andric llvm_unreachable("undeduced type in IR-generation");
2686a037251SDimitry Andric
269809500fcSDimitry Andric // Various scalar types.
27029cafa66SDimitry Andric case Type::Builtin:
27129cafa66SDimitry Andric case Type::Pointer:
27229cafa66SDimitry Andric case Type::BlockPointer:
27329cafa66SDimitry Andric case Type::LValueReference:
27429cafa66SDimitry Andric case Type::RValueReference:
27529cafa66SDimitry Andric case Type::MemberPointer:
27629cafa66SDimitry Andric case Type::Vector:
27729cafa66SDimitry Andric case Type::ExtVector:
278cfca06d7SDimitry Andric case Type::ConstantMatrix:
27929cafa66SDimitry Andric case Type::FunctionProto:
28029cafa66SDimitry Andric case Type::FunctionNoProto:
28129cafa66SDimitry Andric case Type::Enum:
28229cafa66SDimitry Andric case Type::ObjCObjectPointer:
2830414e226SDimitry Andric case Type::Pipe:
28477fc4c14SDimitry Andric case Type::BitInt:
285809500fcSDimitry Andric return TEK_Scalar;
28629cafa66SDimitry Andric
287809500fcSDimitry Andric // Complexes.
28829cafa66SDimitry Andric case Type::Complex:
289809500fcSDimitry Andric return TEK_Complex;
290809500fcSDimitry Andric
291809500fcSDimitry Andric // Arrays, records, and Objective-C objects.
29229cafa66SDimitry Andric case Type::ConstantArray:
29329cafa66SDimitry Andric case Type::IncompleteArray:
29429cafa66SDimitry Andric case Type::VariableArray:
29529cafa66SDimitry Andric case Type::Record:
29629cafa66SDimitry Andric case Type::ObjCObject:
29729cafa66SDimitry Andric case Type::ObjCInterface:
298ac9a064cSDimitry Andric case Type::ArrayParameter:
299809500fcSDimitry Andric return TEK_Aggregate;
30036981b17SDimitry Andric
301809500fcSDimitry Andric // We operate on atomic values according to their underlying type.
30236981b17SDimitry Andric case Type::Atomic:
303809500fcSDimitry Andric type = cast<AtomicType>(type)->getValueType();
304809500fcSDimitry Andric continue;
30529cafa66SDimitry Andric }
30629cafa66SDimitry Andric llvm_unreachable("unknown type kind!");
307ec2b103cSEd Schouten }
308809500fcSDimitry Andric }
309ec2b103cSEd Schouten
EmitReturnBlock()31006d4ba38SDimitry Andric llvm::DebugLoc CodeGenFunction::EmitReturnBlock() {
311ec2b103cSEd Schouten // For cleanliness, we try to avoid emitting the return block for
312ec2b103cSEd Schouten // simple cases.
313ec2b103cSEd Schouten llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
314ec2b103cSEd Schouten
315ec2b103cSEd Schouten if (CurBB) {
316ec2b103cSEd Schouten assert(!CurBB->getTerminator() && "Unexpected terminated block.");
317ec2b103cSEd Schouten
3184c8b2481SRoman Divacky // We have a valid insert point, reuse it if it is empty or there are no
3194c8b2481SRoman Divacky // explicit jumps to the return block.
3203d1dcd9bSDimitry Andric if (CurBB->empty() || ReturnBlock.getBlock()->use_empty()) {
3213d1dcd9bSDimitry Andric ReturnBlock.getBlock()->replaceAllUsesWith(CurBB);
3223d1dcd9bSDimitry Andric delete ReturnBlock.getBlock();
32322989816SDimitry Andric ReturnBlock = JumpDest();
3244c8b2481SRoman Divacky } else
3253d1dcd9bSDimitry Andric EmitBlock(ReturnBlock.getBlock());
32606d4ba38SDimitry Andric return llvm::DebugLoc();
327ec2b103cSEd Schouten }
328ec2b103cSEd Schouten
329ec2b103cSEd Schouten // Otherwise, if the return block is the target of a single direct
330ec2b103cSEd Schouten // branch then we can just put the code in that block instead. This
331ec2b103cSEd Schouten // cleans up functions which started with a unified return block.
3323d1dcd9bSDimitry Andric if (ReturnBlock.getBlock()->hasOneUse()) {
333ec2b103cSEd Schouten llvm::BranchInst *BI =
3349f4dbff6SDimitry Andric dyn_cast<llvm::BranchInst>(*ReturnBlock.getBlock()->user_begin());
3354ba67500SRoman Divacky if (BI && BI->isUnconditional() &&
3363d1dcd9bSDimitry Andric BI->getSuccessor(0) == ReturnBlock.getBlock()) {
33706d4ba38SDimitry Andric // Record/return the DebugLoc of the simple 'return' expression to be used
33806d4ba38SDimitry Andric // later by the actual 'ret' instruction.
33906d4ba38SDimitry Andric llvm::DebugLoc Loc = BI->getDebugLoc();
340ec2b103cSEd Schouten Builder.SetInsertPoint(BI->getParent());
341ec2b103cSEd Schouten BI->eraseFromParent();
3423d1dcd9bSDimitry Andric delete ReturnBlock.getBlock();
34322989816SDimitry Andric ReturnBlock = JumpDest();
34406d4ba38SDimitry Andric return Loc;
345ec2b103cSEd Schouten }
346ec2b103cSEd Schouten }
347ec2b103cSEd Schouten
348ec2b103cSEd Schouten // FIXME: We are at an unreachable point, there is no reason to emit the block
349ec2b103cSEd Schouten // unless it has uses. However, we still need a place to put the debug
350ec2b103cSEd Schouten // region.end for now.
351ec2b103cSEd Schouten
3523d1dcd9bSDimitry Andric EmitBlock(ReturnBlock.getBlock());
35306d4ba38SDimitry Andric return llvm::DebugLoc();
3544ba67500SRoman Divacky }
3554ba67500SRoman Divacky
EmitIfUsed(CodeGenFunction & CGF,llvm::BasicBlock * BB)3564ba67500SRoman Divacky static void EmitIfUsed(CodeGenFunction &CGF, llvm::BasicBlock *BB) {
3574ba67500SRoman Divacky if (!BB) return;
358e3b55780SDimitry Andric if (!BB->use_empty()) {
359e3b55780SDimitry Andric CGF.CurFn->insert(CGF.CurFn->end(), BB);
360e3b55780SDimitry Andric return;
361e3b55780SDimitry Andric }
3624ba67500SRoman Divacky delete BB;
363ec2b103cSEd Schouten }
364ec2b103cSEd Schouten
FinishFunction(SourceLocation EndLoc)365ec2b103cSEd Schouten void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
366ec2b103cSEd Schouten assert(BreakContinueStack.empty() &&
367ec2b103cSEd Schouten "mismatched push/pop in break/continue stack!");
368ac9a064cSDimitry Andric assert(LifetimeExtendedCleanupStack.empty() &&
369ac9a064cSDimitry Andric "mismatched push/pop of cleanups in EHStack!");
370ac9a064cSDimitry Andric assert(DeferredDeactivationCleanupStack.empty() &&
371ac9a064cSDimitry Andric "mismatched activate/deactivate of cleanups!");
372ac9a064cSDimitry Andric
373ac9a064cSDimitry Andric if (CGM.shouldEmitConvergenceTokens()) {
374ac9a064cSDimitry Andric ConvergenceTokenStack.pop_back();
375ac9a064cSDimitry Andric assert(ConvergenceTokenStack.empty() &&
376ac9a064cSDimitry Andric "mismatched push/pop in convergence stack!");
377ac9a064cSDimitry Andric }
378ec2b103cSEd Schouten
3796a037251SDimitry Andric bool OnlySimpleReturnStmts = NumSimpleReturnExprs > 0
380bfef3995SDimitry Andric && NumSimpleReturnExprs == NumReturnExprs
381bfef3995SDimitry Andric && ReturnBlock.getBlock()->use_empty();
382bfef3995SDimitry Andric // Usually the return expression is evaluated before the cleanup
383bfef3995SDimitry Andric // code. If the function contains only a simple return statement,
384bfef3995SDimitry Andric // such as a constant, the location before the cleanup code becomes
385bfef3995SDimitry Andric // the last useful breakpoint in the function, because the simple
386bfef3995SDimitry Andric // return expression will be evaluated after the cleanup code. To be
387bfef3995SDimitry Andric // safe, set the debug location for cleanup code to the location of
388bfef3995SDimitry Andric // the return statement. Otherwise the cleanup code should be at the
389bfef3995SDimitry Andric // end of the function's lexical scope.
390bfef3995SDimitry Andric //
391bfef3995SDimitry Andric // If there are multiple branches to the return block, the branch
392bfef3995SDimitry Andric // instructions will get the location of the return statements and
393bfef3995SDimitry Andric // all will be fine.
3946a037251SDimitry Andric if (CGDebugInfo *DI = getDebugInfo()) {
3956a037251SDimitry Andric if (OnlySimpleReturnStmts)
3966a037251SDimitry Andric DI->EmitLocation(Builder, LastStopPoint);
3976a037251SDimitry Andric else
398809500fcSDimitry Andric DI->EmitLocation(Builder, EndLoc);
3996a037251SDimitry Andric }
400809500fcSDimitry Andric
401180abc3dSDimitry Andric // Pop any cleanups that might have been associated with the
402180abc3dSDimitry Andric // parameters. Do this in whatever block we're currently in; it's
403180abc3dSDimitry Andric // important to do this before we enter the return block or return
404180abc3dSDimitry Andric // edges will be *really* confused.
4055e20cdd8SDimitry Andric bool HasCleanups = EHStack.stable_begin() != PrologueCleanupDepth;
4065e20cdd8SDimitry Andric bool HasOnlyLifetimeMarkers =
4075e20cdd8SDimitry Andric HasCleanups && EHStack.containsOnlyLifetimeMarkers(PrologueCleanupDepth);
4085e20cdd8SDimitry Andric bool EmitRetDbgLoc = !HasCleanups || HasOnlyLifetimeMarkers;
409e3b55780SDimitry Andric
410e3b55780SDimitry Andric std::optional<ApplyDebugLocation> OAL;
4115e20cdd8SDimitry Andric if (HasCleanups) {
4126a037251SDimitry Andric // Make sure the line table doesn't jump back into the body for
4136a037251SDimitry Andric // the ret after it's been at EndLoc.
414706b4fc4SDimitry Andric if (CGDebugInfo *DI = getDebugInfo()) {
4156a037251SDimitry Andric if (OnlySimpleReturnStmts)
4166a037251SDimitry Andric DI->EmitLocation(Builder, EndLoc);
417706b4fc4SDimitry Andric else
418706b4fc4SDimitry Andric // We may not have a valid end location. Try to apply it anyway, and
419706b4fc4SDimitry Andric // fall back to an artificial location if needed.
420e3b55780SDimitry Andric OAL = ApplyDebugLocation::CreateDefaultArtificial(*this, EndLoc);
421706b4fc4SDimitry Andric }
4225e20cdd8SDimitry Andric
4235e20cdd8SDimitry Andric PopCleanupBlocks(PrologueCleanupDepth);
4246a037251SDimitry Andric }
425180abc3dSDimitry Andric
426ec2b103cSEd Schouten // Emit function epilog (to return).
42706d4ba38SDimitry Andric llvm::DebugLoc Loc = EmitReturnBlock();
428ec2b103cSEd Schouten
429461a67faSDimitry Andric if (ShouldInstrumentFunction()) {
430461a67faSDimitry Andric if (CGM.getCodeGenOpts().InstrumentFunctions)
431461a67faSDimitry Andric CurFn->addFnAttr("instrument-function-exit", "__cyg_profile_func_exit");
432461a67faSDimitry Andric if (CGM.getCodeGenOpts().InstrumentFunctionsAfterInlining)
433461a67faSDimitry Andric CurFn->addFnAttr("instrument-function-exit-inlined",
434461a67faSDimitry Andric "__cyg_profile_func_exit");
435461a67faSDimitry Andric }
4364ba67500SRoman Divacky
437ec2b103cSEd Schouten // Emit debug descriptor for function end.
43806d4ba38SDimitry Andric if (CGDebugInfo *DI = getDebugInfo())
439551c6985SDimitry Andric DI->EmitFunctionEnd(Builder, CurFn);
440ec2b103cSEd Schouten
44106d4ba38SDimitry Andric // Reset the debug location to that of the simple 'return' expression, if any
44206d4ba38SDimitry Andric // rather than that of the end of the function's scope '}'.
44306d4ba38SDimitry Andric ApplyDebugLocation AL(*this, Loc);
444bfef3995SDimitry Andric EmitFunctionEpilog(*CurFnInfo, EmitRetDbgLoc, EndLoc);
44534d02d0bSRoman Divacky EmitEndEHSpec(CurCodeDecl);
446ec2b103cSEd Schouten
4474ba67500SRoman Divacky assert(EHStack.empty() &&
4484ba67500SRoman Divacky "did not remove all scopes from cleanup stack!");
4494ba67500SRoman Divacky
45051fb8b01SRoman Divacky // If someone did an indirect goto, emit the indirect goto block at the end of
45151fb8b01SRoman Divacky // the function.
45251fb8b01SRoman Divacky if (IndirectBranch) {
45351fb8b01SRoman Divacky EmitBlock(IndirectBranch->getParent());
45451fb8b01SRoman Divacky Builder.ClearInsertionPoint();
45551fb8b01SRoman Divacky }
45651fb8b01SRoman Divacky
45751ece4aaSDimitry Andric // If some of our locals escaped, insert a call to llvm.localescape in the
4585e20cdd8SDimitry Andric // entry block.
4595e20cdd8SDimitry Andric if (!EscapedLocals.empty()) {
4605e20cdd8SDimitry Andric // Invert the map from local to index into a simple vector. There should be
4615e20cdd8SDimitry Andric // no holes.
4625e20cdd8SDimitry Andric SmallVector<llvm::Value *, 4> EscapeArgs;
4635e20cdd8SDimitry Andric EscapeArgs.resize(EscapedLocals.size());
4645e20cdd8SDimitry Andric for (auto &Pair : EscapedLocals)
4655e20cdd8SDimitry Andric EscapeArgs[Pair.second] = Pair.first;
4665e20cdd8SDimitry Andric llvm::Function *FrameEscapeFn = llvm::Intrinsic::getDeclaration(
46751ece4aaSDimitry Andric &CGM.getModule(), llvm::Intrinsic::localescape);
46845b53394SDimitry Andric CGBuilderTy(*this, AllocaInsertPt).CreateCall(FrameEscapeFn, EscapeArgs);
4695e20cdd8SDimitry Andric }
4705e20cdd8SDimitry Andric
471ec2b103cSEd Schouten // Remove the AllocaInsertPt instruction, which is just a convenience for us.
472ec2b103cSEd Schouten llvm::Instruction *Ptr = AllocaInsertPt;
4739f4dbff6SDimitry Andric AllocaInsertPt = nullptr;
474ec2b103cSEd Schouten Ptr->eraseFromParent();
47551fb8b01SRoman Divacky
476c0981da4SDimitry Andric // PostAllocaInsertPt, if created, was lazily created when it was required,
477c0981da4SDimitry Andric // remove it now since it was just created for our own convenience.
478c0981da4SDimitry Andric if (PostAllocaInsertPt) {
479c0981da4SDimitry Andric llvm::Instruction *PostPtr = PostAllocaInsertPt;
480c0981da4SDimitry Andric PostAllocaInsertPt = nullptr;
481c0981da4SDimitry Andric PostPtr->eraseFromParent();
482c0981da4SDimitry Andric }
483c0981da4SDimitry Andric
48451fb8b01SRoman Divacky // If someone took the address of a label but never did an indirect goto, we
48551fb8b01SRoman Divacky // made a zero entry PHI node, which is illegal, zap it now.
48651fb8b01SRoman Divacky if (IndirectBranch) {
48751fb8b01SRoman Divacky llvm::PHINode *PN = cast<llvm::PHINode>(IndirectBranch->getAddress());
48851fb8b01SRoman Divacky if (PN->getNumIncomingValues() == 0) {
48951fb8b01SRoman Divacky PN->replaceAllUsesWith(llvm::UndefValue::get(PN->getType()));
49051fb8b01SRoman Divacky PN->eraseFromParent();
49151fb8b01SRoman Divacky }
49251fb8b01SRoman Divacky }
4934ba67500SRoman Divacky
49436981b17SDimitry Andric EmitIfUsed(*this, EHResumeBlock);
4954ba67500SRoman Divacky EmitIfUsed(*this, TerminateLandingPad);
4964ba67500SRoman Divacky EmitIfUsed(*this, TerminateHandler);
4974ba67500SRoman Divacky EmitIfUsed(*this, UnreachableBlock);
4984ba67500SRoman Divacky
49948675466SDimitry Andric for (const auto &FuncletAndParent : TerminateFunclets)
50048675466SDimitry Andric EmitIfUsed(*this, FuncletAndParent.second);
50148675466SDimitry Andric
5024ba67500SRoman Divacky if (CGM.getCodeGenOpts().EmitDeclMetadata)
5034ba67500SRoman Divacky EmitDeclMetadata();
5049f4dbff6SDimitry Andric
505344a3780SDimitry Andric for (const auto &R : DeferredReplacements) {
506344a3780SDimitry Andric if (llvm::Value *Old = R.first) {
507344a3780SDimitry Andric Old->replaceAllUsesWith(R.second);
508344a3780SDimitry Andric cast<llvm::Instruction>(Old)->eraseFromParent();
5099f4dbff6SDimitry Andric }
510344a3780SDimitry Andric }
511344a3780SDimitry Andric DeferredReplacements.clear();
512461a67faSDimitry Andric
513461a67faSDimitry Andric // Eliminate CleanupDestSlot alloca by replacing it with SSA values and
514461a67faSDimitry Andric // PHIs if the current function is a coroutine. We don't do it for all
515461a67faSDimitry Andric // functions as it may result in slight increase in numbers of instructions
516461a67faSDimitry Andric // if compiled with no optimizations. We do it for coroutine as the lifetime
517461a67faSDimitry Andric // of CleanupDestSlot alloca make correct coroutine frame building very
518461a67faSDimitry Andric // difficult.
51948675466SDimitry Andric if (NormalCleanupDest.isValid() && isCoroutine()) {
520461a67faSDimitry Andric llvm::DominatorTree DT(*CurFn);
52148675466SDimitry Andric llvm::PromoteMemToReg(
52248675466SDimitry Andric cast<llvm::AllocaInst>(NormalCleanupDest.getPointer()), DT);
52348675466SDimitry Andric NormalCleanupDest = Address::invalid();
524461a67faSDimitry Andric }
52548675466SDimitry Andric
526676fbe81SDimitry Andric // Scan function arguments for vector width.
527676fbe81SDimitry Andric for (llvm::Argument &A : CurFn->args())
528676fbe81SDimitry Andric if (auto *VT = dyn_cast<llvm::VectorType>(A.getType()))
529cfca06d7SDimitry Andric LargestVectorWidth =
530cfca06d7SDimitry Andric std::max((uint64_t)LargestVectorWidth,
531e3b55780SDimitry Andric VT->getPrimitiveSizeInBits().getKnownMinValue());
532676fbe81SDimitry Andric
533676fbe81SDimitry Andric // Update vector width based on return type.
534676fbe81SDimitry Andric if (auto *VT = dyn_cast<llvm::VectorType>(CurFn->getReturnType()))
535cfca06d7SDimitry Andric LargestVectorWidth =
536cfca06d7SDimitry Andric std::max((uint64_t)LargestVectorWidth,
537e3b55780SDimitry Andric VT->getPrimitiveSizeInBits().getKnownMinValue());
538676fbe81SDimitry Andric
539145449b1SDimitry Andric if (CurFnInfo->getMaxVectorWidth() > LargestVectorWidth)
540145449b1SDimitry Andric LargestVectorWidth = CurFnInfo->getMaxVectorWidth();
541145449b1SDimitry Andric
542b1c73532SDimitry Andric // Add the min-legal-vector-width attribute. This contains the max width from:
543676fbe81SDimitry Andric // 1. min-vector-width attribute used in the source program.
544676fbe81SDimitry Andric // 2. Any builtins used that have a vector width specified.
545676fbe81SDimitry Andric // 3. Values passed in and out of inline assembly.
546676fbe81SDimitry Andric // 4. Width of vector arguments and return types for this function.
547b1c73532SDimitry Andric // 5. Width of vector arguments and return types for functions called by this
548676fbe81SDimitry Andric // function.
549e3b55780SDimitry Andric if (getContext().getTargetInfo().getTriple().isX86())
550e3b55780SDimitry Andric CurFn->addFnAttr("min-legal-vector-width",
551e3b55780SDimitry Andric llvm::utostr(LargestVectorWidth));
55222989816SDimitry Andric
553c0981da4SDimitry Andric // Add vscale_range attribute if appropriate.
554e3b55780SDimitry Andric std::optional<std::pair<unsigned, unsigned>> VScaleRange =
555c0981da4SDimitry Andric getContext().getTargetInfo().getVScaleRange(getLangOpts());
556c0981da4SDimitry Andric if (VScaleRange) {
557c0981da4SDimitry Andric CurFn->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs(
558145449b1SDimitry Andric getLLVMContext(), VScaleRange->first, VScaleRange->second));
559344a3780SDimitry Andric }
560344a3780SDimitry Andric
56122989816SDimitry Andric // If we generated an unreachable return block, delete it now.
56222989816SDimitry Andric if (ReturnBlock.isValid() && ReturnBlock.getBlock()->use_empty()) {
56322989816SDimitry Andric Builder.ClearInsertionPoint();
56422989816SDimitry Andric ReturnBlock.getBlock()->eraseFromParent();
56522989816SDimitry Andric }
56622989816SDimitry Andric if (ReturnValue.isValid()) {
567ac9a064cSDimitry Andric auto *RetAlloca =
568ac9a064cSDimitry Andric dyn_cast<llvm::AllocaInst>(ReturnValue.emitRawPointer(*this));
56922989816SDimitry Andric if (RetAlloca && RetAlloca->use_empty()) {
57022989816SDimitry Andric RetAlloca->eraseFromParent();
57122989816SDimitry Andric ReturnValue = Address::invalid();
57222989816SDimitry Andric }
57322989816SDimitry Andric }
5744ba67500SRoman Divacky }
5754ba67500SRoman Divacky
5764ba67500SRoman Divacky /// ShouldInstrumentFunction - Return true if the current function should be
5774ba67500SRoman Divacky /// instrumented with __cyg_profile_func_* calls
ShouldInstrumentFunction()5784ba67500SRoman Divacky bool CodeGenFunction::ShouldInstrumentFunction() {
579461a67faSDimitry Andric if (!CGM.getCodeGenOpts().InstrumentFunctions &&
580461a67faSDimitry Andric !CGM.getCodeGenOpts().InstrumentFunctionsAfterInlining &&
581461a67faSDimitry Andric !CGM.getCodeGenOpts().InstrumentFunctionEntryBare)
5824ba67500SRoman Divacky return false;
58329cafa66SDimitry Andric if (!CurFuncDecl || CurFuncDecl->hasAttr<NoInstrumentFunctionAttr>())
5844ba67500SRoman Divacky return false;
5854ba67500SRoman Divacky return true;
5864ba67500SRoman Divacky }
5874ba67500SRoman Divacky
ShouldSkipSanitizerInstrumentation()588c0981da4SDimitry Andric bool CodeGenFunction::ShouldSkipSanitizerInstrumentation() {
589c0981da4SDimitry Andric if (!CurFuncDecl)
590c0981da4SDimitry Andric return false;
591c0981da4SDimitry Andric return CurFuncDecl->hasAttr<DisableSanitizerInstrumentationAttr>();
592c0981da4SDimitry Andric }
593c0981da4SDimitry Andric
5942b6b257fSDimitry Andric /// ShouldXRayInstrument - Return true if the current function should be
5952b6b257fSDimitry Andric /// instrumented with XRay nop sleds.
ShouldXRayInstrumentFunction() const5962b6b257fSDimitry Andric bool CodeGenFunction::ShouldXRayInstrumentFunction() const {
5972b6b257fSDimitry Andric return CGM.getCodeGenOpts().XRayInstrumentFunctions;
5982b6b257fSDimitry Andric }
5992b6b257fSDimitry Andric
600461a67faSDimitry Andric /// AlwaysEmitXRayCustomEvents - Return true if we should emit IR for calls to
60148675466SDimitry Andric /// the __xray_customevent(...) builtin calls, when doing XRay instrumentation.
AlwaysEmitXRayCustomEvents() const602461a67faSDimitry Andric bool CodeGenFunction::AlwaysEmitXRayCustomEvents() const {
60348675466SDimitry Andric return CGM.getCodeGenOpts().XRayInstrumentFunctions &&
60448675466SDimitry Andric (CGM.getCodeGenOpts().XRayAlwaysEmitCustomEvents ||
60548675466SDimitry Andric CGM.getCodeGenOpts().XRayInstrumentationBundle.Mask ==
60648675466SDimitry Andric XRayInstrKind::Custom);
60748675466SDimitry Andric }
60848675466SDimitry Andric
AlwaysEmitXRayTypedEvents() const60948675466SDimitry Andric bool CodeGenFunction::AlwaysEmitXRayTypedEvents() const {
61048675466SDimitry Andric return CGM.getCodeGenOpts().XRayInstrumentFunctions &&
61148675466SDimitry Andric (CGM.getCodeGenOpts().XRayAlwaysEmitTypedEvents ||
61248675466SDimitry Andric CGM.getCodeGenOpts().XRayInstrumentationBundle.Mask ==
61348675466SDimitry Andric XRayInstrKind::Typed);
614461a67faSDimitry Andric }
6154ba67500SRoman Divacky
6167fa27ce4SDimitry Andric llvm::ConstantInt *
getUBSanFunctionTypeHash(QualType Ty) const6177fa27ce4SDimitry Andric CodeGenFunction::getUBSanFunctionTypeHash(QualType Ty) const {
6187fa27ce4SDimitry Andric // Remove any (C++17) exception specifications, to allow calling e.g. a
6197fa27ce4SDimitry Andric // noexcept function through a non-noexcept pointer.
620b1c73532SDimitry Andric if (!Ty->isFunctionNoProtoType())
6217fa27ce4SDimitry Andric Ty = getContext().getFunctionTypeWithExceptionSpec(Ty, EST_None);
6227fa27ce4SDimitry Andric std::string Mangled;
6237fa27ce4SDimitry Andric llvm::raw_string_ostream Out(Mangled);
624b1c73532SDimitry Andric CGM.getCXXABI().getMangleContext().mangleCanonicalTypeName(Ty, Out, false);
6257fa27ce4SDimitry Andric return llvm::ConstantInt::get(
6267fa27ce4SDimitry Andric CGM.Int32Ty, static_cast<uint32_t>(llvm::xxh3_64bits(Mangled)));
627ec2b103cSEd Schouten }
628ec2b103cSEd Schouten
EmitKernelMetadata(const FunctionDecl * FD,llvm::Function * Fn)629145449b1SDimitry Andric void CodeGenFunction::EmitKernelMetadata(const FunctionDecl *FD,
630145449b1SDimitry Andric llvm::Function *Fn) {
631145449b1SDimitry Andric if (!FD->hasAttr<OpenCLKernelAttr>() && !FD->hasAttr<CUDAGlobalAttr>())
63256d91b49SDimitry Andric return;
63356d91b49SDimitry Andric
63456d91b49SDimitry Andric llvm::LLVMContext &Context = getLLVMContext();
63556d91b49SDimitry Andric
636145449b1SDimitry Andric CGM.GenKernelArgMetadata(Fn, FD, this);
637145449b1SDimitry Andric
638145449b1SDimitry Andric if (!getLangOpts().OpenCL)
639145449b1SDimitry Andric return;
640809500fcSDimitry Andric
6419f4dbff6SDimitry Andric if (const VecTypeHintAttr *A = FD->getAttr<VecTypeHintAttr>()) {
6420a5fb09bSDimitry Andric QualType HintQTy = A->getTypeHint();
6430a5fb09bSDimitry Andric const ExtVectorType *HintEltQTy = HintQTy->getAs<ExtVectorType>();
6440a5fb09bSDimitry Andric bool IsSignedInteger =
6450a5fb09bSDimitry Andric HintQTy->isSignedIntegerType() ||
6460a5fb09bSDimitry Andric (HintEltQTy && HintEltQTy->getElementType()->isSignedIntegerType());
6470a5fb09bSDimitry Andric llvm::Metadata *AttrMDArgs[] = {
64806d4ba38SDimitry Andric llvm::ConstantAsMetadata::get(llvm::UndefValue::get(
64906d4ba38SDimitry Andric CGM.getTypes().ConvertType(A->getTypeHint()))),
65006d4ba38SDimitry Andric llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
651809500fcSDimitry Andric llvm::IntegerType::get(Context, 32),
6520a5fb09bSDimitry Andric llvm::APInt(32, (uint64_t)(IsSignedInteger ? 1 : 0))))};
6530a5fb09bSDimitry Andric Fn->setMetadata("vec_type_hint", llvm::MDNode::get(Context, AttrMDArgs));
654809500fcSDimitry Andric }
65556d91b49SDimitry Andric
6569f4dbff6SDimitry Andric if (const WorkGroupSizeHintAttr *A = FD->getAttr<WorkGroupSizeHintAttr>()) {
6570a5fb09bSDimitry Andric llvm::Metadata *AttrMDArgs[] = {
65806d4ba38SDimitry Andric llvm::ConstantAsMetadata::get(Builder.getInt32(A->getXDim())),
65906d4ba38SDimitry Andric llvm::ConstantAsMetadata::get(Builder.getInt32(A->getYDim())),
66006d4ba38SDimitry Andric llvm::ConstantAsMetadata::get(Builder.getInt32(A->getZDim()))};
6610a5fb09bSDimitry Andric Fn->setMetadata("work_group_size_hint", llvm::MDNode::get(Context, AttrMDArgs));
66256d91b49SDimitry Andric }
66356d91b49SDimitry Andric
6649f4dbff6SDimitry Andric if (const ReqdWorkGroupSizeAttr *A = FD->getAttr<ReqdWorkGroupSizeAttr>()) {
6650a5fb09bSDimitry Andric llvm::Metadata *AttrMDArgs[] = {
66606d4ba38SDimitry Andric llvm::ConstantAsMetadata::get(Builder.getInt32(A->getXDim())),
66706d4ba38SDimitry Andric llvm::ConstantAsMetadata::get(Builder.getInt32(A->getYDim())),
66806d4ba38SDimitry Andric llvm::ConstantAsMetadata::get(Builder.getInt32(A->getZDim()))};
6690a5fb09bSDimitry Andric Fn->setMetadata("reqd_work_group_size", llvm::MDNode::get(Context, AttrMDArgs));
6700a5fb09bSDimitry Andric }
6710a5fb09bSDimitry Andric
6720a5fb09bSDimitry Andric if (const OpenCLIntelReqdSubGroupSizeAttr *A =
6730a5fb09bSDimitry Andric FD->getAttr<OpenCLIntelReqdSubGroupSizeAttr>()) {
6740a5fb09bSDimitry Andric llvm::Metadata *AttrMDArgs[] = {
6750a5fb09bSDimitry Andric llvm::ConstantAsMetadata::get(Builder.getInt32(A->getSubGroupSize()))};
6760a5fb09bSDimitry Andric Fn->setMetadata("intel_reqd_sub_group_size",
6770a5fb09bSDimitry Andric llvm::MDNode::get(Context, AttrMDArgs));
67856d91b49SDimitry Andric }
67956d91b49SDimitry Andric }
68056d91b49SDimitry Andric
6819f4dbff6SDimitry Andric /// Determine whether the function F ends with a return stmt.
endsWithReturn(const Decl * F)6829f4dbff6SDimitry Andric static bool endsWithReturn(const Decl* F) {
6839f4dbff6SDimitry Andric const Stmt *Body = nullptr;
6849f4dbff6SDimitry Andric if (auto *FD = dyn_cast_or_null<FunctionDecl>(F))
6859f4dbff6SDimitry Andric Body = FD->getBody();
6869f4dbff6SDimitry Andric else if (auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(F))
6879f4dbff6SDimitry Andric Body = OMD->getBody();
6889f4dbff6SDimitry Andric
6899f4dbff6SDimitry Andric if (auto *CS = dyn_cast_or_null<CompoundStmt>(Body)) {
6909f4dbff6SDimitry Andric auto LastStmt = CS->body_rbegin();
6919f4dbff6SDimitry Andric if (LastStmt != CS->body_rend())
6929f4dbff6SDimitry Andric return isa<ReturnStmt>(*LastStmt);
6939f4dbff6SDimitry Andric }
6949f4dbff6SDimitry Andric return false;
6959f4dbff6SDimitry Andric }
6969f4dbff6SDimitry Andric
markAsIgnoreThreadCheckingAtRuntime(llvm::Function * Fn)697676fbe81SDimitry Andric void CodeGenFunction::markAsIgnoreThreadCheckingAtRuntime(llvm::Function *Fn) {
698676fbe81SDimitry Andric if (SanOpts.has(SanitizerKind::Thread)) {
6997442d6faSDimitry Andric Fn->addFnAttr("sanitize_thread_no_checking_at_run_time");
7007442d6faSDimitry Andric Fn->removeFnAttr(llvm::Attribute::SanitizeThread);
7017442d6faSDimitry Andric }
702676fbe81SDimitry Andric }
7037442d6faSDimitry Andric
704706b4fc4SDimitry Andric /// Check if the return value of this function requires sanitization.
requiresReturnValueCheck() const705706b4fc4SDimitry Andric bool CodeGenFunction::requiresReturnValueCheck() const {
706706b4fc4SDimitry Andric return requiresReturnValueNullabilityCheck() ||
707706b4fc4SDimitry Andric (SanOpts.has(SanitizerKind::ReturnsNonnullAttribute) && CurCodeDecl &&
708706b4fc4SDimitry Andric CurCodeDecl->getAttr<ReturnsNonNullAttr>());
709706b4fc4SDimitry Andric }
710706b4fc4SDimitry Andric
matchesStlAllocatorFn(const Decl * D,const ASTContext & Ctx)711461a67faSDimitry Andric static bool matchesStlAllocatorFn(const Decl *D, const ASTContext &Ctx) {
712461a67faSDimitry Andric auto *MD = dyn_cast_or_null<CXXMethodDecl>(D);
713461a67faSDimitry Andric if (!MD || !MD->getDeclName().getAsIdentifierInfo() ||
714461a67faSDimitry Andric !MD->getDeclName().getAsIdentifierInfo()->isStr("allocate") ||
715461a67faSDimitry Andric (MD->getNumParams() != 1 && MD->getNumParams() != 2))
716461a67faSDimitry Andric return false;
717461a67faSDimitry Andric
718461a67faSDimitry Andric if (MD->parameters()[0]->getType().getCanonicalType() != Ctx.getSizeType())
719461a67faSDimitry Andric return false;
720461a67faSDimitry Andric
721461a67faSDimitry Andric if (MD->getNumParams() == 2) {
722461a67faSDimitry Andric auto *PT = MD->parameters()[1]->getType()->getAs<PointerType>();
723461a67faSDimitry Andric if (!PT || !PT->isVoidPointerType() ||
724461a67faSDimitry Andric !PT->getPointeeType().isConstQualified())
725461a67faSDimitry Andric return false;
726461a67faSDimitry Andric }
727461a67faSDimitry Andric
728461a67faSDimitry Andric return true;
729461a67faSDimitry Andric }
730461a67faSDimitry Andric
isInAllocaArgument(CGCXXABI & ABI,QualType Ty)731b1c73532SDimitry Andric bool CodeGenFunction::isInAllocaArgument(CGCXXABI &ABI, QualType Ty) {
732b1c73532SDimitry Andric const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
733b1c73532SDimitry Andric return RD && ABI.getRecordArgABI(RD) == CGCXXABI::RAA_DirectInMemory;
734b1c73532SDimitry Andric }
735b1c73532SDimitry Andric
hasInAllocaArg(const CXXMethodDecl * MD)736b1c73532SDimitry Andric bool CodeGenFunction::hasInAllocaArg(const CXXMethodDecl *MD) {
737b1c73532SDimitry Andric return getTarget().getTriple().getArch() == llvm::Triple::x86 &&
738b1c73532SDimitry Andric getTarget().getCXXABI().isMicrosoft() &&
739b1c73532SDimitry Andric llvm::any_of(MD->parameters(), [&](ParmVarDecl *P) {
740b1c73532SDimitry Andric return isInAllocaArgument(CGM.getCXXABI(), P->getType());
741b1c73532SDimitry Andric });
742b1c73532SDimitry Andric }
743b1c73532SDimitry Andric
744461a67faSDimitry Andric /// Return the UBSan prologue signature for \p FD if one is available.
getPrologueSignature(CodeGenModule & CGM,const FunctionDecl * FD)745461a67faSDimitry Andric static llvm::Constant *getPrologueSignature(CodeGenModule &CGM,
746461a67faSDimitry Andric const FunctionDecl *FD) {
747461a67faSDimitry Andric if (const auto *MD = dyn_cast<CXXMethodDecl>(FD))
748461a67faSDimitry Andric if (!MD->isStatic())
749461a67faSDimitry Andric return nullptr;
750461a67faSDimitry Andric return CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM);
751461a67faSDimitry Andric }
752461a67faSDimitry Andric
StartFunction(GlobalDecl GD,QualType RetTy,llvm::Function * Fn,const CGFunctionInfo & FnInfo,const FunctionArgList & Args,SourceLocation Loc,SourceLocation StartLoc)753706b4fc4SDimitry Andric void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
754ec2b103cSEd Schouten llvm::Function *Fn,
75501af97d3SDimitry Andric const CGFunctionInfo &FnInfo,
756ec2b103cSEd Schouten const FunctionArgList &Args,
7579f4dbff6SDimitry Andric SourceLocation Loc,
758ec2b103cSEd Schouten SourceLocation StartLoc) {
75906d4ba38SDimitry Andric assert(!CurFn &&
76006d4ba38SDimitry Andric "Do not use a CodeGenFunction object for more than one function");
76106d4ba38SDimitry Andric
7624c8b2481SRoman Divacky const Decl *D = GD.getDecl();
7634c8b2481SRoman Divacky
764ec2b103cSEd Schouten DidCallStackSave = false;
7656a037251SDimitry Andric CurCodeDecl = D;
766344a3780SDimitry Andric const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
767344a3780SDimitry Andric if (FD && FD->usesSEHTry())
768e3b55780SDimitry Andric CurSEHParent = GD;
7699f4dbff6SDimitry Andric CurFuncDecl = (D ? D->getNonClosureContext() : nullptr);
770ec2b103cSEd Schouten FnRetTy = RetTy;
771ec2b103cSEd Schouten CurFn = Fn;
77201af97d3SDimitry Andric CurFnInfo = &FnInfo;
773ec2b103cSEd Schouten assert(CurFn->isDeclaration() && "Function already has body?");
774ec2b103cSEd Schouten
775344a3780SDimitry Andric // If this function is ignored for any of the enabled sanitizers,
776461a67faSDimitry Andric // disable the sanitizer for the function.
777461a67faSDimitry Andric do {
778461a67faSDimitry Andric #define SANITIZER(NAME, ID) \
779461a67faSDimitry Andric if (SanOpts.empty()) \
780461a67faSDimitry Andric break; \
781461a67faSDimitry Andric if (SanOpts.has(SanitizerKind::ID)) \
782344a3780SDimitry Andric if (CGM.isInNoSanitizeList(SanitizerKind::ID, Fn, Loc)) \
783461a67faSDimitry Andric SanOpts.set(SanitizerKind::ID, false);
784461a67faSDimitry Andric
785461a67faSDimitry Andric #include "clang/Basic/Sanitizers.def"
786461a67faSDimitry Andric #undef SANITIZER
7876f8fc217SDimitry Andric } while (false);
788809500fcSDimitry Andric
7895e20cdd8SDimitry Andric if (D) {
790145449b1SDimitry Andric const bool SanitizeBounds = SanOpts.hasOneOf(SanitizerKind::Bounds);
7917fa27ce4SDimitry Andric SanitizerMask no_sanitize_mask;
792344a3780SDimitry Andric bool NoSanitizeCoverage = false;
793344a3780SDimitry Andric
794e3b55780SDimitry Andric for (auto *Attr : D->specific_attrs<NoSanitizeAttr>()) {
7957fa27ce4SDimitry Andric no_sanitize_mask |= Attr->getMask();
796344a3780SDimitry Andric // SanitizeCoverage is not handled by SanOpts.
797344a3780SDimitry Andric if (Attr->hasCoverage())
798344a3780SDimitry Andric NoSanitizeCoverage = true;
79948675466SDimitry Andric }
800344a3780SDimitry Andric
8017fa27ce4SDimitry Andric // Apply the no_sanitize* attributes to SanOpts.
8027fa27ce4SDimitry Andric SanOpts.Mask &= ~no_sanitize_mask;
8037fa27ce4SDimitry Andric if (no_sanitize_mask & SanitizerKind::Address)
8047fa27ce4SDimitry Andric SanOpts.set(SanitizerKind::KernelAddress, false);
8057fa27ce4SDimitry Andric if (no_sanitize_mask & SanitizerKind::KernelAddress)
8067fa27ce4SDimitry Andric SanOpts.set(SanitizerKind::Address, false);
8077fa27ce4SDimitry Andric if (no_sanitize_mask & SanitizerKind::HWAddress)
8087fa27ce4SDimitry Andric SanOpts.set(SanitizerKind::KernelHWAddress, false);
8097fa27ce4SDimitry Andric if (no_sanitize_mask & SanitizerKind::KernelHWAddress)
8107fa27ce4SDimitry Andric SanOpts.set(SanitizerKind::HWAddress, false);
8117fa27ce4SDimitry Andric
812145449b1SDimitry Andric if (SanitizeBounds && !SanOpts.hasOneOf(SanitizerKind::Bounds))
813145449b1SDimitry Andric Fn->addFnAttr(llvm::Attribute::NoSanitizeBounds);
814145449b1SDimitry Andric
815344a3780SDimitry Andric if (NoSanitizeCoverage && CGM.getCodeGenOpts().hasSanitizeCoverage())
816344a3780SDimitry Andric Fn->addFnAttr(llvm::Attribute::NoSanitizeCoverage);
8177fa27ce4SDimitry Andric
8187fa27ce4SDimitry Andric // Some passes need the non-negated no_sanitize attribute. Pass them on.
8197fa27ce4SDimitry Andric if (CGM.getCodeGenOpts().hasSanitizeBinaryMetadata()) {
8207fa27ce4SDimitry Andric if (no_sanitize_mask & SanitizerKind::Thread)
8217fa27ce4SDimitry Andric Fn->addFnAttr("no_sanitize_thread");
8227fa27ce4SDimitry Andric }
8235e20cdd8SDimitry Andric }
8245e20cdd8SDimitry Andric
825145449b1SDimitry Andric if (ShouldSkipSanitizerInstrumentation()) {
826145449b1SDimitry Andric CurFn->addFnAttr(llvm::Attribute::DisableSanitizerInstrumentation);
827145449b1SDimitry Andric } else {
8285e20cdd8SDimitry Andric // Apply sanitizer attributes to the function.
8292e645aa5SDimitry Andric if (SanOpts.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress))
8305e20cdd8SDimitry Andric Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
831145449b1SDimitry Andric if (SanOpts.hasOneOf(SanitizerKind::HWAddress |
832145449b1SDimitry Andric SanitizerKind::KernelHWAddress))
833461a67faSDimitry Andric Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
834145449b1SDimitry Andric if (SanOpts.has(SanitizerKind::MemtagStack))
83522989816SDimitry Andric Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
8365e20cdd8SDimitry Andric if (SanOpts.has(SanitizerKind::Thread))
8375e20cdd8SDimitry Andric Fn->addFnAttr(llvm::Attribute::SanitizeThread);
838ac9a064cSDimitry Andric if (SanOpts.has(SanitizerKind::NumericalStability))
839ac9a064cSDimitry Andric Fn->addFnAttr(llvm::Attribute::SanitizeNumericalStability);
840676fbe81SDimitry Andric if (SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory))
8415e20cdd8SDimitry Andric Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
842145449b1SDimitry Andric }
8432e645aa5SDimitry Andric if (SanOpts.has(SanitizerKind::SafeStack))
8442e645aa5SDimitry Andric Fn->addFnAttr(llvm::Attribute::SafeStack);
84548675466SDimitry Andric if (SanOpts.has(SanitizerKind::ShadowCallStack))
84648675466SDimitry Andric Fn->addFnAttr(llvm::Attribute::ShadowCallStack);
84748675466SDimitry Andric
84848675466SDimitry Andric // Apply fuzzing attribute to the function.
84948675466SDimitry Andric if (SanOpts.hasOneOf(SanitizerKind::Fuzzer | SanitizerKind::FuzzerNoLink))
85048675466SDimitry Andric Fn->addFnAttr(llvm::Attribute::OptForFuzzing);
8515e20cdd8SDimitry Andric
852bab175ecSDimitry Andric // Ignore TSan memory acesses from within ObjC/ObjC++ dealloc, initialize,
8537442d6faSDimitry Andric // .cxx_destruct, __destroy_helper_block_ and all of their calees at run time.
854bab175ecSDimitry Andric if (SanOpts.has(SanitizerKind::Thread)) {
855bab175ecSDimitry Andric if (const auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
856ac9a064cSDimitry Andric const IdentifierInfo *II = OMD->getSelector().getIdentifierInfoForSlot(0);
857bab175ecSDimitry Andric if (OMD->getMethodFamily() == OMF_dealloc ||
858bab175ecSDimitry Andric OMD->getMethodFamily() == OMF_initialize ||
859bab175ecSDimitry Andric (OMD->getSelector().isUnarySelector() && II->isStr(".cxx_destruct"))) {
8607442d6faSDimitry Andric markAsIgnoreThreadCheckingAtRuntime(Fn);
861bab175ecSDimitry Andric }
862bab175ecSDimitry Andric }
863bab175ecSDimitry Andric }
864bab175ecSDimitry Andric
865461a67faSDimitry Andric // Ignore unrelated casts in STL allocate() since the allocator must cast
866461a67faSDimitry Andric // from void* to T* before object initialization completes. Don't match on the
867461a67faSDimitry Andric // namespace because not all allocators are in std::
868461a67faSDimitry Andric if (D && SanOpts.has(SanitizerKind::CFIUnrelatedCast)) {
869461a67faSDimitry Andric if (matchesStlAllocatorFn(D, getContext()))
870461a67faSDimitry Andric SanOpts.Mask &= ~SanitizerKind::CFIUnrelatedCast;
871461a67faSDimitry Andric }
872461a67faSDimitry Andric
873519fc96cSDimitry Andric // Ignore null checks in coroutine functions since the coroutines passes
874519fc96cSDimitry Andric // are not aware of how to move the extra UBSan instructions across the split
875519fc96cSDimitry Andric // coroutine boundaries.
876519fc96cSDimitry Andric if (D && SanOpts.has(SanitizerKind::Null))
877344a3780SDimitry Andric if (FD && FD->getBody() &&
878519fc96cSDimitry Andric FD->getBody()->getStmtClass() == Stmt::CoroutineBodyStmtClass)
879519fc96cSDimitry Andric SanOpts.Mask &= ~SanitizerKind::Null;
880519fc96cSDimitry Andric
881ac9a064cSDimitry Andric // Add pointer authentication attributes.
882ac9a064cSDimitry Andric const CodeGenOptions &CodeGenOpts = CGM.getCodeGenOpts();
883adf62863SDimitry Andric if (CodeGenOpts.PointerAuth.ReturnAddresses)
884adf62863SDimitry Andric Fn->addFnAttr("ptrauth-returns");
885ac9a064cSDimitry Andric if (CodeGenOpts.PointerAuth.FunctionPointers)
886ac9a064cSDimitry Andric Fn->addFnAttr("ptrauth-calls");
887adf62863SDimitry Andric if (CodeGenOpts.PointerAuth.AuthTraps)
888adf62863SDimitry Andric Fn->addFnAttr("ptrauth-auth-traps");
889ac9a064cSDimitry Andric if (CodeGenOpts.PointerAuth.IndirectGotos)
890ac9a064cSDimitry Andric Fn->addFnAttr("ptrauth-indirect-gotos");
891ac9a064cSDimitry Andric
892706b4fc4SDimitry Andric // Apply xray attributes to the function (as a string, for now)
893b60736ecSDimitry Andric bool AlwaysXRayAttr = false;
894cfca06d7SDimitry Andric if (const auto *XRayAttr = D ? D->getAttr<XRayInstrumentAttr>() : nullptr) {
895676fbe81SDimitry Andric if (CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
896cfca06d7SDimitry Andric XRayInstrKind::FunctionEntry) ||
897cfca06d7SDimitry Andric CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
898cfca06d7SDimitry Andric XRayInstrKind::FunctionExit)) {
899b60736ecSDimitry Andric if (XRayAttr->alwaysXRayInstrument() && ShouldXRayInstrumentFunction()) {
9002b6b257fSDimitry Andric Fn->addFnAttr("function-instrument", "xray-always");
901b60736ecSDimitry Andric AlwaysXRayAttr = true;
902b60736ecSDimitry Andric }
9032b6b257fSDimitry Andric if (XRayAttr->neverXRayInstrument())
9042b6b257fSDimitry Andric Fn->addFnAttr("function-instrument", "xray-never");
905676fbe81SDimitry Andric if (const auto *LogArgs = D->getAttr<XRayLogArgsAttr>())
906676fbe81SDimitry Andric if (ShouldXRayInstrumentFunction())
9077442d6faSDimitry Andric Fn->addFnAttr("xray-log-args",
9087442d6faSDimitry Andric llvm::utostr(LogArgs->getArgumentCount()));
9097442d6faSDimitry Andric }
9102b6b257fSDimitry Andric } else {
911676fbe81SDimitry Andric if (ShouldXRayInstrumentFunction() && !CGM.imbueXRayAttrs(Fn, Loc))
9122b6b257fSDimitry Andric Fn->addFnAttr(
9132b6b257fSDimitry Andric "xray-instruction-threshold",
9142b6b257fSDimitry Andric llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold));
9152b6b257fSDimitry Andric }
916706b4fc4SDimitry Andric
917cfca06d7SDimitry Andric if (ShouldXRayInstrumentFunction()) {
918cfca06d7SDimitry Andric if (CGM.getCodeGenOpts().XRayIgnoreLoops)
919cfca06d7SDimitry Andric Fn->addFnAttr("xray-ignore-loops");
920cfca06d7SDimitry Andric
921cfca06d7SDimitry Andric if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
922cfca06d7SDimitry Andric XRayInstrKind::FunctionExit))
923cfca06d7SDimitry Andric Fn->addFnAttr("xray-skip-exit");
924cfca06d7SDimitry Andric
925cfca06d7SDimitry Andric if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
926cfca06d7SDimitry Andric XRayInstrKind::FunctionEntry))
927cfca06d7SDimitry Andric Fn->addFnAttr("xray-skip-entry");
928b60736ecSDimitry Andric
929b60736ecSDimitry Andric auto FuncGroups = CGM.getCodeGenOpts().XRayTotalFunctionGroups;
930b60736ecSDimitry Andric if (FuncGroups > 1) {
931e3b55780SDimitry Andric auto FuncName = llvm::ArrayRef<uint8_t>(CurFn->getName().bytes_begin(),
932e3b55780SDimitry Andric CurFn->getName().bytes_end());
933b60736ecSDimitry Andric auto Group = crc32(FuncName) % FuncGroups;
934b60736ecSDimitry Andric if (Group != CGM.getCodeGenOpts().XRaySelectedFunctionGroup &&
935b60736ecSDimitry Andric !AlwaysXRayAttr)
936b60736ecSDimitry Andric Fn->addFnAttr("function-instrument", "xray-never");
937706b4fc4SDimitry Andric }
938b60736ecSDimitry Andric }
939b60736ecSDimitry Andric
940e3b55780SDimitry Andric if (CGM.getCodeGenOpts().getProfileInstr() != CodeGenOptions::ProfileNone) {
941e3b55780SDimitry Andric switch (CGM.isFunctionBlockedFromProfileInstr(Fn, Loc)) {
942e3b55780SDimitry Andric case ProfileList::Skip:
943e3b55780SDimitry Andric Fn->addFnAttr(llvm::Attribute::SkipProfile);
944e3b55780SDimitry Andric break;
945e3b55780SDimitry Andric case ProfileList::Forbid:
946b60736ecSDimitry Andric Fn->addFnAttr(llvm::Attribute::NoProfile);
947e3b55780SDimitry Andric break;
948e3b55780SDimitry Andric case ProfileList::Allow:
949e3b55780SDimitry Andric break;
950e3b55780SDimitry Andric }
951e3b55780SDimitry Andric }
952cfca06d7SDimitry Andric
953cfca06d7SDimitry Andric unsigned Count, Offset;
954cfca06d7SDimitry Andric if (const auto *Attr =
955cfca06d7SDimitry Andric D ? D->getAttr<PatchableFunctionEntryAttr>() : nullptr) {
956cfca06d7SDimitry Andric Count = Attr->getCount();
957cfca06d7SDimitry Andric Offset = Attr->getOffset();
958cfca06d7SDimitry Andric } else {
959cfca06d7SDimitry Andric Count = CGM.getCodeGenOpts().PatchableFunctionEntryCount;
960cfca06d7SDimitry Andric Offset = CGM.getCodeGenOpts().PatchableFunctionEntryOffset;
961cfca06d7SDimitry Andric }
962cfca06d7SDimitry Andric if (Count && Offset <= Count) {
963cfca06d7SDimitry Andric Fn->addFnAttr("patchable-function-entry", std::to_string(Count - Offset));
964cfca06d7SDimitry Andric if (Offset)
965cfca06d7SDimitry Andric Fn->addFnAttr("patchable-function-prefix", std::to_string(Offset));
9662b6b257fSDimitry Andric }
9676f8fc217SDimitry Andric // Instruct that functions for COFF/CodeView targets should start with a
9686f8fc217SDimitry Andric // patchable instruction, but only on x86/x64. Don't forward this to ARM/ARM64
9696f8fc217SDimitry Andric // backends as they don't need it -- instructions on these architectures are
9706f8fc217SDimitry Andric // always atomically patchable at runtime.
9716f8fc217SDimitry Andric if (CGM.getCodeGenOpts().HotPatch &&
972e3b55780SDimitry Andric getContext().getTargetInfo().getTriple().isX86() &&
973e3b55780SDimitry Andric getContext().getTargetInfo().getTriple().getEnvironment() !=
974e3b55780SDimitry Andric llvm::Triple::CODE16)
9756f8fc217SDimitry Andric Fn->addFnAttr("patchable-function", "prologue-short-redirect");
9762b6b257fSDimitry Andric
9772b6b257fSDimitry Andric // Add no-jump-tables value.
978344a3780SDimitry Andric if (CGM.getCodeGenOpts().NoUseJumpTables)
979344a3780SDimitry Andric Fn->addFnAttr("no-jump-tables", "true");
9802b6b257fSDimitry Andric
981706b4fc4SDimitry Andric // Add no-inline-line-tables value.
982706b4fc4SDimitry Andric if (CGM.getCodeGenOpts().NoInlineLineTables)
983706b4fc4SDimitry Andric Fn->addFnAttr("no-inline-line-tables");
984706b4fc4SDimitry Andric
985461a67faSDimitry Andric // Add profile-sample-accurate value.
986461a67faSDimitry Andric if (CGM.getCodeGenOpts().ProfileSampleAccurate)
987461a67faSDimitry Andric Fn->addFnAttr("profile-sample-accurate");
988461a67faSDimitry Andric
989cfca06d7SDimitry Andric if (!CGM.getCodeGenOpts().SampleProfileFile.empty())
990cfca06d7SDimitry Andric Fn->addFnAttr("use-sample-profile");
991cfca06d7SDimitry Andric
992519fc96cSDimitry Andric if (D && D->hasAttr<CFICanonicalJumpTableAttr>())
993519fc96cSDimitry Andric Fn->addFnAttr("cfi-canonical-jump-table");
994519fc96cSDimitry Andric
995344a3780SDimitry Andric if (D && D->hasAttr<NoProfileFunctionAttr>())
996344a3780SDimitry Andric Fn->addFnAttr(llvm::Attribute::NoProfile);
997344a3780SDimitry Andric
9989b950333SDimitry Andric if (D && D->hasAttr<HybridPatchableAttr>())
9999b950333SDimitry Andric Fn->addFnAttr(llvm::Attribute::HybridPatchable);
10009b950333SDimitry Andric
10011f917f69SDimitry Andric if (D) {
10021f917f69SDimitry Andric // Function attributes take precedence over command line flags.
10031f917f69SDimitry Andric if (auto *A = D->getAttr<FunctionReturnThunksAttr>()) {
10041f917f69SDimitry Andric switch (A->getThunkType()) {
10051f917f69SDimitry Andric case FunctionReturnThunksAttr::Kind::Keep:
10061f917f69SDimitry Andric break;
10071f917f69SDimitry Andric case FunctionReturnThunksAttr::Kind::Extern:
10081f917f69SDimitry Andric Fn->addFnAttr(llvm::Attribute::FnRetThunkExtern);
10091f917f69SDimitry Andric break;
10101f917f69SDimitry Andric }
10111f917f69SDimitry Andric } else if (CGM.getCodeGenOpts().FunctionReturnThunks)
10121f917f69SDimitry Andric Fn->addFnAttr(llvm::Attribute::FnRetThunkExtern);
10131f917f69SDimitry Andric }
10141f917f69SDimitry Andric
1015145449b1SDimitry Andric if (FD && (getLangOpts().OpenCL ||
1016145449b1SDimitry Andric (getLangOpts().HIP && getLangOpts().CUDAIsDevice))) {
1017bca07a45SDimitry Andric // Add metadata for a kernel function.
1018145449b1SDimitry Andric EmitKernelMetadata(FD, Fn);
1019bca07a45SDimitry Andric }
1020bca07a45SDimitry Andric
1021ac9a064cSDimitry Andric if (FD && FD->hasAttr<ClspvLibclcBuiltinAttr>()) {
1022ac9a064cSDimitry Andric Fn->setMetadata("clspv_libclc_builtin",
1023ac9a064cSDimitry Andric llvm::MDNode::get(getLLVMContext(), {}));
1024ac9a064cSDimitry Andric }
1025ac9a064cSDimitry Andric
1026bfef3995SDimitry Andric // If we are checking function types, emit a function type signature as
102706d4ba38SDimitry Andric // prologue data.
10287fa27ce4SDimitry Andric if (FD && SanOpts.has(SanitizerKind::Function)) {
1029461a67faSDimitry Andric if (llvm::Constant *PrologueSig = getPrologueSignature(CGM, FD)) {
1030145449b1SDimitry Andric llvm::LLVMContext &Ctx = Fn->getContext();
1031145449b1SDimitry Andric llvm::MDBuilder MDB(Ctx);
10327fa27ce4SDimitry Andric Fn->setMetadata(
10337fa27ce4SDimitry Andric llvm::LLVMContext::MD_func_sanitize,
10347fa27ce4SDimitry Andric MDB.createRTTIPointerPrologue(
10357fa27ce4SDimitry Andric PrologueSig, getUBSanFunctionTypeHash(FD->getType())));
1036bfef3995SDimitry Andric }
1037bfef3995SDimitry Andric }
1038bfef3995SDimitry Andric
10397442d6faSDimitry Andric // If we're checking nullability, we need to know whether we can check the
10407442d6faSDimitry Andric // return value. Initialize the flag to 'true' and refine it in EmitParmDecl.
10417442d6faSDimitry Andric if (SanOpts.has(SanitizerKind::NullabilityReturn)) {
1042e3b55780SDimitry Andric auto Nullability = FnRetTy->getNullability();
1043ac9a064cSDimitry Andric if (Nullability && *Nullability == NullabilityKind::NonNull &&
1044ac9a064cSDimitry Andric !FnRetTy->isRecordType()) {
10457442d6faSDimitry Andric if (!(SanOpts.has(SanitizerKind::ReturnsNonnullAttribute) &&
10467442d6faSDimitry Andric CurCodeDecl && CurCodeDecl->getAttr<ReturnsNonNullAttr>()))
10477442d6faSDimitry Andric RetValNullabilityPrecondition =
10487442d6faSDimitry Andric llvm::ConstantInt::getTrue(getLLVMContext());
10497442d6faSDimitry Andric }
10507442d6faSDimitry Andric }
10517442d6faSDimitry Andric
105245b53394SDimitry Andric // If we're in C++ mode and the function name is "main", it is guaranteed
105345b53394SDimitry Andric // to be norecurse by the standard (3.6.1.3 "The function main shall not be
105445b53394SDimitry Andric // used within a program").
1055cfca06d7SDimitry Andric //
1056cfca06d7SDimitry Andric // OpenCL C 2.0 v2.2-11 s6.9.i:
1057cfca06d7SDimitry Andric // Recursion is not supported.
1058cfca06d7SDimitry Andric //
1059cfca06d7SDimitry Andric // SYCL v1.2.1 s3.10:
1060cfca06d7SDimitry Andric // kernels cannot include RTTI information, exception classes,
1061cfca06d7SDimitry Andric // recursive code, virtual functions or make use of C++ libraries that
1062cfca06d7SDimitry Andric // are not compiled for the device.
1063344a3780SDimitry Andric if (FD && ((getLangOpts().CPlusPlus && FD->isMain()) ||
1064344a3780SDimitry Andric getLangOpts().OpenCL || getLangOpts().SYCLIsDevice ||
1065344a3780SDimitry Andric (getLangOpts().CUDA && FD->hasAttr<CUDAGlobalAttr>())))
106645b53394SDimitry Andric Fn->addFnAttr(llvm::Attribute::NoRecurse);
106745b53394SDimitry Andric
1068145449b1SDimitry Andric llvm::RoundingMode RM = getLangOpts().getDefaultRoundingMode();
1069c0981da4SDimitry Andric llvm::fp::ExceptionBehavior FPExceptionBehavior =
1070145449b1SDimitry Andric ToConstrainedExceptMD(getLangOpts().getDefaultExceptionMode());
1071c0981da4SDimitry Andric Builder.setDefaultConstrainedRounding(RM);
1072c0981da4SDimitry Andric Builder.setDefaultConstrainedExcept(FPExceptionBehavior);
1073c0981da4SDimitry Andric if ((FD && (FD->UsesFPIntrin() || FD->hasAttr<StrictFPAttr>())) ||
1074c0981da4SDimitry Andric (!FD && (FPExceptionBehavior != llvm::fp::ebIgnore ||
1075c0981da4SDimitry Andric RM != llvm::RoundingMode::NearestTiesToEven))) {
1076c0981da4SDimitry Andric Builder.setIsFPConstrained(true);
1077706b4fc4SDimitry Andric Fn->addFnAttr(llvm::Attribute::StrictFP);
1078cfca06d7SDimitry Andric }
1079706b4fc4SDimitry Andric
1080676fbe81SDimitry Andric // If a custom alignment is used, force realigning to this alignment on
1081676fbe81SDimitry Andric // any main function which certainly will need it.
1082344a3780SDimitry Andric if (FD && ((FD->isMain() || FD->isMSVCRTEntryPoint()) &&
1083344a3780SDimitry Andric CGM.getCodeGenOpts().StackAlignment))
1084676fbe81SDimitry Andric Fn->addFnAttr("stackrealign");
1085676fbe81SDimitry Andric
1086145449b1SDimitry Andric // "main" doesn't need to zero out call-used registers.
1087145449b1SDimitry Andric if (FD && FD->isMain())
1088145449b1SDimitry Andric Fn->removeFnAttr("zero-call-used-regs");
1089145449b1SDimitry Andric
1090ec2b103cSEd Schouten llvm::BasicBlock *EntryBB = createBasicBlock("entry", CurFn);
1091ec2b103cSEd Schouten
1092ec2b103cSEd Schouten // Create a marker to make it easy to insert allocas into the entryblock
1093ec2b103cSEd Schouten // later. Don't create this with the builder, because we don't want it
1094ec2b103cSEd Schouten // folded.
10954ba67500SRoman Divacky llvm::Value *Undef = llvm::UndefValue::get(Int32Ty);
10962b6b257fSDimitry Andric AllocaInsertPt = new llvm::BitCastInst(Undef, Int32Ty, "allocapt", EntryBB);
1097ec2b103cSEd Schouten
10984ba67500SRoman Divacky ReturnBlock = getJumpDestInCurrentScope("return");
1099ec2b103cSEd Schouten
1100ec2b103cSEd Schouten Builder.SetInsertPoint(EntryBB);
1101ec2b103cSEd Schouten
1102ef915aabSDimitry Andric // If we're checking the return value, allocate space for a pointer to a
1103ef915aabSDimitry Andric // precise source location of the checked return statement.
1104ef915aabSDimitry Andric if (requiresReturnValueCheck()) {
1105ef915aabSDimitry Andric ReturnLocation = CreateDefaultAlignTempAlloca(Int8PtrTy, "return.sloc.ptr");
1106c0981da4SDimitry Andric Builder.CreateStore(llvm::ConstantPointerNull::get(Int8PtrTy),
1107c0981da4SDimitry Andric ReturnLocation);
1108ef915aabSDimitry Andric }
1109ef915aabSDimitry Andric
1110ec2b103cSEd Schouten // Emit subprogram debug descriptor.
1111ec2b103cSEd Schouten if (CGDebugInfo *DI = getDebugInfo()) {
11122b6b257fSDimitry Andric // Reconstruct the type from the argument list so that implicit parameters,
11132b6b257fSDimitry Andric // such as 'this' and 'vtt', show up in the debug info. Preserve the calling
11142b6b257fSDimitry Andric // convention.
1115c0981da4SDimitry Andric DI->emitFunctionStart(GD, Loc, StartLoc,
1116c0981da4SDimitry Andric DI->getFunctionType(FD, RetTy, Args), CurFn,
1117c0981da4SDimitry Andric CurFuncIsThunk);
1118ec2b103cSEd Schouten }
1119ec2b103cSEd Schouten
1120461a67faSDimitry Andric if (ShouldInstrumentFunction()) {
1121461a67faSDimitry Andric if (CGM.getCodeGenOpts().InstrumentFunctions)
1122461a67faSDimitry Andric CurFn->addFnAttr("instrument-function-entry", "__cyg_profile_func_enter");
1123461a67faSDimitry Andric if (CGM.getCodeGenOpts().InstrumentFunctionsAfterInlining)
1124461a67faSDimitry Andric CurFn->addFnAttr("instrument-function-entry-inlined",
1125461a67faSDimitry Andric "__cyg_profile_func_enter");
1126461a67faSDimitry Andric if (CGM.getCodeGenOpts().InstrumentFunctionEntryBare)
1127461a67faSDimitry Andric CurFn->addFnAttr("instrument-function-entry-inlined",
1128461a67faSDimitry Andric "__cyg_profile_func_enter_bare");
1129461a67faSDimitry Andric }
11304ba67500SRoman Divacky
1131bab175ecSDimitry Andric // Since emitting the mcount call here impacts optimizations such as function
1132bab175ecSDimitry Andric // inlining, we just add an attribute to insert a mcount call in backend.
1133bab175ecSDimitry Andric // The attribute "counting-function" is set to mcount function name which is
1134bab175ecSDimitry Andric // architecture dependent.
11357442d6faSDimitry Andric if (CGM.getCodeGenOpts().InstrumentForProfiling) {
113648675466SDimitry Andric // Calls to fentry/mcount should not be generated if function has
113748675466SDimitry Andric // the no_instrument_function attribute.
113848675466SDimitry Andric if (!CurFuncDecl || !CurFuncDecl->hasAttr<NoInstrumentFunctionAttr>()) {
11397442d6faSDimitry Andric if (CGM.getCodeGenOpts().CallFEntry)
11407442d6faSDimitry Andric Fn->addFnAttr("fentry-call", "true");
1141ef915aabSDimitry Andric else {
1142461a67faSDimitry Andric Fn->addFnAttr("instrument-function-entry-inlined",
1143461a67faSDimitry Andric getTarget().getMCountName());
1144461a67faSDimitry Andric }
1145706b4fc4SDimitry Andric if (CGM.getCodeGenOpts().MNopMCount) {
1146706b4fc4SDimitry Andric if (!CGM.getCodeGenOpts().CallFEntry)
1147706b4fc4SDimitry Andric CGM.getDiags().Report(diag::err_opt_not_valid_without_opt)
1148706b4fc4SDimitry Andric << "-mnop-mcount" << "-mfentry";
1149706b4fc4SDimitry Andric Fn->addFnAttr("mnop-mcount");
11507442d6faSDimitry Andric }
1151706b4fc4SDimitry Andric
1152706b4fc4SDimitry Andric if (CGM.getCodeGenOpts().RecordMCount) {
1153706b4fc4SDimitry Andric if (!CGM.getCodeGenOpts().CallFEntry)
1154706b4fc4SDimitry Andric CGM.getDiags().Report(diag::err_opt_not_valid_without_opt)
1155706b4fc4SDimitry Andric << "-mrecord-mcount" << "-mfentry";
1156706b4fc4SDimitry Andric Fn->addFnAttr("mrecord-mcount");
1157706b4fc4SDimitry Andric }
1158706b4fc4SDimitry Andric }
1159706b4fc4SDimitry Andric }
1160706b4fc4SDimitry Andric
1161706b4fc4SDimitry Andric if (CGM.getCodeGenOpts().PackedStack) {
1162706b4fc4SDimitry Andric if (getContext().getTargetInfo().getTriple().getArch() !=
1163706b4fc4SDimitry Andric llvm::Triple::systemz)
1164706b4fc4SDimitry Andric CGM.getDiags().Report(diag::err_opt_not_valid_on_target)
1165706b4fc4SDimitry Andric << "-mpacked-stack";
1166706b4fc4SDimitry Andric Fn->addFnAttr("packed-stack");
1167ef915aabSDimitry Andric }
1168bca07a45SDimitry Andric
1169c0981da4SDimitry Andric if (CGM.getCodeGenOpts().WarnStackSize != UINT_MAX &&
1170c0981da4SDimitry Andric !CGM.getDiags().isIgnored(diag::warn_fe_backend_frame_larger_than, Loc))
1171344a3780SDimitry Andric Fn->addFnAttr("warn-stack-size",
1172344a3780SDimitry Andric std::to_string(CGM.getCodeGenOpts().WarnStackSize));
1173344a3780SDimitry Andric
117434d02d0bSRoman Divacky if (RetTy->isVoidType()) {
117534d02d0bSRoman Divacky // Void type; nothing to return.
117645b53394SDimitry Andric ReturnValue = Address::invalid();
11779f4dbff6SDimitry Andric
11789f4dbff6SDimitry Andric // Count the implicit return.
11799f4dbff6SDimitry Andric if (!endsWithReturn(D))
11809f4dbff6SDimitry Andric ++NumReturnExprs;
1181676fbe81SDimitry Andric } else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect) {
1182676fbe81SDimitry Andric // Indirect return; emit returned value directly into sret slot.
118379ade4e0SRoman Divacky // This reduces code size, and affects correctness in C++.
11849f4dbff6SDimitry Andric auto AI = CurFn->arg_begin();
11859f4dbff6SDimitry Andric if (CurFnInfo->getReturnInfo().isSRetAfterThis())
11869f4dbff6SDimitry Andric ++AI;
1187ac9a064cSDimitry Andric ReturnValue = makeNaturalAddressForPointer(
1188ac9a064cSDimitry Andric &*AI, RetTy, CurFnInfo->getReturnInfo().getIndirectAlign(), false,
1189ac9a064cSDimitry Andric nullptr, nullptr, KnownNonNull);
119022989816SDimitry Andric if (!CurFnInfo->getReturnInfo().getIndirectByVal()) {
1191ac9a064cSDimitry Andric ReturnValuePointer =
1192ac9a064cSDimitry Andric CreateDefaultAlignTempAlloca(ReturnValue.getType(), "result.ptr");
1193ac9a064cSDimitry Andric Builder.CreateStore(ReturnValue.emitRawPointer(*this),
1194ac9a064cSDimitry Andric ReturnValuePointer);
119522989816SDimitry Andric }
11969f4dbff6SDimitry Andric } else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::InAlloca &&
11979f4dbff6SDimitry Andric !hasScalarEvaluationKind(CurFnInfo->getReturnType())) {
11989f4dbff6SDimitry Andric // Load the sret pointer from the argument struct and return into that.
11999f4dbff6SDimitry Andric unsigned Idx = CurFnInfo->getReturnInfo().getInAllocaFieldIndex();
12009f4dbff6SDimitry Andric llvm::Function::arg_iterator EI = CurFn->arg_end();
12019f4dbff6SDimitry Andric --EI;
1202344a3780SDimitry Andric llvm::Value *Addr = Builder.CreateStructGEP(
1203145449b1SDimitry Andric CurFnInfo->getArgStruct(), &*EI, Idx);
1204344a3780SDimitry Andric llvm::Type *Ty =
1205344a3780SDimitry Andric cast<llvm::GetElementPtrInst>(Addr)->getResultElementType();
1206145449b1SDimitry Andric ReturnValuePointer = Address(Addr, Ty, getPointerAlign());
1207344a3780SDimitry Andric Addr = Builder.CreateAlignedLoad(Ty, Addr, getPointerAlign(), "agg.result");
12087fa27ce4SDimitry Andric ReturnValue = Address(Addr, ConvertType(RetTy),
12097fa27ce4SDimitry Andric CGM.getNaturalTypeAlignment(RetTy), KnownNonNull);
121034d02d0bSRoman Divacky } else {
121179ade4e0SRoman Divacky ReturnValue = CreateIRTemp(RetTy, "retval");
1212180abc3dSDimitry Andric
1213180abc3dSDimitry Andric // Tell the epilog emitter to autorelease the result. We do this
1214180abc3dSDimitry Andric // now so that various specialized functions can suppress it
1215180abc3dSDimitry Andric // during their IR-generation.
1216dbe13110SDimitry Andric if (getLangOpts().ObjCAutoRefCount &&
1217180abc3dSDimitry Andric !CurFnInfo->isReturnsRetained() &&
1218180abc3dSDimitry Andric RetTy->isObjCRetainableType())
1219180abc3dSDimitry Andric AutoreleaseResult = true;
122034d02d0bSRoman Divacky }
122134d02d0bSRoman Divacky
122234d02d0bSRoman Divacky EmitStartEHSpec(CurCodeDecl);
1223180abc3dSDimitry Andric
1224180abc3dSDimitry Andric PrologueCleanupDepth = EHStack.stable_begin();
122548675466SDimitry Andric
122648675466SDimitry Andric // Emit OpenMP specific initialization of the device functions.
122748675466SDimitry Andric if (getLangOpts().OpenMP && CurCodeDecl)
122848675466SDimitry Andric CGM.getOpenMPRuntime().emitFunctionProlog(*this, CurCodeDecl);
122948675466SDimitry Andric
1230e3b55780SDimitry Andric // Handle emitting HLSL entry functions.
1231e3b55780SDimitry Andric if (D && D->hasAttr<HLSLShaderAttr>())
1232e3b55780SDimitry Andric CGM.getHLSLRuntime().emitEntryFunction(FD, Fn);
1233e3b55780SDimitry Andric
1234ec2b103cSEd Schouten EmitFunctionProlog(*CurFnInfo, CurFn, Args);
1235ec2b103cSEd Schouten
1236b1c73532SDimitry Andric if (const CXXMethodDecl *MD = dyn_cast_if_present<CXXMethodDecl>(D);
1237b1c73532SDimitry Andric MD && !MD->isStatic()) {
1238b1c73532SDimitry Andric bool IsInLambda =
1239b1c73532SDimitry Andric MD->getParent()->isLambda() && MD->getOverloadedOperator() == OO_Call;
1240b1c73532SDimitry Andric if (MD->isImplicitObjectMemberFunction())
12413d1dcd9bSDimitry Andric CGM.getCXXABI().EmitInstanceFunctionProlog(*this);
1242b1c73532SDimitry Andric if (IsInLambda) {
1243dbe13110SDimitry Andric // We're in a lambda; figure out the captures.
1244dbe13110SDimitry Andric MD->getParent()->getCaptureFields(LambdaCaptureFields,
1245dbe13110SDimitry Andric LambdaThisCaptureField);
1246dbe13110SDimitry Andric if (LambdaThisCaptureField) {
12472b6b257fSDimitry Andric // If the lambda captures the object referred to by '*this' - either by
12482b6b257fSDimitry Andric // value or by reference, make sure CXXThisValue points to the correct
12492b6b257fSDimitry Andric // object.
12502b6b257fSDimitry Andric
12512b6b257fSDimitry Andric // Get the lvalue for the field (which is a copy of the enclosing object
12522b6b257fSDimitry Andric // or contains the address of the enclosing object).
12532b6b257fSDimitry Andric LValue ThisFieldLValue = EmitLValueForLambdaField(LambdaThisCaptureField);
12542b6b257fSDimitry Andric if (!LambdaThisCaptureField->getType()->isPointerType()) {
1255ac9a064cSDimitry Andric // If the enclosing object was captured by value, just use its
1256ac9a064cSDimitry Andric // address. Sign this pointer.
1257ac9a064cSDimitry Andric CXXThisValue = ThisFieldLValue.getPointer(*this);
12582b6b257fSDimitry Andric } else {
12592b6b257fSDimitry Andric // Load the lvalue pointed to by the field, since '*this' was captured
12602b6b257fSDimitry Andric // by reference.
12612b6b257fSDimitry Andric CXXThisValue =
12622b6b257fSDimitry Andric EmitLoadOfLValue(ThisFieldLValue, SourceLocation()).getScalarVal();
12632b6b257fSDimitry Andric }
1264dbe13110SDimitry Andric }
126506d4ba38SDimitry Andric for (auto *FD : MD->getParent()->fields()) {
126606d4ba38SDimitry Andric if (FD->hasCapturedVLAType()) {
126706d4ba38SDimitry Andric auto *ExprArg = EmitLoadOfLValue(EmitLValueForLambdaField(FD),
126806d4ba38SDimitry Andric SourceLocation()).getScalarVal();
126906d4ba38SDimitry Andric auto VAT = FD->getCapturedVLAType();
127006d4ba38SDimitry Andric VLASizeMap[VAT->getSizeExpr()] = ExprArg;
127106d4ba38SDimitry Andric }
127206d4ba38SDimitry Andric }
1273b1c73532SDimitry Andric } else if (MD->isImplicitObjectMemberFunction()) {
1274dbe13110SDimitry Andric // Not in a lambda; just use 'this' from the method.
1275dbe13110SDimitry Andric // FIXME: Should we generate a new load for each use of 'this'? The
1276dbe13110SDimitry Andric // fast register allocator would be happier...
1277dbe13110SDimitry Andric CXXThisValue = CXXABIThisValue;
1278dbe13110SDimitry Andric }
12797442d6faSDimitry Andric
12807442d6faSDimitry Andric // Check the 'this' pointer once per function, if it's available.
1281ef2abedbSDimitry Andric if (CXXABIThisValue) {
12827442d6faSDimitry Andric SanitizerSet SkippedChecks;
12837442d6faSDimitry Andric SkippedChecks.set(SanitizerKind::ObjectSize, true);
1284676fbe81SDimitry Andric QualType ThisTy = MD->getThisType();
1285ef2abedbSDimitry Andric
1286b1c73532SDimitry Andric // If this is the call operator of a lambda with no captures, it
1287ef2abedbSDimitry Andric // may have a static invoker function, which may call this operator with
1288ef2abedbSDimitry Andric // a null 'this' pointer.
1289b1c73532SDimitry Andric if (isLambdaCallOperator(MD) && MD->getParent()->isCapturelessLambda())
1290ef2abedbSDimitry Andric SkippedChecks.set(SanitizerKind::Null, true);
1291ef2abedbSDimitry Andric
1292b60736ecSDimitry Andric EmitTypeCheck(
1293b60736ecSDimitry Andric isa<CXXConstructorDecl>(MD) ? TCK_ConstructorCall : TCK_MemberCall,
1294b60736ecSDimitry Andric Loc, CXXABIThisValue, ThisTy, CXXABIThisAlignment, SkippedChecks);
12957442d6faSDimitry Andric }
1296dbe13110SDimitry Andric }
129779ade4e0SRoman Divacky
1298ec2b103cSEd Schouten // If any of the arguments have a variably modified type, make sure to
1299145449b1SDimitry Andric // emit the type size, but only if the function is not naked. Naked functions
1300145449b1SDimitry Andric // have no prolog to run this evaluation.
1301145449b1SDimitry Andric if (!FD || !FD->hasAttr<NakedAttr>()) {
1302145449b1SDimitry Andric for (const VarDecl *VD : Args) {
1303809500fcSDimitry Andric // Dig out the type as written from ParmVarDecls; it's unclear whether
1304809500fcSDimitry Andric // the standard (C99 6.9.1p10) requires this, but we're following the
1305809500fcSDimitry Andric // precedent set by gcc.
1306809500fcSDimitry Andric QualType Ty;
1307809500fcSDimitry Andric if (const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(VD))
1308809500fcSDimitry Andric Ty = PVD->getOriginalType();
1309809500fcSDimitry Andric else
1310809500fcSDimitry Andric Ty = VD->getType();
1311ec2b103cSEd Schouten
1312ec2b103cSEd Schouten if (Ty->isVariablyModifiedType())
1313180abc3dSDimitry Andric EmitVariablyModifiedType(Ty);
1314ec2b103cSEd Schouten }
1315145449b1SDimitry Andric }
131636981b17SDimitry Andric // Emit a location at the end of the prologue.
131736981b17SDimitry Andric if (CGDebugInfo *DI = getDebugInfo())
131836981b17SDimitry Andric DI->EmitLocation(Builder, StartLoc);
131948675466SDimitry Andric // TODO: Do we need to handle this in two places like we do with
132048675466SDimitry Andric // target-features/target-cpu?
132148675466SDimitry Andric if (CurFuncDecl)
132248675466SDimitry Andric if (const auto *VecWidth = CurFuncDecl->getAttr<MinVectorWidthAttr>())
132348675466SDimitry Andric LargestVectorWidth = VecWidth->getVectorWidth();
1324ac9a064cSDimitry Andric
1325ac9a064cSDimitry Andric if (CGM.shouldEmitConvergenceTokens())
1326ac9a064cSDimitry Andric ConvergenceTokenStack.push_back(getOrEmitConvergenceEntryToken(CurFn));
1327ec2b103cSEd Schouten }
1328ec2b103cSEd Schouten
EmitFunctionBody(const Stmt * Body)1329676fbe81SDimitry Andric void CodeGenFunction::EmitFunctionBody(const Stmt *Body) {
13305e20cdd8SDimitry Andric incrementProfileCounter(Body);
1331aca2e42cSDimitry Andric maybeCreateMCDCCondBitmap();
1332bfef3995SDimitry Andric if (const CompoundStmt *S = dyn_cast<CompoundStmt>(Body))
1333809500fcSDimitry Andric EmitCompoundStmtWithoutScope(*S);
1334809500fcSDimitry Andric else
1335bfef3995SDimitry Andric EmitStmt(Body);
133679ade4e0SRoman Divacky }
133779ade4e0SRoman Divacky
13389f4dbff6SDimitry Andric /// When instrumenting to collect profile data, the counts for some blocks
13399f4dbff6SDimitry Andric /// such as switch cases need to not include the fall-through counts, so
13409f4dbff6SDimitry Andric /// emit a branch around the instrumentation code. When not instrumenting,
13419f4dbff6SDimitry Andric /// this just calls EmitBlock().
EmitBlockWithFallThrough(llvm::BasicBlock * BB,const Stmt * S)13429f4dbff6SDimitry Andric void CodeGenFunction::EmitBlockWithFallThrough(llvm::BasicBlock *BB,
13435e20cdd8SDimitry Andric const Stmt *S) {
13449f4dbff6SDimitry Andric llvm::BasicBlock *SkipCountBB = nullptr;
1345ac9a064cSDimitry Andric // Do not skip over the instrumentation when single byte coverage mode is
1346ac9a064cSDimitry Andric // enabled.
1347ac9a064cSDimitry Andric if (HaveInsertPoint() && CGM.getCodeGenOpts().hasProfileClangInstr() &&
1348ac9a064cSDimitry Andric !llvm::EnableSingleByteCoverage) {
13499f4dbff6SDimitry Andric // When instrumenting for profiling, the fallthrough to certain
13509f4dbff6SDimitry Andric // statements needs to skip over the instrumentation code so that we
13519f4dbff6SDimitry Andric // get an accurate count.
13529f4dbff6SDimitry Andric SkipCountBB = createBasicBlock("skipcount");
13539f4dbff6SDimitry Andric EmitBranch(SkipCountBB);
13549f4dbff6SDimitry Andric }
13559f4dbff6SDimitry Andric EmitBlock(BB);
13565e20cdd8SDimitry Andric uint64_t CurrentCount = getCurrentProfileCount();
13575e20cdd8SDimitry Andric incrementProfileCounter(S);
13585e20cdd8SDimitry Andric setCurrentProfileCount(getCurrentProfileCount() + CurrentCount);
13599f4dbff6SDimitry Andric if (SkipCountBB)
13609f4dbff6SDimitry Andric EmitBlock(SkipCountBB);
13619f4dbff6SDimitry Andric }
13629f4dbff6SDimitry Andric
13633d1dcd9bSDimitry Andric /// Tries to mark the given function nounwind based on the
13643d1dcd9bSDimitry Andric /// non-existence of any throwing calls within it. We believe this is
13653d1dcd9bSDimitry Andric /// lightweight enough to do at -O0.
TryMarkNoThrow(llvm::Function * F)13663d1dcd9bSDimitry Andric static void TryMarkNoThrow(llvm::Function *F) {
13673d1dcd9bSDimitry Andric // LLVM treats 'nounwind' on a function as part of the type, so we
13683d1dcd9bSDimitry Andric // can't do this on functions that can be overwritten.
13692b6b257fSDimitry Andric if (F->isInterposable()) return;
13703d1dcd9bSDimitry Andric
137145b53394SDimitry Andric for (llvm::BasicBlock &BB : *F)
137245b53394SDimitry Andric for (llvm::Instruction &I : BB)
137345b53394SDimitry Andric if (I.mayThrow())
13743d1dcd9bSDimitry Andric return;
137545b53394SDimitry Andric
137613cc256eSDimitry Andric F->setDoesNotThrow();
13773d1dcd9bSDimitry Andric }
13783d1dcd9bSDimitry Andric
BuildFunctionArgList(GlobalDecl GD,FunctionArgList & Args)13792b6b257fSDimitry Andric QualType CodeGenFunction::BuildFunctionArgList(GlobalDecl GD,
13802b6b257fSDimitry Andric FunctionArgList &Args) {
13814c8b2481SRoman Divacky const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
13829f4dbff6SDimitry Andric QualType ResTy = FD->getReturnType();
1383ec2b103cSEd Schouten
13849f4dbff6SDimitry Andric const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
1385b1c73532SDimitry Andric if (MD && MD->isImplicitObjectMemberFunction()) {
1386bfef3995SDimitry Andric if (CGM.getCXXABI().HasThisReturn(GD))
1387676fbe81SDimitry Andric ResTy = MD->getThisType();
138806d4ba38SDimitry Andric else if (CGM.getCXXABI().hasMostDerivedReturn(GD))
138906d4ba38SDimitry Andric ResTy = CGM.getContext().VoidPtrTy;
13909f4dbff6SDimitry Andric CGM.getCXXABI().buildThisParam(*this, Args);
1391bfef3995SDimitry Andric }
1392ec2b103cSEd Schouten
13932b6b257fSDimitry Andric // The base version of an inheriting constructor whose constructed base is a
13942b6b257fSDimitry Andric // virtual base is not passed any arguments (because it doesn't actually call
13952b6b257fSDimitry Andric // the inherited constructor).
13962b6b257fSDimitry Andric bool PassedParams = true;
13972b6b257fSDimitry Andric if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD))
13982b6b257fSDimitry Andric if (auto Inherited = CD->getInheritedConstructor())
13992b6b257fSDimitry Andric PassedParams =
14002b6b257fSDimitry Andric getTypes().inheritingCtorHasParams(Inherited, GD.getCtorType());
14012b6b257fSDimitry Andric
14022b6b257fSDimitry Andric if (PassedParams) {
14032b6b257fSDimitry Andric for (auto *Param : FD->parameters()) {
140445b53394SDimitry Andric Args.push_back(Param);
140545b53394SDimitry Andric if (!Param->hasAttr<PassObjectSizeAttr>())
140645b53394SDimitry Andric continue;
140745b53394SDimitry Andric
140845b53394SDimitry Andric auto *Implicit = ImplicitParamDecl::Create(
14091b08b196SDimitry Andric getContext(), Param->getDeclContext(), Param->getLocation(),
1410b1c73532SDimitry Andric /*Id=*/nullptr, getContext().getSizeType(), ImplicitParamKind::Other);
141145b53394SDimitry Andric SizeArguments[Param] = Implicit;
141245b53394SDimitry Andric Args.push_back(Implicit);
141345b53394SDimitry Andric }
14142b6b257fSDimitry Andric }
1415ec2b103cSEd Schouten
14169f4dbff6SDimitry Andric if (MD && (isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)))
14179f4dbff6SDimitry Andric CGM.getCXXABI().addImplicitStructorParams(*this, ResTy, Args);
14189f4dbff6SDimitry Andric
14192b6b257fSDimitry Andric return ResTy;
14202b6b257fSDimitry Andric }
14212b6b257fSDimitry Andric
GenerateCode(GlobalDecl GD,llvm::Function * Fn,const CGFunctionInfo & FnInfo)14222b6b257fSDimitry Andric void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
14232b6b257fSDimitry Andric const CGFunctionInfo &FnInfo) {
142477fc4c14SDimitry Andric assert(Fn && "generating code for null Function");
14252b6b257fSDimitry Andric const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
14262b6b257fSDimitry Andric CurGD = GD;
14272b6b257fSDimitry Andric
14282b6b257fSDimitry Andric FunctionArgList Args;
14292b6b257fSDimitry Andric QualType ResTy = BuildFunctionArgList(GD, Args);
14302b6b257fSDimitry Andric
1431ac9a064cSDimitry Andric CGM.getTargetCodeGenInfo().checkFunctionABI(CGM, FD);
1432ac9a064cSDimitry Andric
1433c0981da4SDimitry Andric if (FD->isInlineBuiltinDeclaration()) {
143477fc4c14SDimitry Andric // When generating code for a builtin with an inline declaration, use a
143577fc4c14SDimitry Andric // mangled name to hold the actual body, while keeping an external
143677fc4c14SDimitry Andric // definition in case the function pointer is referenced somewhere.
1437c0981da4SDimitry Andric std::string FDInlineName = (Fn->getName() + ".inline").str();
1438c0981da4SDimitry Andric llvm::Module *M = Fn->getParent();
1439c0981da4SDimitry Andric llvm::Function *Clone = M->getFunction(FDInlineName);
1440c0981da4SDimitry Andric if (!Clone) {
1441c0981da4SDimitry Andric Clone = llvm::Function::Create(Fn->getFunctionType(),
1442c0981da4SDimitry Andric llvm::GlobalValue::InternalLinkage,
1443c0981da4SDimitry Andric Fn->getAddressSpace(), FDInlineName, M);
1444c0981da4SDimitry Andric Clone->addFnAttr(llvm::Attribute::AlwaysInline);
1445c0981da4SDimitry Andric }
1446c0981da4SDimitry Andric Fn->setLinkage(llvm::GlobalValue::ExternalLinkage);
1447c0981da4SDimitry Andric Fn = Clone;
144877fc4c14SDimitry Andric } else {
1449c0981da4SDimitry Andric // Detect the unusual situation where an inline version is shadowed by a
1450c0981da4SDimitry Andric // non-inline version. In that case we should pick the external one
1451c0981da4SDimitry Andric // everywhere. That's GCC behavior too. Unfortunately, I cannot find a way
1452c0981da4SDimitry Andric // to detect that situation before we reach codegen, so do some late
1453c0981da4SDimitry Andric // replacement.
1454c0981da4SDimitry Andric for (const FunctionDecl *PD = FD->getPreviousDecl(); PD;
1455c0981da4SDimitry Andric PD = PD->getPreviousDecl()) {
1456c0981da4SDimitry Andric if (LLVM_UNLIKELY(PD->isInlineBuiltinDeclaration())) {
1457c0981da4SDimitry Andric std::string FDInlineName = (Fn->getName() + ".inline").str();
1458c0981da4SDimitry Andric llvm::Module *M = Fn->getParent();
1459c0981da4SDimitry Andric if (llvm::Function *Clone = M->getFunction(FDInlineName)) {
1460c0981da4SDimitry Andric Clone->replaceAllUsesWith(Fn);
1461c0981da4SDimitry Andric Clone->eraseFromParent();
1462c0981da4SDimitry Andric }
1463c0981da4SDimitry Andric break;
1464c0981da4SDimitry Andric }
1465c0981da4SDimitry Andric }
1466c0981da4SDimitry Andric }
1467c0981da4SDimitry Andric
14682b6b257fSDimitry Andric // Check if we should generate debug info for this function.
1469344a3780SDimitry Andric if (FD->hasAttr<NoDebugAttr>()) {
1470344a3780SDimitry Andric // Clear non-distinct debug info that was possibly attached to the function
1471344a3780SDimitry Andric // due to an earlier declaration without the nodebug attribute
1472344a3780SDimitry Andric Fn->setSubprogram(nullptr);
1473344a3780SDimitry Andric // Disable debug info indefinitely for this function
1474344a3780SDimitry Andric DebugInfo = nullptr;
1475344a3780SDimitry Andric }
14762b6b257fSDimitry Andric
14777442d6faSDimitry Andric // The function might not have a body if we're generating thunks for a
14787442d6faSDimitry Andric // function declaration.
147979ade4e0SRoman Divacky SourceRange BodyRange;
14807442d6faSDimitry Andric if (Stmt *Body = FD->getBody())
14817442d6faSDimitry Andric BodyRange = Body->getSourceRange();
14827442d6faSDimitry Andric else
14837442d6faSDimitry Andric BodyRange = FD->getLocation();
1484bfef3995SDimitry Andric CurEHLocation = BodyRange.getEnd();
1485809500fcSDimitry Andric
14869f4dbff6SDimitry Andric // Use the location of the start of the function to determine where
14879f4dbff6SDimitry Andric // the function definition is located. By default use the location
14889f4dbff6SDimitry Andric // of the declaration as the location for the subprogram. A function
14899f4dbff6SDimitry Andric // may lack a declaration in the source code if it is created by code
14909f4dbff6SDimitry Andric // gen. (examples: _GLOBAL__I_a, __cxx_global_array_dtor, thunk).
14919f4dbff6SDimitry Andric SourceLocation Loc = FD->getLocation();
14929f4dbff6SDimitry Andric
14939f4dbff6SDimitry Andric // If this is a function specialization then use the pattern body
14949f4dbff6SDimitry Andric // as the location for the function.
14959f4dbff6SDimitry Andric if (const FunctionDecl *SpecDecl = FD->getTemplateInstantiationPattern())
14969f4dbff6SDimitry Andric if (SpecDecl->hasBody(SpecDecl))
14979f4dbff6SDimitry Andric Loc = SpecDecl->getLocation();
14989f4dbff6SDimitry Andric
1499bab175ecSDimitry Andric Stmt *Body = FD->getBody();
1500bab175ecSDimitry Andric
1501344a3780SDimitry Andric if (Body) {
1502344a3780SDimitry Andric // Coroutines always emit lifetime markers.
1503344a3780SDimitry Andric if (isa<CoroutineBodyStmt>(Body))
1504344a3780SDimitry Andric ShouldEmitLifetimeMarkers = true;
1505344a3780SDimitry Andric
1506344a3780SDimitry Andric // Initialize helper which will detect jumps which can cause invalid
1507344a3780SDimitry Andric // lifetime markers.
1508344a3780SDimitry Andric if (ShouldEmitLifetimeMarkers)
1509bab175ecSDimitry Andric Bypasses.Init(Body);
1510344a3780SDimitry Andric }
1511bab175ecSDimitry Andric
151279ade4e0SRoman Divacky // Emit the standard function prologue.
15139f4dbff6SDimitry Andric StartFunction(GD, ResTy, Fn, FnInfo, Args, Loc, BodyRange.getBegin());
15144c8b2481SRoman Divacky
1515344a3780SDimitry Andric // Save parameters for coroutine function.
1516344a3780SDimitry Andric if (Body && isa_and_nonnull<CoroutineBodyStmt>(Body))
1517145449b1SDimitry Andric llvm::append_range(FnArgs, FD->parameters());
1518344a3780SDimitry Andric
1519b1c73532SDimitry Andric // Ensure that the function adheres to the forward progress guarantee, which
1520b1c73532SDimitry Andric // is required by certain optimizations.
1521ac9a064cSDimitry Andric // In C++11 and up, the attribute will be removed if the body contains a
1522ac9a064cSDimitry Andric // trivial empty loop.
1523b1c73532SDimitry Andric if (checkIfFunctionMustProgress())
1524b1c73532SDimitry Andric CurFn->addFnAttr(llvm::Attribute::MustProgress);
1525b1c73532SDimitry Andric
152679ade4e0SRoman Divacky // Generate the body of the function.
152745b53394SDimitry Andric PGO.assignRegionCounters(GD, CurFn);
152879ade4e0SRoman Divacky if (isa<CXXDestructorDecl>(FD))
152979ade4e0SRoman Divacky EmitDestructorBody(Args);
153079ade4e0SRoman Divacky else if (isa<CXXConstructorDecl>(FD))
153179ade4e0SRoman Divacky EmitConstructorBody(Args);
153213cc256eSDimitry Andric else if (getLangOpts().CUDA &&
15335e20cdd8SDimitry Andric !getLangOpts().CUDAIsDevice &&
153436981b17SDimitry Andric FD->hasAttr<CUDAGlobalAttr>())
15355e20cdd8SDimitry Andric CGM.getCUDARuntime().emitDeviceStub(*this, Args);
1536461a67faSDimitry Andric else if (isa<CXXMethodDecl>(FD) &&
1537dbe13110SDimitry Andric cast<CXXMethodDecl>(FD)->isLambdaStaticInvoker()) {
1538bfef3995SDimitry Andric // The lambda static invoker function is special, because it forwards or
1539dbe13110SDimitry Andric // clones the body of the function call operator (but is actually static).
1540461a67faSDimitry Andric EmitLambdaStaticInvokeBody(cast<CXXMethodDecl>(FD));
1541b1c73532SDimitry Andric } else if (isa<CXXMethodDecl>(FD) &&
1542b1c73532SDimitry Andric isLambdaCallOperator(cast<CXXMethodDecl>(FD)) &&
1543b1c73532SDimitry Andric !FnInfo.isDelegateCall() &&
1544b1c73532SDimitry Andric cast<CXXMethodDecl>(FD)->getParent()->getLambdaStaticInvoker() &&
1545b1c73532SDimitry Andric hasInAllocaArg(cast<CXXMethodDecl>(FD))) {
1546b1c73532SDimitry Andric // If emitting a lambda with static invoker on X86 Windows, change
1547b1c73532SDimitry Andric // the call operator body.
1548b1c73532SDimitry Andric // Make sure that this is a call operator with an inalloca arg and check
1549b1c73532SDimitry Andric // for delegate call to make sure this is the original call op and not the
1550b1c73532SDimitry Andric // new forwarding function for the static invoker.
1551b1c73532SDimitry Andric EmitLambdaInAllocaCallOpBody(cast<CXXMethodDecl>(FD));
1552809500fcSDimitry Andric } else if (FD->isDefaulted() && isa<CXXMethodDecl>(FD) &&
1553bfef3995SDimitry Andric (cast<CXXMethodDecl>(FD)->isCopyAssignmentOperator() ||
1554bfef3995SDimitry Andric cast<CXXMethodDecl>(FD)->isMoveAssignmentOperator())) {
1555809500fcSDimitry Andric // Implicit copy-assignment gets the same special treatment as implicit
1556809500fcSDimitry Andric // copy-constructors.
1557809500fcSDimitry Andric emitImplicitAssignmentOperatorBody(Args);
1558bab175ecSDimitry Andric } else if (Body) {
1559676fbe81SDimitry Andric EmitFunctionBody(Body);
1560bfef3995SDimitry Andric } else
1561bfef3995SDimitry Andric llvm_unreachable("no definition for emitted function");
1562b3d5a323SRoman Divacky
156313cc256eSDimitry Andric // C++11 [stmt.return]p2:
156413cc256eSDimitry Andric // Flowing off the end of a function [...] results in undefined behavior in
156513cc256eSDimitry Andric // a value-returning function.
156613cc256eSDimitry Andric // C11 6.9.1p12:
156713cc256eSDimitry Andric // If the '}' that terminates a function is reached, and the value of the
156813cc256eSDimitry Andric // function call is used by the caller, the behavior is undefined.
156906d4ba38SDimitry Andric if (getLangOpts().CPlusPlus && !FD->hasImplicitReturnZero() && !SawAsmBlock &&
15709f4dbff6SDimitry Andric !FD->getReturnType()->isVoidType() && Builder.GetInsertBlock()) {
15710c75eea8SDimitry Andric bool ShouldEmitUnreachable =
15720c75eea8SDimitry Andric CGM.getCodeGenOpts().StrictReturn ||
1573344a3780SDimitry Andric !CGM.MayDropFunctionReturn(FD->getASTContext(), FD->getReturnType());
157406d4ba38SDimitry Andric if (SanOpts.has(SanitizerKind::Return)) {
15759f4dbff6SDimitry Andric SanitizerScope SanScope(this);
157606d4ba38SDimitry Andric llvm::Value *IsFalse = Builder.getFalse();
157706d4ba38SDimitry Andric EmitCheck(std::make_pair(IsFalse, SanitizerKind::Return),
1578bab175ecSDimitry Andric SanitizerHandler::MissingReturn,
1579e3b55780SDimitry Andric EmitCheckSourceLocation(FD->getLocation()), std::nullopt);
15800c75eea8SDimitry Andric } else if (ShouldEmitUnreachable) {
15810c75eea8SDimitry Andric if (CGM.getCodeGenOpts().OptimizationLevel == 0)
1582c192b3dcSDimitry Andric EmitTrapCall(llvm::Intrinsic::trap);
1583c192b3dcSDimitry Andric }
15840c75eea8SDimitry Andric if (SanOpts.has(SanitizerKind::Return) || ShouldEmitUnreachable) {
158513cc256eSDimitry Andric Builder.CreateUnreachable();
158613cc256eSDimitry Andric Builder.ClearInsertionPoint();
158713cc256eSDimitry Andric }
15880c75eea8SDimitry Andric }
158913cc256eSDimitry Andric
159079ade4e0SRoman Divacky // Emit the standard function epilogue.
159179ade4e0SRoman Divacky FinishFunction(BodyRange.getEnd());
1592ec2b103cSEd Schouten
15933d1dcd9bSDimitry Andric // If we haven't marked the function nothrow through other means, do
15943d1dcd9bSDimitry Andric // a quick pass now to see if we can.
15953d1dcd9bSDimitry Andric if (!CurFn->doesNotThrow())
15963d1dcd9bSDimitry Andric TryMarkNoThrow(CurFn);
1597ec2b103cSEd Schouten }
1598ec2b103cSEd Schouten
1599ec2b103cSEd Schouten /// ContainsLabel - Return true if the statement contains a label in it. If
1600ec2b103cSEd Schouten /// this statement is not executed normally, it not containing a label means
1601ec2b103cSEd Schouten /// that we can just remove the code.
ContainsLabel(const Stmt * S,bool IgnoreCaseStmts)1602ec2b103cSEd Schouten bool CodeGenFunction::ContainsLabel(const Stmt *S, bool IgnoreCaseStmts) {
1603ec2b103cSEd Schouten // Null statement, not a label!
16049f4dbff6SDimitry Andric if (!S) return false;
1605ec2b103cSEd Schouten
1606ec2b103cSEd Schouten // If this is a label, we have to emit the code, consider something like:
1607ec2b103cSEd Schouten // if (0) { ... foo: bar(); } goto foo;
160801af97d3SDimitry Andric //
160901af97d3SDimitry Andric // TODO: If anyone cared, we could track __label__'s, since we know that you
161001af97d3SDimitry Andric // can't jump to one from outside their declared region.
1611ec2b103cSEd Schouten if (isa<LabelStmt>(S))
1612ec2b103cSEd Schouten return true;
1613ec2b103cSEd Schouten
1614ec2b103cSEd Schouten // If this is a case/default statement, and we haven't seen a switch, we have
1615ec2b103cSEd Schouten // to emit the code.
1616ec2b103cSEd Schouten if (isa<SwitchCase>(S) && !IgnoreCaseStmts)
1617ec2b103cSEd Schouten return true;
1618ec2b103cSEd Schouten
1619ec2b103cSEd Schouten // If this is a switch statement, we want to ignore cases below it.
1620ec2b103cSEd Schouten if (isa<SwitchStmt>(S))
1621ec2b103cSEd Schouten IgnoreCaseStmts = true;
1622ec2b103cSEd Schouten
1623ec2b103cSEd Schouten // Scan subexpressions for verboten labels.
1624c192b3dcSDimitry Andric for (const Stmt *SubStmt : S->children())
1625c192b3dcSDimitry Andric if (ContainsLabel(SubStmt, IgnoreCaseStmts))
1626ec2b103cSEd Schouten return true;
1627ec2b103cSEd Schouten
1628ec2b103cSEd Schouten return false;
1629ec2b103cSEd Schouten }
1630ec2b103cSEd Schouten
163101af97d3SDimitry Andric /// containsBreak - Return true if the statement contains a break out of it.
163201af97d3SDimitry Andric /// If the statement (recursively) contains a switch or loop with a break
163301af97d3SDimitry Andric /// inside of it, this is fine.
containsBreak(const Stmt * S)163401af97d3SDimitry Andric bool CodeGenFunction::containsBreak(const Stmt *S) {
163501af97d3SDimitry Andric // Null statement, not a label!
16369f4dbff6SDimitry Andric if (!S) return false;
1637ec2b103cSEd Schouten
163801af97d3SDimitry Andric // If this is a switch or loop that defines its own break scope, then we can
163901af97d3SDimitry Andric // include it and anything inside of it.
164001af97d3SDimitry Andric if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || isa<DoStmt>(S) ||
164101af97d3SDimitry Andric isa<ForStmt>(S))
164201af97d3SDimitry Andric return false;
164301af97d3SDimitry Andric
164401af97d3SDimitry Andric if (isa<BreakStmt>(S))
164501af97d3SDimitry Andric return true;
164601af97d3SDimitry Andric
164701af97d3SDimitry Andric // Scan subexpressions for verboten breaks.
1648c192b3dcSDimitry Andric for (const Stmt *SubStmt : S->children())
1649c192b3dcSDimitry Andric if (containsBreak(SubStmt))
165001af97d3SDimitry Andric return true;
165101af97d3SDimitry Andric
165201af97d3SDimitry Andric return false;
165301af97d3SDimitry Andric }
165401af97d3SDimitry Andric
mightAddDeclToScope(const Stmt * S)165517c7957fSDimitry Andric bool CodeGenFunction::mightAddDeclToScope(const Stmt *S) {
165617c7957fSDimitry Andric if (!S) return false;
165717c7957fSDimitry Andric
165817c7957fSDimitry Andric // Some statement kinds add a scope and thus never add a decl to the current
165917c7957fSDimitry Andric // scope. Note, this list is longer than the list of statements that might
166017c7957fSDimitry Andric // have an unscoped decl nested within them, but this way is conservatively
166117c7957fSDimitry Andric // correct even if more statement kinds are added.
166217c7957fSDimitry Andric if (isa<IfStmt>(S) || isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
166317c7957fSDimitry Andric isa<DoStmt>(S) || isa<ForStmt>(S) || isa<CompoundStmt>(S) ||
166417c7957fSDimitry Andric isa<CXXForRangeStmt>(S) || isa<CXXTryStmt>(S) ||
166517c7957fSDimitry Andric isa<ObjCForCollectionStmt>(S) || isa<ObjCAtTryStmt>(S))
166617c7957fSDimitry Andric return false;
166717c7957fSDimitry Andric
166817c7957fSDimitry Andric if (isa<DeclStmt>(S))
166917c7957fSDimitry Andric return true;
167017c7957fSDimitry Andric
167117c7957fSDimitry Andric for (const Stmt *SubStmt : S->children())
167217c7957fSDimitry Andric if (mightAddDeclToScope(SubStmt))
167317c7957fSDimitry Andric return true;
167417c7957fSDimitry Andric
167517c7957fSDimitry Andric return false;
167617c7957fSDimitry Andric }
167701af97d3SDimitry Andric
167801af97d3SDimitry Andric /// ConstantFoldsToSimpleInteger - If the specified expression does not fold
167901af97d3SDimitry Andric /// to a constant, or if it does but contains a label, return false. If it
168001af97d3SDimitry Andric /// constant folds return true and set the boolean result in Result.
ConstantFoldsToSimpleInteger(const Expr * Cond,bool & ResultBool,bool AllowLabels)168101af97d3SDimitry Andric bool CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond,
16822b6b257fSDimitry Andric bool &ResultBool,
16832b6b257fSDimitry Andric bool AllowLabels) {
1684aca2e42cSDimitry Andric // If MC/DC is enabled, disable folding so that we can instrument all
1685aca2e42cSDimitry Andric // conditions to yield complete test vectors. We still keep track of
1686aca2e42cSDimitry Andric // folded conditions during region mapping and visualization.
1687aca2e42cSDimitry Andric if (!AllowLabels && CGM.getCodeGenOpts().hasProfileClangInstr() &&
1688aca2e42cSDimitry Andric CGM.getCodeGenOpts().MCDCCoverage)
1689aca2e42cSDimitry Andric return false;
1690aca2e42cSDimitry Andric
169156d91b49SDimitry Andric llvm::APSInt ResultInt;
16922b6b257fSDimitry Andric if (!ConstantFoldsToSimpleInteger(Cond, ResultInt, AllowLabels))
169301af97d3SDimitry Andric return false;
169401af97d3SDimitry Andric
169501af97d3SDimitry Andric ResultBool = ResultInt.getBoolValue();
169601af97d3SDimitry Andric return true;
169701af97d3SDimitry Andric }
169801af97d3SDimitry Andric
169901af97d3SDimitry Andric /// ConstantFoldsToSimpleInteger - If the specified expression does not fold
170001af97d3SDimitry Andric /// to a constant, or if it does but contains a label, return false. If it
170101af97d3SDimitry Andric /// constant folds return true and set the folded value.
ConstantFoldsToSimpleInteger(const Expr * Cond,llvm::APSInt & ResultInt,bool AllowLabels)17022b6b257fSDimitry Andric bool CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond,
17032b6b257fSDimitry Andric llvm::APSInt &ResultInt,
17042b6b257fSDimitry Andric bool AllowLabels) {
1705ec2b103cSEd Schouten // FIXME: Rename and handle conversion of other evaluatable things
1706ec2b103cSEd Schouten // to bool.
1707676fbe81SDimitry Andric Expr::EvalResult Result;
1708676fbe81SDimitry Andric if (!Cond->EvaluateAsInt(Result, getContext()))
170901af97d3SDimitry Andric return false; // Not foldable, not integer or not fully evaluatable.
1710ec2b103cSEd Schouten
1711676fbe81SDimitry Andric llvm::APSInt Int = Result.Val.getInt();
17122b6b257fSDimitry Andric if (!AllowLabels && CodeGenFunction::ContainsLabel(Cond))
171301af97d3SDimitry Andric return false; // Contains a label.
1714ec2b103cSEd Schouten
1715dbe13110SDimitry Andric ResultInt = Int;
171601af97d3SDimitry Andric return true;
1717ec2b103cSEd Schouten }
1718ec2b103cSEd Schouten
1719aca2e42cSDimitry Andric /// Strip parentheses and simplistic logical-NOT operators.
stripCond(const Expr * C)1720aca2e42cSDimitry Andric const Expr *CodeGenFunction::stripCond(const Expr *C) {
1721aca2e42cSDimitry Andric while (const UnaryOperator *Op = dyn_cast<UnaryOperator>(C->IgnoreParens())) {
1722aca2e42cSDimitry Andric if (Op->getOpcode() != UO_LNot)
1723aca2e42cSDimitry Andric break;
1724aca2e42cSDimitry Andric C = Op->getSubExpr();
1725aca2e42cSDimitry Andric }
1726aca2e42cSDimitry Andric return C->IgnoreParens();
1727aca2e42cSDimitry Andric }
1728aca2e42cSDimitry Andric
1729b60736ecSDimitry Andric /// Determine whether the given condition is an instrumentable condition
1730b60736ecSDimitry Andric /// (i.e. no "&&" or "||").
isInstrumentedCondition(const Expr * C)1731b60736ecSDimitry Andric bool CodeGenFunction::isInstrumentedCondition(const Expr *C) {
1732aca2e42cSDimitry Andric const BinaryOperator *BOp = dyn_cast<BinaryOperator>(stripCond(C));
1733b60736ecSDimitry Andric return (!BOp || !BOp->isLogicalOp());
1734b60736ecSDimitry Andric }
1735b60736ecSDimitry Andric
1736b60736ecSDimitry Andric /// EmitBranchToCounterBlock - Emit a conditional branch to a new block that
1737b60736ecSDimitry Andric /// increments a profile counter based on the semantics of the given logical
1738b60736ecSDimitry Andric /// operator opcode. This is used to instrument branch condition coverage for
1739b60736ecSDimitry Andric /// logical operators.
EmitBranchToCounterBlock(const Expr * Cond,BinaryOperator::Opcode LOp,llvm::BasicBlock * TrueBlock,llvm::BasicBlock * FalseBlock,uint64_t TrueCount,Stmt::Likelihood LH,const Expr * CntrIdx)1740b60736ecSDimitry Andric void CodeGenFunction::EmitBranchToCounterBlock(
1741b60736ecSDimitry Andric const Expr *Cond, BinaryOperator::Opcode LOp, llvm::BasicBlock *TrueBlock,
1742b60736ecSDimitry Andric llvm::BasicBlock *FalseBlock, uint64_t TrueCount /* = 0 */,
1743b60736ecSDimitry Andric Stmt::Likelihood LH /* =None */, const Expr *CntrIdx /* = nullptr */) {
1744b60736ecSDimitry Andric // If not instrumenting, just emit a branch.
1745b60736ecSDimitry Andric bool InstrumentRegions = CGM.getCodeGenOpts().hasProfileClangInstr();
1746b60736ecSDimitry Andric if (!InstrumentRegions || !isInstrumentedCondition(Cond))
1747b60736ecSDimitry Andric return EmitBranchOnBoolExpr(Cond, TrueBlock, FalseBlock, TrueCount, LH);
1748b60736ecSDimitry Andric
17496f8fc217SDimitry Andric llvm::BasicBlock *ThenBlock = nullptr;
17506f8fc217SDimitry Andric llvm::BasicBlock *ElseBlock = nullptr;
17516f8fc217SDimitry Andric llvm::BasicBlock *NextBlock = nullptr;
1752b60736ecSDimitry Andric
1753b60736ecSDimitry Andric // Create the block we'll use to increment the appropriate counter.
1754b60736ecSDimitry Andric llvm::BasicBlock *CounterIncrBlock = createBasicBlock("lop.rhscnt");
1755b60736ecSDimitry Andric
1756b60736ecSDimitry Andric // Set block pointers according to Logical-AND (BO_LAnd) semantics. This
1757b60736ecSDimitry Andric // means we need to evaluate the condition and increment the counter on TRUE:
1758b60736ecSDimitry Andric //
1759b60736ecSDimitry Andric // if (Cond)
1760b60736ecSDimitry Andric // goto CounterIncrBlock;
1761b60736ecSDimitry Andric // else
1762b60736ecSDimitry Andric // goto FalseBlock;
1763b60736ecSDimitry Andric //
1764b60736ecSDimitry Andric // CounterIncrBlock:
1765b60736ecSDimitry Andric // Counter++;
1766b60736ecSDimitry Andric // goto TrueBlock;
1767b60736ecSDimitry Andric
1768b60736ecSDimitry Andric if (LOp == BO_LAnd) {
1769b60736ecSDimitry Andric ThenBlock = CounterIncrBlock;
1770b60736ecSDimitry Andric ElseBlock = FalseBlock;
1771b60736ecSDimitry Andric NextBlock = TrueBlock;
1772b60736ecSDimitry Andric }
1773b60736ecSDimitry Andric
1774b60736ecSDimitry Andric // Set block pointers according to Logical-OR (BO_LOr) semantics. This means
1775b60736ecSDimitry Andric // we need to evaluate the condition and increment the counter on FALSE:
1776b60736ecSDimitry Andric //
1777b60736ecSDimitry Andric // if (Cond)
1778b60736ecSDimitry Andric // goto TrueBlock;
1779b60736ecSDimitry Andric // else
1780b60736ecSDimitry Andric // goto CounterIncrBlock;
1781b60736ecSDimitry Andric //
1782b60736ecSDimitry Andric // CounterIncrBlock:
1783b60736ecSDimitry Andric // Counter++;
1784b60736ecSDimitry Andric // goto FalseBlock;
1785b60736ecSDimitry Andric
1786b60736ecSDimitry Andric else if (LOp == BO_LOr) {
1787b60736ecSDimitry Andric ThenBlock = TrueBlock;
1788b60736ecSDimitry Andric ElseBlock = CounterIncrBlock;
1789b60736ecSDimitry Andric NextBlock = FalseBlock;
1790b60736ecSDimitry Andric } else {
1791b60736ecSDimitry Andric llvm_unreachable("Expected Opcode must be that of a Logical Operator");
1792b60736ecSDimitry Andric }
1793b60736ecSDimitry Andric
1794b60736ecSDimitry Andric // Emit Branch based on condition.
1795b60736ecSDimitry Andric EmitBranchOnBoolExpr(Cond, ThenBlock, ElseBlock, TrueCount, LH);
1796b60736ecSDimitry Andric
1797b60736ecSDimitry Andric // Emit the block containing the counter increment(s).
1798b60736ecSDimitry Andric EmitBlock(CounterIncrBlock);
1799b60736ecSDimitry Andric
1800b60736ecSDimitry Andric // Increment corresponding counter; if index not provided, use Cond as index.
1801b60736ecSDimitry Andric incrementProfileCounter(CntrIdx ? CntrIdx : Cond);
1802b60736ecSDimitry Andric
1803b60736ecSDimitry Andric // Go to the next block.
1804b60736ecSDimitry Andric EmitBranch(NextBlock);
1805b60736ecSDimitry Andric }
180601af97d3SDimitry Andric
1807ec2b103cSEd Schouten /// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an if
1808ec2b103cSEd Schouten /// statement) to the specified blocks. Based on the condition, this might try
1809ec2b103cSEd Schouten /// to simplify the codegen of the conditional based on the branch.
1810b60736ecSDimitry Andric /// \param LH The value of the likelihood attribute on the True branch.
1811aca2e42cSDimitry Andric /// \param ConditionalOp Used by MC/DC code coverage to track the result of the
1812aca2e42cSDimitry Andric /// ConditionalOperator (ternary) through a recursive call for the operator's
1813aca2e42cSDimitry Andric /// LHS and RHS nodes.
EmitBranchOnBoolExpr(const Expr * Cond,llvm::BasicBlock * TrueBlock,llvm::BasicBlock * FalseBlock,uint64_t TrueCount,Stmt::Likelihood LH,const Expr * ConditionalOp)1814aca2e42cSDimitry Andric void CodeGenFunction::EmitBranchOnBoolExpr(
1815aca2e42cSDimitry Andric const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock,
1816aca2e42cSDimitry Andric uint64_t TrueCount, Stmt::Likelihood LH, const Expr *ConditionalOp) {
181701af97d3SDimitry Andric Cond = Cond->IgnoreParens();
1818ec2b103cSEd Schouten
1819ec2b103cSEd Schouten if (const BinaryOperator *CondBOp = dyn_cast<BinaryOperator>(Cond)) {
1820ec2b103cSEd Schouten // Handle X && Y in a condition.
18213d1dcd9bSDimitry Andric if (CondBOp->getOpcode() == BO_LAnd) {
1822aca2e42cSDimitry Andric MCDCLogOpStack.push_back(CondBOp);
1823aca2e42cSDimitry Andric
1824ec2b103cSEd Schouten // If we have "1 && X", simplify the code. "0 && X" would have constant
1825ec2b103cSEd Schouten // folded if the case was simple enough.
182601af97d3SDimitry Andric bool ConstantBool = false;
182701af97d3SDimitry Andric if (ConstantFoldsToSimpleInteger(CondBOp->getLHS(), ConstantBool) &&
182801af97d3SDimitry Andric ConstantBool) {
1829ec2b103cSEd Schouten // br(1 && X) -> br(X).
18305e20cdd8SDimitry Andric incrementProfileCounter(CondBOp);
1831aca2e42cSDimitry Andric EmitBranchToCounterBlock(CondBOp->getRHS(), BO_LAnd, TrueBlock,
1832b60736ecSDimitry Andric FalseBlock, TrueCount, LH);
1833aca2e42cSDimitry Andric MCDCLogOpStack.pop_back();
1834aca2e42cSDimitry Andric return;
1835ec2b103cSEd Schouten }
1836ec2b103cSEd Schouten
1837ec2b103cSEd Schouten // If we have "X && 1", simplify the code to use an uncond branch.
1838ec2b103cSEd Schouten // "X && 0" would have been constant folded to 0.
183901af97d3SDimitry Andric if (ConstantFoldsToSimpleInteger(CondBOp->getRHS(), ConstantBool) &&
184001af97d3SDimitry Andric ConstantBool) {
1841ec2b103cSEd Schouten // br(X && 1) -> br(X).
1842aca2e42cSDimitry Andric EmitBranchToCounterBlock(CondBOp->getLHS(), BO_LAnd, TrueBlock,
1843b60736ecSDimitry Andric FalseBlock, TrueCount, LH, CondBOp);
1844aca2e42cSDimitry Andric MCDCLogOpStack.pop_back();
1845aca2e42cSDimitry Andric return;
1846ec2b103cSEd Schouten }
1847ec2b103cSEd Schouten
1848ec2b103cSEd Schouten // Emit the LHS as a conditional. If the LHS conditional is false, we
1849ec2b103cSEd Schouten // want to jump to the FalseBlock.
1850ec2b103cSEd Schouten llvm::BasicBlock *LHSTrue = createBasicBlock("land.lhs.true");
18519f4dbff6SDimitry Andric // The counter tells us how often we evaluate RHS, and all of TrueCount
18529f4dbff6SDimitry Andric // can be propagated to that branch.
18535e20cdd8SDimitry Andric uint64_t RHSCount = getProfileCount(CondBOp->getRHS());
1854bca07a45SDimitry Andric
1855bca07a45SDimitry Andric ConditionalEvaluation eval(*this);
18565e20cdd8SDimitry Andric {
18575e20cdd8SDimitry Andric ApplyDebugLocation DL(*this, Cond);
1858b60736ecSDimitry Andric // Propagate the likelihood attribute like __builtin_expect
1859b60736ecSDimitry Andric // __builtin_expect(X && Y, 1) -> X and Y are likely
1860b60736ecSDimitry Andric // __builtin_expect(X && Y, 0) -> only Y is unlikely
1861b60736ecSDimitry Andric EmitBranchOnBoolExpr(CondBOp->getLHS(), LHSTrue, FalseBlock, RHSCount,
1862b60736ecSDimitry Andric LH == Stmt::LH_Unlikely ? Stmt::LH_None : LH);
1863ec2b103cSEd Schouten EmitBlock(LHSTrue);
18645e20cdd8SDimitry Andric }
18655e20cdd8SDimitry Andric
18665e20cdd8SDimitry Andric incrementProfileCounter(CondBOp);
18675e20cdd8SDimitry Andric setCurrentProfileCount(getProfileCount(CondBOp->getRHS()));
1868ec2b103cSEd Schouten
1869ecb7e5c8SRoman Divacky // Any temporaries created here are conditional.
1870bca07a45SDimitry Andric eval.begin(*this);
1871b60736ecSDimitry Andric EmitBranchToCounterBlock(CondBOp->getRHS(), BO_LAnd, TrueBlock,
1872b60736ecSDimitry Andric FalseBlock, TrueCount, LH);
1873bca07a45SDimitry Andric eval.end(*this);
1874aca2e42cSDimitry Andric MCDCLogOpStack.pop_back();
1875ec2b103cSEd Schouten return;
187601af97d3SDimitry Andric }
187701af97d3SDimitry Andric
187801af97d3SDimitry Andric if (CondBOp->getOpcode() == BO_LOr) {
1879aca2e42cSDimitry Andric MCDCLogOpStack.push_back(CondBOp);
1880aca2e42cSDimitry Andric
1881ec2b103cSEd Schouten // If we have "0 || X", simplify the code. "1 || X" would have constant
1882ec2b103cSEd Schouten // folded if the case was simple enough.
188301af97d3SDimitry Andric bool ConstantBool = false;
188401af97d3SDimitry Andric if (ConstantFoldsToSimpleInteger(CondBOp->getLHS(), ConstantBool) &&
188501af97d3SDimitry Andric !ConstantBool) {
1886ec2b103cSEd Schouten // br(0 || X) -> br(X).
18875e20cdd8SDimitry Andric incrementProfileCounter(CondBOp);
1888aca2e42cSDimitry Andric EmitBranchToCounterBlock(CondBOp->getRHS(), BO_LOr, TrueBlock,
1889b60736ecSDimitry Andric FalseBlock, TrueCount, LH);
1890aca2e42cSDimitry Andric MCDCLogOpStack.pop_back();
1891aca2e42cSDimitry Andric return;
1892ec2b103cSEd Schouten }
1893ec2b103cSEd Schouten
1894ec2b103cSEd Schouten // If we have "X || 0", simplify the code to use an uncond branch.
1895ec2b103cSEd Schouten // "X || 1" would have been constant folded to 1.
189601af97d3SDimitry Andric if (ConstantFoldsToSimpleInteger(CondBOp->getRHS(), ConstantBool) &&
189701af97d3SDimitry Andric !ConstantBool) {
1898ec2b103cSEd Schouten // br(X || 0) -> br(X).
1899aca2e42cSDimitry Andric EmitBranchToCounterBlock(CondBOp->getLHS(), BO_LOr, TrueBlock,
1900b60736ecSDimitry Andric FalseBlock, TrueCount, LH, CondBOp);
1901aca2e42cSDimitry Andric MCDCLogOpStack.pop_back();
1902aca2e42cSDimitry Andric return;
1903ec2b103cSEd Schouten }
1904ec2b103cSEd Schouten // Emit the LHS as a conditional. If the LHS conditional is true, we
1905ec2b103cSEd Schouten // want to jump to the TrueBlock.
1906ec2b103cSEd Schouten llvm::BasicBlock *LHSFalse = createBasicBlock("lor.lhs.false");
19079f4dbff6SDimitry Andric // We have the count for entry to the RHS and for the whole expression
19089f4dbff6SDimitry Andric // being true, so we can divy up True count between the short circuit and
19099f4dbff6SDimitry Andric // the RHS.
19105e20cdd8SDimitry Andric uint64_t LHSCount =
19115e20cdd8SDimitry Andric getCurrentProfileCount() - getProfileCount(CondBOp->getRHS());
19129f4dbff6SDimitry Andric uint64_t RHSCount = TrueCount - LHSCount;
1913bca07a45SDimitry Andric
1914bca07a45SDimitry Andric ConditionalEvaluation eval(*this);
19155e20cdd8SDimitry Andric {
1916b60736ecSDimitry Andric // Propagate the likelihood attribute like __builtin_expect
1917b60736ecSDimitry Andric // __builtin_expect(X || Y, 1) -> only Y is likely
1918b60736ecSDimitry Andric // __builtin_expect(X || Y, 0) -> both X and Y are unlikely
19195e20cdd8SDimitry Andric ApplyDebugLocation DL(*this, Cond);
1920b60736ecSDimitry Andric EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, LHSFalse, LHSCount,
1921b60736ecSDimitry Andric LH == Stmt::LH_Likely ? Stmt::LH_None : LH);
1922ec2b103cSEd Schouten EmitBlock(LHSFalse);
19235e20cdd8SDimitry Andric }
19245e20cdd8SDimitry Andric
19255e20cdd8SDimitry Andric incrementProfileCounter(CondBOp);
19265e20cdd8SDimitry Andric setCurrentProfileCount(getProfileCount(CondBOp->getRHS()));
1927ec2b103cSEd Schouten
1928ecb7e5c8SRoman Divacky // Any temporaries created here are conditional.
1929bca07a45SDimitry Andric eval.begin(*this);
1930b60736ecSDimitry Andric EmitBranchToCounterBlock(CondBOp->getRHS(), BO_LOr, TrueBlock, FalseBlock,
1931b60736ecSDimitry Andric RHSCount, LH);
19329f4dbff6SDimitry Andric
1933bca07a45SDimitry Andric eval.end(*this);
1934aca2e42cSDimitry Andric MCDCLogOpStack.pop_back();
1935ec2b103cSEd Schouten return;
1936ec2b103cSEd Schouten }
1937ec2b103cSEd Schouten }
1938ec2b103cSEd Schouten
1939ec2b103cSEd Schouten if (const UnaryOperator *CondUOp = dyn_cast<UnaryOperator>(Cond)) {
1940ec2b103cSEd Schouten // br(!x, t, f) -> br(x, f, t)
1941aca2e42cSDimitry Andric // Avoid doing this optimization when instrumenting a condition for MC/DC.
1942aca2e42cSDimitry Andric // LNot is taken as part of the condition for simplicity, and changing its
1943aca2e42cSDimitry Andric // sense negatively impacts test vector tracking.
1944aca2e42cSDimitry Andric bool MCDCCondition = CGM.getCodeGenOpts().hasProfileClangInstr() &&
1945aca2e42cSDimitry Andric CGM.getCodeGenOpts().MCDCCoverage &&
1946aca2e42cSDimitry Andric isInstrumentedCondition(Cond);
1947aca2e42cSDimitry Andric if (CondUOp->getOpcode() == UO_LNot && !MCDCCondition) {
19489f4dbff6SDimitry Andric // Negate the count.
19495e20cdd8SDimitry Andric uint64_t FalseCount = getCurrentProfileCount() - TrueCount;
1950b60736ecSDimitry Andric // The values of the enum are chosen to make this negation possible.
1951b60736ecSDimitry Andric LH = static_cast<Stmt::Likelihood>(-LH);
19529f4dbff6SDimitry Andric // Negate the condition and swap the destination blocks.
19539f4dbff6SDimitry Andric return EmitBranchOnBoolExpr(CondUOp->getSubExpr(), FalseBlock, TrueBlock,
1954b60736ecSDimitry Andric FalseCount, LH);
19559f4dbff6SDimitry Andric }
1956ec2b103cSEd Schouten }
1957ec2b103cSEd Schouten
1958ec2b103cSEd Schouten if (const ConditionalOperator *CondOp = dyn_cast<ConditionalOperator>(Cond)) {
1959ec2b103cSEd Schouten // br(c ? x : y, t, f) -> br(c, br(x, t, f), br(y, t, f))
1960ec2b103cSEd Schouten llvm::BasicBlock *LHSBlock = createBasicBlock("cond.true");
1961ec2b103cSEd Schouten llvm::BasicBlock *RHSBlock = createBasicBlock("cond.false");
1962bca07a45SDimitry Andric
1963b60736ecSDimitry Andric // The ConditionalOperator itself has no likelihood information for its
1964b60736ecSDimitry Andric // true and false branches. This matches the behavior of __builtin_expect.
1965bca07a45SDimitry Andric ConditionalEvaluation cond(*this);
19665e20cdd8SDimitry Andric EmitBranchOnBoolExpr(CondOp->getCond(), LHSBlock, RHSBlock,
1967b60736ecSDimitry Andric getProfileCount(CondOp), Stmt::LH_None);
19689f4dbff6SDimitry Andric
19699f4dbff6SDimitry Andric // When computing PGO branch weights, we only know the overall count for
19709f4dbff6SDimitry Andric // the true block. This code is essentially doing tail duplication of the
19719f4dbff6SDimitry Andric // naive code-gen, introducing new edges for which counts are not
19729f4dbff6SDimitry Andric // available. Divide the counts proportionally between the LHS and RHS of
19739f4dbff6SDimitry Andric // the conditional operator.
19749f4dbff6SDimitry Andric uint64_t LHSScaledTrueCount = 0;
19759f4dbff6SDimitry Andric if (TrueCount) {
19765e20cdd8SDimitry Andric double LHSRatio =
19775e20cdd8SDimitry Andric getProfileCount(CondOp) / (double)getCurrentProfileCount();
19789f4dbff6SDimitry Andric LHSScaledTrueCount = TrueCount * LHSRatio;
19799f4dbff6SDimitry Andric }
1980bca07a45SDimitry Andric
1981bca07a45SDimitry Andric cond.begin(*this);
1982ec2b103cSEd Schouten EmitBlock(LHSBlock);
19835e20cdd8SDimitry Andric incrementProfileCounter(CondOp);
19845e20cdd8SDimitry Andric {
19855e20cdd8SDimitry Andric ApplyDebugLocation DL(*this, Cond);
19869f4dbff6SDimitry Andric EmitBranchOnBoolExpr(CondOp->getLHS(), TrueBlock, FalseBlock,
1987aca2e42cSDimitry Andric LHSScaledTrueCount, LH, CondOp);
19885e20cdd8SDimitry Andric }
1989bca07a45SDimitry Andric cond.end(*this);
1990bca07a45SDimitry Andric
1991bca07a45SDimitry Andric cond.begin(*this);
1992ec2b103cSEd Schouten EmitBlock(RHSBlock);
19939f4dbff6SDimitry Andric EmitBranchOnBoolExpr(CondOp->getRHS(), TrueBlock, FalseBlock,
1994aca2e42cSDimitry Andric TrueCount - LHSScaledTrueCount, LH, CondOp);
1995bca07a45SDimitry Andric cond.end(*this);
1996bca07a45SDimitry Andric
1997ec2b103cSEd Schouten return;
1998ec2b103cSEd Schouten }
1999ec2b103cSEd Schouten
20006a037251SDimitry Andric if (const CXXThrowExpr *Throw = dyn_cast<CXXThrowExpr>(Cond)) {
20016a037251SDimitry Andric // Conditional operator handling can give us a throw expression as a
20026a037251SDimitry Andric // condition for a case like:
20036a037251SDimitry Andric // br(c ? throw x : y, t, f) -> br(c, br(throw x, t, f), br(y, t, f)
20046a037251SDimitry Andric // Fold this to:
20056a037251SDimitry Andric // br(c, throw x, br(y, t, f))
20066a037251SDimitry Andric EmitCXXThrowExpr(Throw, /*KeepInsertionPoint*/false);
20076a037251SDimitry Andric return;
20086a037251SDimitry Andric }
20096a037251SDimitry Andric
2010344a3780SDimitry Andric // Emit the code with the fully general case.
2011344a3780SDimitry Andric llvm::Value *CondV;
2012344a3780SDimitry Andric {
2013344a3780SDimitry Andric ApplyDebugLocation DL(*this, Cond);
2014344a3780SDimitry Andric CondV = EvaluateExprAsBool(Cond);
2015344a3780SDimitry Andric }
2016344a3780SDimitry Andric
2017aca2e42cSDimitry Andric // If not at the top of the logical operator nest, update MCDC temp with the
2018aca2e42cSDimitry Andric // boolean result of the evaluated condition.
2019aca2e42cSDimitry Andric if (!MCDCLogOpStack.empty()) {
2020aca2e42cSDimitry Andric const Expr *MCDCBaseExpr = Cond;
2021aca2e42cSDimitry Andric // When a nested ConditionalOperator (ternary) is encountered in a boolean
2022aca2e42cSDimitry Andric // expression, MC/DC tracks the result of the ternary, and this is tied to
2023aca2e42cSDimitry Andric // the ConditionalOperator expression and not the ternary's LHS or RHS. If
2024aca2e42cSDimitry Andric // this is the case, the ConditionalOperator expression is passed through
2025aca2e42cSDimitry Andric // the ConditionalOp parameter and then used as the MCDC base expression.
2026aca2e42cSDimitry Andric if (ConditionalOp)
2027aca2e42cSDimitry Andric MCDCBaseExpr = ConditionalOp;
2028aca2e42cSDimitry Andric
2029aca2e42cSDimitry Andric maybeUpdateMCDCCondBitmap(MCDCBaseExpr, CondV);
2030aca2e42cSDimitry Andric }
2031aca2e42cSDimitry Andric
2032344a3780SDimitry Andric llvm::MDNode *Weights = nullptr;
2033344a3780SDimitry Andric llvm::MDNode *Unpredictable = nullptr;
2034344a3780SDimitry Andric
203545b53394SDimitry Andric // If the branch has a condition wrapped by __builtin_unpredictable,
203645b53394SDimitry Andric // create metadata that specifies that the branch is unpredictable.
203745b53394SDimitry Andric // Don't bother if not optimizing because that metadata would not be used.
2038676fbe81SDimitry Andric auto *Call = dyn_cast<CallExpr>(Cond->IgnoreImpCasts());
20392b6b257fSDimitry Andric if (Call && CGM.getCodeGenOpts().OptimizationLevel != 0) {
20402b6b257fSDimitry Andric auto *FD = dyn_cast_or_null<FunctionDecl>(Call->getCalleeDecl());
20412b6b257fSDimitry Andric if (FD && FD->getBuiltinID() == Builtin::BI__builtin_unpredictable) {
204245b53394SDimitry Andric llvm::MDBuilder MDHelper(getLLVMContext());
204345b53394SDimitry Andric Unpredictable = MDHelper.createUnpredictable();
204445b53394SDimitry Andric }
204545b53394SDimitry Andric }
204645b53394SDimitry Andric
2047344a3780SDimitry Andric // If there is a Likelihood knowledge for the cond, lower it.
2048344a3780SDimitry Andric // Note that if not optimizing this won't emit anything.
2049344a3780SDimitry Andric llvm::Value *NewCondV = emitCondLikelihoodViaExpectIntrinsic(CondV, LH);
2050344a3780SDimitry Andric if (CondV != NewCondV)
2051344a3780SDimitry Andric CondV = NewCondV;
2052344a3780SDimitry Andric else {
2053344a3780SDimitry Andric // Otherwise, lower profile counts. Note that we do this even at -O0.
20545e20cdd8SDimitry Andric uint64_t CurrentCount = std::max(getCurrentProfileCount(), TrueCount);
2055b60736ecSDimitry Andric Weights = createProfileWeights(TrueCount, CurrentCount - TrueCount);
2056b60736ecSDimitry Andric }
20579f4dbff6SDimitry Andric
205845b53394SDimitry Andric Builder.CreateCondBr(CondV, TrueBlock, FalseBlock, Weights, Unpredictable);
2059ec2b103cSEd Schouten }
2060ec2b103cSEd Schouten
2061ec2b103cSEd Schouten /// ErrorUnsupported - Print out an error that codegen doesn't support the
2062ec2b103cSEd Schouten /// specified stmt yet.
ErrorUnsupported(const Stmt * S,const char * Type)2063bfef3995SDimitry Andric void CodeGenFunction::ErrorUnsupported(const Stmt *S, const char *Type) {
2064bfef3995SDimitry Andric CGM.ErrorUnsupported(S, Type);
2065ec2b103cSEd Schouten }
2066ec2b103cSEd Schouten
2067bca07a45SDimitry Andric /// emitNonZeroVLAInit - Emit the "zero" initialization of a
2068bca07a45SDimitry Andric /// variable-length array whose elements have a non-zero bit-pattern.
2069bca07a45SDimitry Andric ///
207056d91b49SDimitry Andric /// \param baseType the inner-most element type of the array
2071bca07a45SDimitry Andric /// \param src - a char* pointing to the bit-pattern for a single
2072bca07a45SDimitry Andric /// base element of the array
2073bca07a45SDimitry Andric /// \param sizeInChars - the total size of the VLA, in chars
emitNonZeroVLAInit(CodeGenFunction & CGF,QualType baseType,Address dest,Address src,llvm::Value * sizeInChars)2074bca07a45SDimitry Andric static void emitNonZeroVLAInit(CodeGenFunction &CGF, QualType baseType,
207545b53394SDimitry Andric Address dest, Address src,
2076bca07a45SDimitry Andric llvm::Value *sizeInChars) {
2077bca07a45SDimitry Andric CGBuilderTy &Builder = CGF.Builder;
2078bca07a45SDimitry Andric
207945b53394SDimitry Andric CharUnits baseSize = CGF.getContext().getTypeSizeInChars(baseType);
2080bca07a45SDimitry Andric llvm::Value *baseSizeInChars
208145b53394SDimitry Andric = llvm::ConstantInt::get(CGF.IntPtrTy, baseSize.getQuantity());
2082bca07a45SDimitry Andric
20837fa27ce4SDimitry Andric Address begin = dest.withElementType(CGF.Int8Ty);
2084ac9a064cSDimitry Andric llvm::Value *end = Builder.CreateInBoundsGEP(begin.getElementType(),
2085ac9a064cSDimitry Andric begin.emitRawPointer(CGF),
2086ac9a064cSDimitry Andric sizeInChars, "vla.end");
2087bca07a45SDimitry Andric
2088bca07a45SDimitry Andric llvm::BasicBlock *originBB = CGF.Builder.GetInsertBlock();
2089bca07a45SDimitry Andric llvm::BasicBlock *loopBB = CGF.createBasicBlock("vla-init.loop");
2090bca07a45SDimitry Andric llvm::BasicBlock *contBB = CGF.createBasicBlock("vla-init.cont");
2091bca07a45SDimitry Andric
2092bca07a45SDimitry Andric // Make a loop over the VLA. C99 guarantees that the VLA element
2093bca07a45SDimitry Andric // count must be nonzero.
2094bca07a45SDimitry Andric CGF.EmitBlock(loopBB);
2095bca07a45SDimitry Andric
209645b53394SDimitry Andric llvm::PHINode *cur = Builder.CreatePHI(begin.getType(), 2, "vla.cur");
2097ac9a064cSDimitry Andric cur->addIncoming(begin.emitRawPointer(CGF), originBB);
209845b53394SDimitry Andric
209945b53394SDimitry Andric CharUnits curAlign =
210045b53394SDimitry Andric dest.getAlignment().alignmentOfArrayElement(baseSize);
2101bca07a45SDimitry Andric
2102bca07a45SDimitry Andric // memcpy the individual element bit-pattern.
2103145449b1SDimitry Andric Builder.CreateMemCpy(Address(cur, CGF.Int8Ty, curAlign), src, baseSizeInChars,
2104bca07a45SDimitry Andric /*volatile*/ false);
2105bca07a45SDimitry Andric
2106bca07a45SDimitry Andric // Go to the next element.
210745b53394SDimitry Andric llvm::Value *next =
210845b53394SDimitry Andric Builder.CreateInBoundsGEP(CGF.Int8Ty, cur, baseSizeInChars, "vla.next");
2109bca07a45SDimitry Andric
2110bca07a45SDimitry Andric // Leave if that's the end of the VLA.
2111bca07a45SDimitry Andric llvm::Value *done = Builder.CreateICmpEQ(next, end, "vla-init.isdone");
2112bca07a45SDimitry Andric Builder.CreateCondBr(done, contBB, loopBB);
2113bca07a45SDimitry Andric cur->addIncoming(next, loopBB);
2114bca07a45SDimitry Andric
2115bca07a45SDimitry Andric CGF.EmitBlock(contBB);
2116bca07a45SDimitry Andric }
2117bca07a45SDimitry Andric
2118d7279c4cSRoman Divacky void
EmitNullInitialization(Address DestPtr,QualType Ty)211945b53394SDimitry Andric CodeGenFunction::EmitNullInitialization(Address DestPtr, QualType Ty) {
21200883ccd9SRoman Divacky // Ignore empty classes in C++.
212113cc256eSDimitry Andric if (getLangOpts().CPlusPlus) {
21220883ccd9SRoman Divacky if (const RecordType *RT = Ty->getAs<RecordType>()) {
21230883ccd9SRoman Divacky if (cast<CXXRecordDecl>(RT->getDecl())->isEmpty())
21240883ccd9SRoman Divacky return;
21250883ccd9SRoman Divacky }
21260883ccd9SRoman Divacky }
21270883ccd9SRoman Divacky
212845b53394SDimitry Andric if (DestPtr.getElementType() != Int8Ty)
21297fa27ce4SDimitry Andric DestPtr = DestPtr.withElementType(Int8Ty);
2130ec2b103cSEd Schouten
2131ec2b103cSEd Schouten // Get size and alignment info for this aggregate.
213245b53394SDimitry Andric CharUnits size = getContext().getTypeSizeInChars(Ty);
2133bca07a45SDimitry Andric
2134bca07a45SDimitry Andric llvm::Value *SizeVal;
2135bca07a45SDimitry Andric const VariableArrayType *vla;
2136ec2b103cSEd Schouten
2137ec2b103cSEd Schouten // Don't bother emitting a zero-byte memset.
213845b53394SDimitry Andric if (size.isZero()) {
2139bca07a45SDimitry Andric // But note that getTypeInfo returns 0 for a VLA.
2140bca07a45SDimitry Andric if (const VariableArrayType *vlaType =
2141bca07a45SDimitry Andric dyn_cast_or_null<VariableArrayType>(
2142bca07a45SDimitry Andric getContext().getAsArrayType(Ty))) {
214348675466SDimitry Andric auto VlaSize = getVLASize(vlaType);
214448675466SDimitry Andric SizeVal = VlaSize.NumElts;
214548675466SDimitry Andric CharUnits eltSize = getContext().getTypeSizeInChars(VlaSize.Type);
2146180abc3dSDimitry Andric if (!eltSize.isOne())
2147180abc3dSDimitry Andric SizeVal = Builder.CreateNUWMul(SizeVal, CGM.getSize(eltSize));
2148bca07a45SDimitry Andric vla = vlaType;
2149bca07a45SDimitry Andric } else {
2150ec2b103cSEd Schouten return;
2151bca07a45SDimitry Andric }
2152bca07a45SDimitry Andric } else {
215345b53394SDimitry Andric SizeVal = CGM.getSize(size);
21549f4dbff6SDimitry Andric vla = nullptr;
2155bca07a45SDimitry Andric }
21563d1dcd9bSDimitry Andric
21573d1dcd9bSDimitry Andric // If the type contains a pointer to data member we can't memset it to zero.
21583d1dcd9bSDimitry Andric // Instead, create a null constant and copy it to the destination.
2159bca07a45SDimitry Andric // TODO: there are other patterns besides zero that we can usefully memset,
2160bca07a45SDimitry Andric // like -1, which happens to be the pattern used by member-pointers.
21613d1dcd9bSDimitry Andric if (!CGM.getTypes().isZeroInitializable(Ty)) {
2162bca07a45SDimitry Andric // For a VLA, emit a single element, then splat that over the VLA.
2163bca07a45SDimitry Andric if (vla) Ty = getContext().getBaseElementType(vla);
2164bca07a45SDimitry Andric
21653d1dcd9bSDimitry Andric llvm::Constant *NullConstant = CGM.EmitNullConstant(Ty);
21663d1dcd9bSDimitry Andric
21673d1dcd9bSDimitry Andric llvm::GlobalVariable *NullVariable =
21683d1dcd9bSDimitry Andric new llvm::GlobalVariable(CGM.getModule(), NullConstant->getType(),
21693d1dcd9bSDimitry Andric /*isConstant=*/true,
21703d1dcd9bSDimitry Andric llvm::GlobalVariable::PrivateLinkage,
217136981b17SDimitry Andric NullConstant, Twine());
217245b53394SDimitry Andric CharUnits NullAlign = DestPtr.getAlignment();
2173519fc96cSDimitry Andric NullVariable->setAlignment(NullAlign.getAsAlign());
2174b1c73532SDimitry Andric Address SrcPtr(NullVariable, Builder.getInt8Ty(), NullAlign);
21753d1dcd9bSDimitry Andric
2176bca07a45SDimitry Andric if (vla) return emitNonZeroVLAInit(*this, Ty, DestPtr, SrcPtr, SizeVal);
21773d1dcd9bSDimitry Andric
21783d1dcd9bSDimitry Andric // Get and call the appropriate llvm.memcpy overload.
217945b53394SDimitry Andric Builder.CreateMemCpy(DestPtr, SrcPtr, SizeVal, false);
21803d1dcd9bSDimitry Andric return;
21813d1dcd9bSDimitry Andric }
21823d1dcd9bSDimitry Andric
21833d1dcd9bSDimitry Andric // Otherwise, just memset the whole thing to zero. This is legal
21843d1dcd9bSDimitry Andric // because in LLVM, all default initializers (other than the ones we just
21853d1dcd9bSDimitry Andric // handled above) are guaranteed to have a bit pattern of all zeros.
218645b53394SDimitry Andric Builder.CreateMemSet(DestPtr, Builder.getInt8(0), SizeVal, false);
2187ec2b103cSEd Schouten }
2188ec2b103cSEd Schouten
GetAddrOfLabel(const LabelDecl * L)2189bca07a45SDimitry Andric llvm::BlockAddress *CodeGenFunction::GetAddrOfLabel(const LabelDecl *L) {
219051fb8b01SRoman Divacky // Make sure that there is a block for the indirect goto.
21919f4dbff6SDimitry Andric if (!IndirectBranch)
219251fb8b01SRoman Divacky GetIndirectGotoBlock();
219351fb8b01SRoman Divacky
21943d1dcd9bSDimitry Andric llvm::BasicBlock *BB = getJumpDestForLabel(L).getBlock();
2195ec2b103cSEd Schouten
219651fb8b01SRoman Divacky // Make sure the indirect branch includes all of the address-taken blocks.
219751fb8b01SRoman Divacky IndirectBranch->addDestination(BB);
219851fb8b01SRoman Divacky return llvm::BlockAddress::get(CurFn, BB);
21994c8b2481SRoman Divacky }
22004c8b2481SRoman Divacky
GetIndirectGotoBlock()22014c8b2481SRoman Divacky llvm::BasicBlock *CodeGenFunction::GetIndirectGotoBlock() {
220251fb8b01SRoman Divacky // If we already made the indirect branch for indirect goto, return its block.
220351fb8b01SRoman Divacky if (IndirectBranch) return IndirectBranch->getParent();
22044c8b2481SRoman Divacky
220545b53394SDimitry Andric CGBuilderTy TmpBuilder(*this, createBasicBlock("indirectgoto"));
220651fb8b01SRoman Divacky
22074c8b2481SRoman Divacky // Create the PHI node that indirect gotos will add entries to.
220801af97d3SDimitry Andric llvm::Value *DestVal = TmpBuilder.CreatePHI(Int8PtrTy, 0,
220901af97d3SDimitry Andric "indirect.goto.dest");
22104c8b2481SRoman Divacky
221151fb8b01SRoman Divacky // Create the indirect branch instruction.
221251fb8b01SRoman Divacky IndirectBranch = TmpBuilder.CreateIndirectBr(DestVal);
221351fb8b01SRoman Divacky return IndirectBranch->getParent();
2214ec2b103cSEd Schouten }
2215ec2b103cSEd Schouten
2216180abc3dSDimitry Andric /// Computes the length of an array in elements, as well as the base
2217180abc3dSDimitry Andric /// element type and a properly-typed first element pointer.
emitArrayLength(const ArrayType * origArrayType,QualType & baseType,Address & addr)2218180abc3dSDimitry Andric llvm::Value *CodeGenFunction::emitArrayLength(const ArrayType *origArrayType,
2219180abc3dSDimitry Andric QualType &baseType,
222045b53394SDimitry Andric Address &addr) {
2221180abc3dSDimitry Andric const ArrayType *arrayType = origArrayType;
2222ec2b103cSEd Schouten
2223180abc3dSDimitry Andric // If it's a VLA, we have to load the stored size. Note that
2224180abc3dSDimitry Andric // this is the size of the VLA in bytes, not its size in elements.
22259f4dbff6SDimitry Andric llvm::Value *numVLAElements = nullptr;
2226180abc3dSDimitry Andric if (isa<VariableArrayType>(arrayType)) {
222748675466SDimitry Andric numVLAElements = getVLASize(cast<VariableArrayType>(arrayType)).NumElts;
2228180abc3dSDimitry Andric
2229180abc3dSDimitry Andric // Walk into all VLAs. This doesn't require changes to addr,
2230180abc3dSDimitry Andric // which has type T* where T is the first non-VLA element type.
2231180abc3dSDimitry Andric do {
2232180abc3dSDimitry Andric QualType elementType = arrayType->getElementType();
2233180abc3dSDimitry Andric arrayType = getContext().getAsArrayType(elementType);
2234180abc3dSDimitry Andric
2235180abc3dSDimitry Andric // If we only have VLA components, 'addr' requires no adjustment.
2236180abc3dSDimitry Andric if (!arrayType) {
2237180abc3dSDimitry Andric baseType = elementType;
2238180abc3dSDimitry Andric return numVLAElements;
2239180abc3dSDimitry Andric }
2240180abc3dSDimitry Andric } while (isa<VariableArrayType>(arrayType));
2241180abc3dSDimitry Andric
2242180abc3dSDimitry Andric // We get out here only if we find a constant array type
2243180abc3dSDimitry Andric // inside the VLA.
2244ec2b103cSEd Schouten }
2245ec2b103cSEd Schouten
2246180abc3dSDimitry Andric // We have some number of constant-length arrays, so addr should
2247180abc3dSDimitry Andric // have LLVM type [M x [N x [...]]]*. Build a GEP that walks
2248180abc3dSDimitry Andric // down to the first element of addr.
224936981b17SDimitry Andric SmallVector<llvm::Value*, 8> gepIndices;
2250180abc3dSDimitry Andric
2251180abc3dSDimitry Andric // GEP down to the array type.
2252180abc3dSDimitry Andric llvm::ConstantInt *zero = Builder.getInt32(0);
2253180abc3dSDimitry Andric gepIndices.push_back(zero);
2254180abc3dSDimitry Andric
2255180abc3dSDimitry Andric uint64_t countFromCLAs = 1;
225656d91b49SDimitry Andric QualType eltType;
2257180abc3dSDimitry Andric
225836981b17SDimitry Andric llvm::ArrayType *llvmArrayType =
225945b53394SDimitry Andric dyn_cast<llvm::ArrayType>(addr.getElementType());
226056d91b49SDimitry Andric while (llvmArrayType) {
2261180abc3dSDimitry Andric assert(isa<ConstantArrayType>(arrayType));
2262ac9a064cSDimitry Andric assert(cast<ConstantArrayType>(arrayType)->getZExtSize() ==
2263ac9a064cSDimitry Andric llvmArrayType->getNumElements());
2264180abc3dSDimitry Andric
2265180abc3dSDimitry Andric gepIndices.push_back(zero);
2266180abc3dSDimitry Andric countFromCLAs *= llvmArrayType->getNumElements();
226756d91b49SDimitry Andric eltType = arrayType->getElementType();
2268180abc3dSDimitry Andric
2269180abc3dSDimitry Andric llvmArrayType =
2270180abc3dSDimitry Andric dyn_cast<llvm::ArrayType>(llvmArrayType->getElementType());
2271180abc3dSDimitry Andric arrayType = getContext().getAsArrayType(arrayType->getElementType());
227256d91b49SDimitry Andric assert((!llvmArrayType || arrayType) &&
227356d91b49SDimitry Andric "LLVM and Clang types are out-of-synch");
2274180abc3dSDimitry Andric }
2275180abc3dSDimitry Andric
227656d91b49SDimitry Andric if (arrayType) {
227756d91b49SDimitry Andric // From this point onwards, the Clang array type has been emitted
227856d91b49SDimitry Andric // as some other type (probably a packed struct). Compute the array
227956d91b49SDimitry Andric // size, and just emit the 'begin' expression as a bitcast.
228056d91b49SDimitry Andric while (arrayType) {
2281ac9a064cSDimitry Andric countFromCLAs *= cast<ConstantArrayType>(arrayType)->getZExtSize();
228256d91b49SDimitry Andric eltType = arrayType->getElementType();
228356d91b49SDimitry Andric arrayType = getContext().getAsArrayType(eltType);
228456d91b49SDimitry Andric }
2285180abc3dSDimitry Andric
228645b53394SDimitry Andric llvm::Type *baseType = ConvertType(eltType);
22877fa27ce4SDimitry Andric addr = addr.withElementType(baseType);
228856d91b49SDimitry Andric } else {
2289180abc3dSDimitry Andric // Create the actual GEP.
2290ac9a064cSDimitry Andric addr = Address(Builder.CreateInBoundsGEP(addr.getElementType(),
2291ac9a064cSDimitry Andric addr.emitRawPointer(*this),
2292ac9a064cSDimitry Andric gepIndices, "array.begin"),
2293ac9a064cSDimitry Andric ConvertTypeForMem(eltType), addr.getAlignment());
229456d91b49SDimitry Andric }
229556d91b49SDimitry Andric
229656d91b49SDimitry Andric baseType = eltType;
2297180abc3dSDimitry Andric
2298180abc3dSDimitry Andric llvm::Value *numElements
2299180abc3dSDimitry Andric = llvm::ConstantInt::get(SizeTy, countFromCLAs);
2300180abc3dSDimitry Andric
2301180abc3dSDimitry Andric // If we had any VLA dimensions, factor them in.
2302180abc3dSDimitry Andric if (numVLAElements)
2303180abc3dSDimitry Andric numElements = Builder.CreateNUWMul(numVLAElements, numElements);
2304180abc3dSDimitry Andric
2305180abc3dSDimitry Andric return numElements;
2306180abc3dSDimitry Andric }
2307180abc3dSDimitry Andric
getVLASize(QualType type)230848675466SDimitry Andric CodeGenFunction::VlaSizePair CodeGenFunction::getVLASize(QualType type) {
2309180abc3dSDimitry Andric const VariableArrayType *vla = getContext().getAsVariableArrayType(type);
2310180abc3dSDimitry Andric assert(vla && "type was not a variable array type!");
2311180abc3dSDimitry Andric return getVLASize(vla);
2312180abc3dSDimitry Andric }
2313180abc3dSDimitry Andric
231448675466SDimitry Andric CodeGenFunction::VlaSizePair
getVLASize(const VariableArrayType * type)2315180abc3dSDimitry Andric CodeGenFunction::getVLASize(const VariableArrayType *type) {
2316180abc3dSDimitry Andric // The number of elements so far; always size_t.
23179f4dbff6SDimitry Andric llvm::Value *numElements = nullptr;
2318180abc3dSDimitry Andric
2319180abc3dSDimitry Andric QualType elementType;
2320180abc3dSDimitry Andric do {
2321180abc3dSDimitry Andric elementType = type->getElementType();
2322180abc3dSDimitry Andric llvm::Value *vlaSize = VLASizeMap[type->getSizeExpr()];
2323180abc3dSDimitry Andric assert(vlaSize && "no size for VLA!");
2324180abc3dSDimitry Andric assert(vlaSize->getType() == SizeTy);
2325180abc3dSDimitry Andric
2326180abc3dSDimitry Andric if (!numElements) {
2327180abc3dSDimitry Andric numElements = vlaSize;
2328180abc3dSDimitry Andric } else {
2329180abc3dSDimitry Andric // It's undefined behavior if this wraps around, so mark it that way.
23309f4dbff6SDimitry Andric // FIXME: Teach -fsanitize=undefined to trap this.
2331180abc3dSDimitry Andric numElements = Builder.CreateNUWMul(numElements, vlaSize);
2332180abc3dSDimitry Andric }
2333180abc3dSDimitry Andric } while ((type = getContext().getAsVariableArrayType(elementType)));
2334180abc3dSDimitry Andric
233548675466SDimitry Andric return { numElements, elementType };
233648675466SDimitry Andric }
233748675466SDimitry Andric
233848675466SDimitry Andric CodeGenFunction::VlaSizePair
getVLAElements1D(QualType type)233948675466SDimitry Andric CodeGenFunction::getVLAElements1D(QualType type) {
234048675466SDimitry Andric const VariableArrayType *vla = getContext().getAsVariableArrayType(type);
234148675466SDimitry Andric assert(vla && "type was not a variable array type!");
234248675466SDimitry Andric return getVLAElements1D(vla);
234348675466SDimitry Andric }
234448675466SDimitry Andric
234548675466SDimitry Andric CodeGenFunction::VlaSizePair
getVLAElements1D(const VariableArrayType * Vla)234648675466SDimitry Andric CodeGenFunction::getVLAElements1D(const VariableArrayType *Vla) {
234748675466SDimitry Andric llvm::Value *VlaSize = VLASizeMap[Vla->getSizeExpr()];
234848675466SDimitry Andric assert(VlaSize && "no size for VLA!");
234948675466SDimitry Andric assert(VlaSize->getType() == SizeTy);
235048675466SDimitry Andric return { VlaSize, Vla->getElementType() };
2351180abc3dSDimitry Andric }
2352180abc3dSDimitry Andric
EmitVariablyModifiedType(QualType type)2353180abc3dSDimitry Andric void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
2354180abc3dSDimitry Andric assert(type->isVariablyModifiedType() &&
2355ec2b103cSEd Schouten "Must pass variably modified type to EmitVLASizes!");
2356ec2b103cSEd Schouten
23574c8b2481SRoman Divacky EnsureInsertPoint();
23584c8b2481SRoman Divacky
2359180abc3dSDimitry Andric // We're going to walk down into the type and look for VLA
2360180abc3dSDimitry Andric // expressions.
2361180abc3dSDimitry Andric do {
2362180abc3dSDimitry Andric assert(type->isVariablyModifiedType());
2363ec2b103cSEd Schouten
2364180abc3dSDimitry Andric const Type *ty = type.getTypePtr();
2365180abc3dSDimitry Andric switch (ty->getTypeClass()) {
2366dbe13110SDimitry Andric
2367180abc3dSDimitry Andric #define TYPE(Class, Base)
2368180abc3dSDimitry Andric #define ABSTRACT_TYPE(Class, Base)
2369dbe13110SDimitry Andric #define NON_CANONICAL_TYPE(Class, Base)
2370180abc3dSDimitry Andric #define DEPENDENT_TYPE(Class, Base) case Type::Class:
2371dbe13110SDimitry Andric #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)
2372519fc96cSDimitry Andric #include "clang/AST/TypeNodes.inc"
2373dbe13110SDimitry Andric llvm_unreachable("unexpected dependent type!");
2374ec2b103cSEd Schouten
2375180abc3dSDimitry Andric // These types are never variably-modified.
2376180abc3dSDimitry Andric case Type::Builtin:
2377180abc3dSDimitry Andric case Type::Complex:
2378180abc3dSDimitry Andric case Type::Vector:
2379180abc3dSDimitry Andric case Type::ExtVector:
2380cfca06d7SDimitry Andric case Type::ConstantMatrix:
2381180abc3dSDimitry Andric case Type::Record:
2382180abc3dSDimitry Andric case Type::Enum:
238377fc4c14SDimitry Andric case Type::Using:
2384dbe13110SDimitry Andric case Type::TemplateSpecialization:
2385bab175ecSDimitry Andric case Type::ObjCTypeParam:
2386180abc3dSDimitry Andric case Type::ObjCObject:
2387180abc3dSDimitry Andric case Type::ObjCInterface:
2388180abc3dSDimitry Andric case Type::ObjCObjectPointer:
238977fc4c14SDimitry Andric case Type::BitInt:
2390180abc3dSDimitry Andric llvm_unreachable("type class is never variably-modified!");
2391ec2b103cSEd Schouten
2392e3b55780SDimitry Andric case Type::Elaborated:
2393e3b55780SDimitry Andric type = cast<ElaboratedType>(ty)->getNamedType();
2394e3b55780SDimitry Andric break;
2395e3b55780SDimitry Andric
23969f4dbff6SDimitry Andric case Type::Adjusted:
23979f4dbff6SDimitry Andric type = cast<AdjustedType>(ty)->getAdjustedType();
23989f4dbff6SDimitry Andric break;
23999f4dbff6SDimitry Andric
2400bfef3995SDimitry Andric case Type::Decayed:
2401bfef3995SDimitry Andric type = cast<DecayedType>(ty)->getPointeeType();
2402bfef3995SDimitry Andric break;
2403bfef3995SDimitry Andric
2404180abc3dSDimitry Andric case Type::Pointer:
2405180abc3dSDimitry Andric type = cast<PointerType>(ty)->getPointeeType();
2406180abc3dSDimitry Andric break;
2407ec2b103cSEd Schouten
2408180abc3dSDimitry Andric case Type::BlockPointer:
2409180abc3dSDimitry Andric type = cast<BlockPointerType>(ty)->getPointeeType();
2410180abc3dSDimitry Andric break;
2411180abc3dSDimitry Andric
2412180abc3dSDimitry Andric case Type::LValueReference:
2413180abc3dSDimitry Andric case Type::RValueReference:
2414180abc3dSDimitry Andric type = cast<ReferenceType>(ty)->getPointeeType();
2415180abc3dSDimitry Andric break;
2416180abc3dSDimitry Andric
2417180abc3dSDimitry Andric case Type::MemberPointer:
2418180abc3dSDimitry Andric type = cast<MemberPointerType>(ty)->getPointeeType();
2419180abc3dSDimitry Andric break;
2420180abc3dSDimitry Andric
2421ac9a064cSDimitry Andric case Type::ArrayParameter:
2422180abc3dSDimitry Andric case Type::ConstantArray:
2423180abc3dSDimitry Andric case Type::IncompleteArray:
2424180abc3dSDimitry Andric // Losing element qualification here is fine.
2425180abc3dSDimitry Andric type = cast<ArrayType>(ty)->getElementType();
2426180abc3dSDimitry Andric break;
2427180abc3dSDimitry Andric
2428180abc3dSDimitry Andric case Type::VariableArray: {
2429180abc3dSDimitry Andric // Losing element qualification here is fine.
2430180abc3dSDimitry Andric const VariableArrayType *vat = cast<VariableArrayType>(ty);
2431180abc3dSDimitry Andric
2432180abc3dSDimitry Andric // Unknown size indication requires no size computation.
2433180abc3dSDimitry Andric // Otherwise, evaluate and record it.
24346f8fc217SDimitry Andric if (const Expr *sizeExpr = vat->getSizeExpr()) {
2435180abc3dSDimitry Andric // It's possible that we might have emitted this already,
2436180abc3dSDimitry Andric // e.g. with a typedef and a pointer to it.
24376f8fc217SDimitry Andric llvm::Value *&entry = VLASizeMap[sizeExpr];
2438180abc3dSDimitry Andric if (!entry) {
24396f8fc217SDimitry Andric llvm::Value *size = EmitScalarExpr(sizeExpr);
244013cc256eSDimitry Andric
244113cc256eSDimitry Andric // C11 6.7.6.2p5:
244213cc256eSDimitry Andric // If the size is an expression that is not an integer constant
244313cc256eSDimitry Andric // expression [...] each time it is evaluated it shall have a value
244413cc256eSDimitry Andric // greater than zero.
24456f8fc217SDimitry Andric if (SanOpts.has(SanitizerKind::VLABound)) {
24469f4dbff6SDimitry Andric SanitizerScope SanScope(this);
24476f8fc217SDimitry Andric llvm::Value *Zero = llvm::Constant::getNullValue(size->getType());
24486f8fc217SDimitry Andric clang::QualType SEType = sizeExpr->getType();
24496f8fc217SDimitry Andric llvm::Value *CheckCondition =
24506f8fc217SDimitry Andric SEType->isSignedIntegerType()
24516f8fc217SDimitry Andric ? Builder.CreateICmpSGT(size, Zero)
24526f8fc217SDimitry Andric : Builder.CreateICmpUGT(size, Zero);
245313cc256eSDimitry Andric llvm::Constant *StaticArgs[] = {
24546f8fc217SDimitry Andric EmitCheckSourceLocation(sizeExpr->getBeginLoc()),
24556f8fc217SDimitry Andric EmitCheckTypeDescriptor(SEType)};
24566f8fc217SDimitry Andric EmitCheck(std::make_pair(CheckCondition, SanitizerKind::VLABound),
24576f8fc217SDimitry Andric SanitizerHandler::VLABoundNotPositive, StaticArgs, size);
245813cc256eSDimitry Andric }
245913cc256eSDimitry Andric
2460180abc3dSDimitry Andric // Always zexting here would be wrong if it weren't
2461180abc3dSDimitry Andric // undefined behavior to have a negative bound.
24626f8fc217SDimitry Andric // FIXME: What about when size's type is larger than size_t?
24636f8fc217SDimitry Andric entry = Builder.CreateIntCast(size, SizeTy, /*signed*/ false);
2464180abc3dSDimitry Andric }
2465180abc3dSDimitry Andric }
2466180abc3dSDimitry Andric type = vat->getElementType();
2467180abc3dSDimitry Andric break;
2468ec2b103cSEd Schouten }
2469ec2b103cSEd Schouten
2470180abc3dSDimitry Andric case Type::FunctionProto:
2471180abc3dSDimitry Andric case Type::FunctionNoProto:
24729f4dbff6SDimitry Andric type = cast<FunctionType>(ty)->getReturnType();
2473180abc3dSDimitry Andric break;
247436981b17SDimitry Andric
2475dbe13110SDimitry Andric case Type::Paren:
2476dbe13110SDimitry Andric case Type::TypeOf:
2477dbe13110SDimitry Andric case Type::UnaryTransform:
2478dbe13110SDimitry Andric case Type::Attributed:
2479145449b1SDimitry Andric case Type::BTFTagAttributed:
2480dbe13110SDimitry Andric case Type::SubstTemplateTypeParm:
248122989816SDimitry Andric case Type::MacroQualified:
2482ac9a064cSDimitry Andric case Type::CountAttributed:
2483dbe13110SDimitry Andric // Keep walking after single level desugaring.
2484dbe13110SDimitry Andric type = type.getSingleStepDesugaredType(getContext());
2485dbe13110SDimitry Andric break;
2486dbe13110SDimitry Andric
2487dbe13110SDimitry Andric case Type::Typedef:
2488dbe13110SDimitry Andric case Type::Decltype:
2489dbe13110SDimitry Andric case Type::Auto:
24907442d6faSDimitry Andric case Type::DeducedTemplateSpecialization:
2491ac9a064cSDimitry Andric case Type::PackIndexing:
2492dbe13110SDimitry Andric // Stop walking: nothing to do.
2493dbe13110SDimitry Andric return;
2494dbe13110SDimitry Andric
2495dbe13110SDimitry Andric case Type::TypeOfExpr:
2496dbe13110SDimitry Andric // Stop walking: emit typeof expression.
2497dbe13110SDimitry Andric EmitIgnoredExpr(cast<TypeOfExprType>(ty)->getUnderlyingExpr());
2498dbe13110SDimitry Andric return;
2499dbe13110SDimitry Andric
250036981b17SDimitry Andric case Type::Atomic:
250136981b17SDimitry Andric type = cast<AtomicType>(ty)->getValueType();
250236981b17SDimitry Andric break;
25030414e226SDimitry Andric
25040414e226SDimitry Andric case Type::Pipe:
25050414e226SDimitry Andric type = cast<PipeType>(ty)->getElementType();
25060414e226SDimitry Andric break;
2507ec2b103cSEd Schouten }
2508180abc3dSDimitry Andric } while (type->isVariablyModifiedType());
2509ec2b103cSEd Schouten }
2510ec2b103cSEd Schouten
EmitVAListRef(const Expr * E)251145b53394SDimitry Andric Address CodeGenFunction::EmitVAListRef(const Expr* E) {
2512bca07a45SDimitry Andric if (getContext().getBuiltinVaListType()->isArrayType())
251345b53394SDimitry Andric return EmitPointerWithAlignment(E);
2514ac9a064cSDimitry Andric return EmitLValue(E).getAddress();
251545b53394SDimitry Andric }
251645b53394SDimitry Andric
EmitMSVAListRef(const Expr * E)251745b53394SDimitry Andric Address CodeGenFunction::EmitMSVAListRef(const Expr *E) {
2518ac9a064cSDimitry Andric return EmitLValue(E).getAddress();
2519ec2b103cSEd Schouten }
2520ec2b103cSEd Schouten
EmitDeclRefExprDbgValue(const DeclRefExpr * E,const APValue & Init)25213d1dcd9bSDimitry Andric void CodeGenFunction::EmitDeclRefExprDbgValue(const DeclRefExpr *E,
2522bab175ecSDimitry Andric const APValue &Init) {
252322989816SDimitry Andric assert(Init.hasValue() && "Invalid DeclRefExpr initializer!");
25243d1dcd9bSDimitry Andric if (CGDebugInfo *Dbg = getDebugInfo())
2525706b4fc4SDimitry Andric if (CGM.getCodeGenOpts().hasReducedDebugInfo())
2526bca07a45SDimitry Andric Dbg->EmitGlobalVariable(E->getDecl(), Init);
2527bca07a45SDimitry Andric }
2528bca07a45SDimitry Andric
2529bca07a45SDimitry Andric CodeGenFunction::PeepholeProtection
protectFromPeepholes(RValue rvalue)2530bca07a45SDimitry Andric CodeGenFunction::protectFromPeepholes(RValue rvalue) {
2531bca07a45SDimitry Andric // At the moment, the only aggressive peephole we do in IR gen
2532bca07a45SDimitry Andric // is trunc(zext) folding, but if we add more, we can easily
2533bca07a45SDimitry Andric // extend this protection.
2534bca07a45SDimitry Andric
2535bca07a45SDimitry Andric if (!rvalue.isScalar()) return PeepholeProtection();
2536bca07a45SDimitry Andric llvm::Value *value = rvalue.getScalarVal();
2537bca07a45SDimitry Andric if (!isa<llvm::ZExtInst>(value)) return PeepholeProtection();
2538bca07a45SDimitry Andric
2539bca07a45SDimitry Andric // Just make an extra bitcast.
2540bca07a45SDimitry Andric assert(HaveInsertPoint());
2541bca07a45SDimitry Andric llvm::Instruction *inst = new llvm::BitCastInst(value, value->getType(), "",
2542bca07a45SDimitry Andric Builder.GetInsertBlock());
2543bca07a45SDimitry Andric
2544bca07a45SDimitry Andric PeepholeProtection protection;
2545bca07a45SDimitry Andric protection.Inst = inst;
2546bca07a45SDimitry Andric return protection;
2547bca07a45SDimitry Andric }
2548bca07a45SDimitry Andric
unprotectFromPeepholes(PeepholeProtection protection)2549bca07a45SDimitry Andric void CodeGenFunction::unprotectFromPeepholes(PeepholeProtection protection) {
2550bca07a45SDimitry Andric if (!protection.Inst) return;
2551bca07a45SDimitry Andric
2552bca07a45SDimitry Andric // In theory, we could try to duplicate the peepholes now, but whatever.
2553bca07a45SDimitry Andric protection.Inst->eraseFromParent();
25543d1dcd9bSDimitry Andric }
255536981b17SDimitry Andric
emitAlignmentAssumption(llvm::Value * PtrValue,QualType Ty,SourceLocation Loc,SourceLocation AssumptionLoc,llvm::Value * Alignment,llvm::Value * OffsetValue)2556cfca06d7SDimitry Andric void CodeGenFunction::emitAlignmentAssumption(llvm::Value *PtrValue,
2557676fbe81SDimitry Andric QualType Ty, SourceLocation Loc,
2558676fbe81SDimitry Andric SourceLocation AssumptionLoc,
2559676fbe81SDimitry Andric llvm::Value *Alignment,
2560676fbe81SDimitry Andric llvm::Value *OffsetValue) {
2561cfca06d7SDimitry Andric if (Alignment->getType() != IntPtrTy)
2562cfca06d7SDimitry Andric Alignment =
2563cfca06d7SDimitry Andric Builder.CreateIntCast(Alignment, IntPtrTy, false, "casted.align");
2564cfca06d7SDimitry Andric if (OffsetValue && OffsetValue->getType() != IntPtrTy)
2565cfca06d7SDimitry Andric OffsetValue =
2566cfca06d7SDimitry Andric Builder.CreateIntCast(OffsetValue, IntPtrTy, true, "casted.offset");
2567cfca06d7SDimitry Andric llvm::Value *TheCheck = nullptr;
2568676fbe81SDimitry Andric if (SanOpts.has(SanitizerKind::Alignment)) {
2569cfca06d7SDimitry Andric llvm::Value *PtrIntValue =
2570cfca06d7SDimitry Andric Builder.CreatePtrToInt(PtrValue, IntPtrTy, "ptrint");
2571cfca06d7SDimitry Andric
2572cfca06d7SDimitry Andric if (OffsetValue) {
2573cfca06d7SDimitry Andric bool IsOffsetZero = false;
2574cfca06d7SDimitry Andric if (const auto *CI = dyn_cast<llvm::ConstantInt>(OffsetValue))
2575cfca06d7SDimitry Andric IsOffsetZero = CI->isZero();
2576cfca06d7SDimitry Andric
2577cfca06d7SDimitry Andric if (!IsOffsetZero)
2578cfca06d7SDimitry Andric PtrIntValue = Builder.CreateSub(PtrIntValue, OffsetValue, "offsetptr");
2579676fbe81SDimitry Andric }
2580676fbe81SDimitry Andric
2581cfca06d7SDimitry Andric llvm::Value *Zero = llvm::ConstantInt::get(IntPtrTy, 0);
2582cfca06d7SDimitry Andric llvm::Value *Mask =
2583cfca06d7SDimitry Andric Builder.CreateSub(Alignment, llvm::ConstantInt::get(IntPtrTy, 1));
2584cfca06d7SDimitry Andric llvm::Value *MaskedPtr = Builder.CreateAnd(PtrIntValue, Mask, "maskedptr");
2585cfca06d7SDimitry Andric TheCheck = Builder.CreateICmpEQ(MaskedPtr, Zero, "maskcond");
2586cfca06d7SDimitry Andric }
2587cfca06d7SDimitry Andric llvm::Instruction *Assumption = Builder.CreateAlignmentAssumption(
2588cfca06d7SDimitry Andric CGM.getDataLayout(), PtrValue, Alignment, OffsetValue);
2589cfca06d7SDimitry Andric
2590cfca06d7SDimitry Andric if (!SanOpts.has(SanitizerKind::Alignment))
2591cfca06d7SDimitry Andric return;
2592cfca06d7SDimitry Andric emitAlignmentAssumptionCheck(PtrValue, Ty, Loc, AssumptionLoc, Alignment,
2593cfca06d7SDimitry Andric OffsetValue, TheCheck, Assumption);
2594cfca06d7SDimitry Andric }
2595cfca06d7SDimitry Andric
emitAlignmentAssumption(llvm::Value * PtrValue,const Expr * E,SourceLocation AssumptionLoc,llvm::Value * Alignment,llvm::Value * OffsetValue)2596cfca06d7SDimitry Andric void CodeGenFunction::emitAlignmentAssumption(llvm::Value *PtrValue,
2597676fbe81SDimitry Andric const Expr *E,
2598676fbe81SDimitry Andric SourceLocation AssumptionLoc,
2599519fc96cSDimitry Andric llvm::Value *Alignment,
2600676fbe81SDimitry Andric llvm::Value *OffsetValue) {
2601676fbe81SDimitry Andric QualType Ty = E->getType();
2602676fbe81SDimitry Andric SourceLocation Loc = E->getExprLoc();
2603676fbe81SDimitry Andric
2604cfca06d7SDimitry Andric emitAlignmentAssumption(PtrValue, Ty, Loc, AssumptionLoc, Alignment,
2605676fbe81SDimitry Andric OffsetValue);
2606676fbe81SDimitry Andric }
2607676fbe81SDimitry Andric
EmitAnnotationCall(llvm::Function * AnnotationFn,llvm::Value * AnnotatedVal,StringRef AnnotationStr,SourceLocation Location,const AnnotateAttr * Attr)260822989816SDimitry Andric llvm::Value *CodeGenFunction::EmitAnnotationCall(llvm::Function *AnnotationFn,
260936981b17SDimitry Andric llvm::Value *AnnotatedVal,
2610809500fcSDimitry Andric StringRef AnnotationStr,
2611b60736ecSDimitry Andric SourceLocation Location,
2612b60736ecSDimitry Andric const AnnotateAttr *Attr) {
2613b60736ecSDimitry Andric SmallVector<llvm::Value *, 5> Args = {
261436981b17SDimitry Andric AnnotatedVal,
2615b1c73532SDimitry Andric CGM.EmitAnnotationString(AnnotationStr),
2616b1c73532SDimitry Andric CGM.EmitAnnotationUnit(Location),
2617b60736ecSDimitry Andric CGM.EmitAnnotationLineNo(Location),
261836981b17SDimitry Andric };
2619b60736ecSDimitry Andric if (Attr)
2620b60736ecSDimitry Andric Args.push_back(CGM.EmitAnnotationArgs(Attr));
262136981b17SDimitry Andric return Builder.CreateCall(AnnotationFn, Args);
262236981b17SDimitry Andric }
262336981b17SDimitry Andric
EmitVarAnnotations(const VarDecl * D,llvm::Value * V)262436981b17SDimitry Andric void CodeGenFunction::EmitVarAnnotations(const VarDecl *D, llvm::Value *V) {
262536981b17SDimitry Andric assert(D->hasAttr<AnnotateAttr>() && "no annotate attribute");
26269f4dbff6SDimitry Andric for (const auto *I : D->specific_attrs<AnnotateAttr>())
2627e3b55780SDimitry Andric EmitAnnotationCall(CGM.getIntrinsic(llvm::Intrinsic::var_annotation,
2628b1c73532SDimitry Andric {V->getType(), CGM.ConstGlobalsPtrTy}),
2629b1c73532SDimitry Andric V, I->getAnnotation(), D->getLocation(), I);
263036981b17SDimitry Andric }
263136981b17SDimitry Andric
EmitFieldAnnotations(const FieldDecl * D,Address Addr)263245b53394SDimitry Andric Address CodeGenFunction::EmitFieldAnnotations(const FieldDecl *D,
263345b53394SDimitry Andric Address Addr) {
263436981b17SDimitry Andric assert(D->hasAttr<AnnotateAttr>() && "no annotate attribute");
2635ac9a064cSDimitry Andric llvm::Value *V = Addr.emitRawPointer(*this);
263636981b17SDimitry Andric llvm::Type *VTy = V->getType();
2637c0981da4SDimitry Andric auto *PTy = dyn_cast<llvm::PointerType>(VTy);
2638c0981da4SDimitry Andric unsigned AS = PTy ? PTy->getAddressSpace() : 0;
2639c0981da4SDimitry Andric llvm::PointerType *IntrinTy =
26407fa27ce4SDimitry Andric llvm::PointerType::get(CGM.getLLVMContext(), AS);
2641e3b55780SDimitry Andric llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::ptr_annotation,
2642e3b55780SDimitry Andric {IntrinTy, CGM.ConstGlobalsPtrTy});
264336981b17SDimitry Andric
26449f4dbff6SDimitry Andric for (const auto *I : D->specific_attrs<AnnotateAttr>()) {
264536981b17SDimitry Andric // FIXME Always emit the cast inst so we can differentiate between
264636981b17SDimitry Andric // annotation on the first field of a struct and annotation on the struct
264736981b17SDimitry Andric // itself.
2648c0981da4SDimitry Andric if (VTy != IntrinTy)
2649c0981da4SDimitry Andric V = Builder.CreateBitCast(V, IntrinTy);
2650b60736ecSDimitry Andric V = EmitAnnotationCall(F, V, I->getAnnotation(), D->getLocation(), I);
265136981b17SDimitry Andric V = Builder.CreateBitCast(V, VTy);
265236981b17SDimitry Andric }
265336981b17SDimitry Andric
2654145449b1SDimitry Andric return Address(V, Addr.getElementType(), Addr.getAlignment());
265536981b17SDimitry Andric }
2656bfef3995SDimitry Andric
~CGCapturedStmtInfo()2657bfef3995SDimitry Andric CodeGenFunction::CGCapturedStmtInfo::~CGCapturedStmtInfo() { }
26589f4dbff6SDimitry Andric
SanitizerScope(CodeGenFunction * CGF)26599f4dbff6SDimitry Andric CodeGenFunction::SanitizerScope::SanitizerScope(CodeGenFunction *CGF)
26609f4dbff6SDimitry Andric : CGF(CGF) {
26619f4dbff6SDimitry Andric assert(!CGF->IsSanitizerScope);
26629f4dbff6SDimitry Andric CGF->IsSanitizerScope = true;
26639f4dbff6SDimitry Andric }
26649f4dbff6SDimitry Andric
~SanitizerScope()26659f4dbff6SDimitry Andric CodeGenFunction::SanitizerScope::~SanitizerScope() {
26669f4dbff6SDimitry Andric CGF->IsSanitizerScope = false;
26679f4dbff6SDimitry Andric }
26689f4dbff6SDimitry Andric
InsertHelper(llvm::Instruction * I,const llvm::Twine & Name,llvm::BasicBlock::iterator InsertPt) const26699f4dbff6SDimitry Andric void CodeGenFunction::InsertHelper(llvm::Instruction *I,
26709f4dbff6SDimitry Andric const llvm::Twine &Name,
26719f4dbff6SDimitry Andric llvm::BasicBlock::iterator InsertPt) const {
26729f4dbff6SDimitry Andric LoopStack.InsertHelper(I);
267306d4ba38SDimitry Andric if (IsSanitizerScope)
26747fa27ce4SDimitry Andric I->setNoSanitizeMetadata();
26759f4dbff6SDimitry Andric }
26769f4dbff6SDimitry Andric
InsertHelper(llvm::Instruction * I,const llvm::Twine & Name,llvm::BasicBlock::iterator InsertPt) const26772b6b257fSDimitry Andric void CGBuilderInserter::InsertHelper(
2678ac9a064cSDimitry Andric llvm::Instruction *I, const llvm::Twine &Name,
26799f4dbff6SDimitry Andric llvm::BasicBlock::iterator InsertPt) const {
2680ac9a064cSDimitry Andric llvm::IRBuilderDefaultInserter::InsertHelper(I, Name, InsertPt);
26819f4dbff6SDimitry Andric if (CGF)
2682ac9a064cSDimitry Andric CGF->InsertHelper(I, Name, InsertPt);
26839f4dbff6SDimitry Andric }
26849f4dbff6SDimitry Andric
268545b53394SDimitry Andric // Emits an error if we don't have a valid set of target features for the
268645b53394SDimitry Andric // called function.
checkTargetFeatures(const CallExpr * E,const FunctionDecl * TargetDecl)268745b53394SDimitry Andric void CodeGenFunction::checkTargetFeatures(const CallExpr *E,
268845b53394SDimitry Andric const FunctionDecl *TargetDecl) {
2689ac9a064cSDimitry Andric // SemaChecking cannot handle below x86 builtins because they have different
2690ac9a064cSDimitry Andric // parameter ranges with different TargetAttribute of caller.
2691ac9a064cSDimitry Andric if (CGM.getContext().getTargetInfo().getTriple().isX86()) {
2692ac9a064cSDimitry Andric unsigned BuiltinID = TargetDecl->getBuiltinID();
2693ac9a064cSDimitry Andric if (BuiltinID == X86::BI__builtin_ia32_cmpps ||
2694ac9a064cSDimitry Andric BuiltinID == X86::BI__builtin_ia32_cmpss ||
2695ac9a064cSDimitry Andric BuiltinID == X86::BI__builtin_ia32_cmppd ||
2696ac9a064cSDimitry Andric BuiltinID == X86::BI__builtin_ia32_cmpsd) {
2697ac9a064cSDimitry Andric const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurCodeDecl);
2698ac9a064cSDimitry Andric llvm::StringMap<bool> TargetFetureMap;
2699ac9a064cSDimitry Andric CGM.getContext().getFunctionFeatureMap(TargetFetureMap, FD);
2700ac9a064cSDimitry Andric llvm::APSInt Result =
2701ac9a064cSDimitry Andric *(E->getArg(2)->getIntegerConstantExpr(CGM.getContext()));
2702ac9a064cSDimitry Andric if (Result.getSExtValue() > 7 && !TargetFetureMap.lookup("avx"))
2703ac9a064cSDimitry Andric CGM.getDiags().Report(E->getBeginLoc(), diag::err_builtin_needs_feature)
2704ac9a064cSDimitry Andric << TargetDecl->getDeclName() << "avx";
2705ac9a064cSDimitry Andric }
2706ac9a064cSDimitry Andric }
270722989816SDimitry Andric return checkTargetFeatures(E->getBeginLoc(), TargetDecl);
270822989816SDimitry Andric }
270922989816SDimitry Andric
271022989816SDimitry Andric // Emits an error if we don't have a valid set of target features for the
271122989816SDimitry Andric // called function.
checkTargetFeatures(SourceLocation Loc,const FunctionDecl * TargetDecl)271222989816SDimitry Andric void CodeGenFunction::checkTargetFeatures(SourceLocation Loc,
271322989816SDimitry Andric const FunctionDecl *TargetDecl) {
271445b53394SDimitry Andric // Early exit if this is an indirect call.
271545b53394SDimitry Andric if (!TargetDecl)
271645b53394SDimitry Andric return;
271745b53394SDimitry Andric
271845b53394SDimitry Andric // Get the current enclosing function if it exists. If it doesn't
271945b53394SDimitry Andric // we can't check the target features anyhow.
2720519fc96cSDimitry Andric const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurCodeDecl);
272145b53394SDimitry Andric if (!FD)
272245b53394SDimitry Andric return;
272345b53394SDimitry Andric
272445b53394SDimitry Andric // Grab the required features for the call. For a builtin this is listed in
272545b53394SDimitry Andric // the td file with the default cpu, for an always_inline function this is any
272645b53394SDimitry Andric // listed cpu and any listed features.
272745b53394SDimitry Andric unsigned BuiltinID = TargetDecl->getBuiltinID();
272845b53394SDimitry Andric std::string MissingFeature;
2729b60736ecSDimitry Andric llvm::StringMap<bool> CallerFeatureMap;
2730b60736ecSDimitry Andric CGM.getContext().getFunctionFeatureMap(CallerFeatureMap, FD);
2731b1c73532SDimitry Andric // When compiling in HipStdPar mode we have to be conservative in rejecting
2732b1c73532SDimitry Andric // target specific features in the FE, and defer the possible error to the
2733b1c73532SDimitry Andric // AcceleratorCodeSelection pass, wherein iff an unsupported target builtin is
2734b1c73532SDimitry Andric // referenced by an accelerator executable function, we emit an error.
2735b1c73532SDimitry Andric bool IsHipStdPar = getLangOpts().HIPStdPar && getLangOpts().CUDAIsDevice;
273645b53394SDimitry Andric if (BuiltinID) {
2737145449b1SDimitry Andric StringRef FeatureList(CGM.getContext().BuiltinInfo.getRequiredFeatures(BuiltinID));
2738145449b1SDimitry Andric if (!Builtin::evaluateRequiredTargetFeatures(
2739b1c73532SDimitry Andric FeatureList, CallerFeatureMap) && !IsHipStdPar) {
274022989816SDimitry Andric CGM.getDiags().Report(Loc, diag::err_builtin_needs_feature)
2741145449b1SDimitry Andric << TargetDecl->getDeclName()
2742145449b1SDimitry Andric << FeatureList;
2743145449b1SDimitry Andric }
2744706b4fc4SDimitry Andric } else if (!TargetDecl->isMultiVersion() &&
2745706b4fc4SDimitry Andric TargetDecl->hasAttr<TargetAttr>()) {
274645b53394SDimitry Andric // Get the required features for the callee.
274748675466SDimitry Andric
274848675466SDimitry Andric const TargetAttr *TD = TargetDecl->getAttr<TargetAttr>();
2749706b4fc4SDimitry Andric ParsedTargetAttr ParsedAttr =
2750706b4fc4SDimitry Andric CGM.getContext().filterFunctionTargetAttrs(TD);
275148675466SDimitry Andric
275245b53394SDimitry Andric SmallVector<StringRef, 1> ReqFeatures;
275345b53394SDimitry Andric llvm::StringMap<bool> CalleeFeatureMap;
2754cfca06d7SDimitry Andric CGM.getContext().getFunctionFeatureMap(CalleeFeatureMap, TargetDecl);
275548675466SDimitry Andric
275648675466SDimitry Andric for (const auto &F : ParsedAttr.Features) {
275748675466SDimitry Andric if (F[0] == '+' && CalleeFeatureMap.lookup(F.substr(1)))
275848675466SDimitry Andric ReqFeatures.push_back(StringRef(F).substr(1));
275948675466SDimitry Andric }
276048675466SDimitry Andric
276145b53394SDimitry Andric for (const auto &F : CalleeFeatureMap) {
276245b53394SDimitry Andric // Only positive features are "required".
276345b53394SDimitry Andric if (F.getValue())
276445b53394SDimitry Andric ReqFeatures.push_back(F.getKey());
276545b53394SDimitry Andric }
2766b60736ecSDimitry Andric if (!llvm::all_of(ReqFeatures, [&](StringRef Feature) {
2767b60736ecSDimitry Andric if (!CallerFeatureMap.lookup(Feature)) {
2768b60736ecSDimitry Andric MissingFeature = Feature.str();
2769b60736ecSDimitry Andric return false;
2770b60736ecSDimitry Andric }
2771b60736ecSDimitry Andric return true;
2772b1c73532SDimitry Andric }) && !IsHipStdPar)
277322989816SDimitry Andric CGM.getDiags().Report(Loc, diag::err_function_needs_feature)
277445b53394SDimitry Andric << FD->getDeclName() << TargetDecl->getDeclName() << MissingFeature;
27757fa27ce4SDimitry Andric } else if (!FD->isMultiVersion() && FD->hasAttr<TargetAttr>()) {
27767fa27ce4SDimitry Andric llvm::StringMap<bool> CalleeFeatureMap;
27777fa27ce4SDimitry Andric CGM.getContext().getFunctionFeatureMap(CalleeFeatureMap, TargetDecl);
27787fa27ce4SDimitry Andric
27797fa27ce4SDimitry Andric for (const auto &F : CalleeFeatureMap) {
27807fa27ce4SDimitry Andric if (F.getValue() && (!CallerFeatureMap.lookup(F.getKey()) ||
2781b1c73532SDimitry Andric !CallerFeatureMap.find(F.getKey())->getValue()) &&
2782b1c73532SDimitry Andric !IsHipStdPar)
27837fa27ce4SDimitry Andric CGM.getDiags().Report(Loc, diag::err_function_needs_feature)
27847fa27ce4SDimitry Andric << FD->getDeclName() << TargetDecl->getDeclName() << F.getKey();
27857fa27ce4SDimitry Andric }
278645b53394SDimitry Andric }
278745b53394SDimitry Andric }
27882b6b257fSDimitry Andric
EmitSanitizerStatReport(llvm::SanitizerStatKind SSK)27892b6b257fSDimitry Andric void CodeGenFunction::EmitSanitizerStatReport(llvm::SanitizerStatKind SSK) {
27902b6b257fSDimitry Andric if (!CGM.getCodeGenOpts().SanitizeStats)
27912b6b257fSDimitry Andric return;
27922b6b257fSDimitry Andric
27932b6b257fSDimitry Andric llvm::IRBuilder<> IRB(Builder.GetInsertBlock(), Builder.GetInsertPoint());
27942b6b257fSDimitry Andric IRB.SetCurrentDebugLocation(Builder.getCurrentDebugLocation());
27952b6b257fSDimitry Andric CGM.getSanStats().create(IRB, SSK);
27962b6b257fSDimitry Andric }
2797bab175ecSDimitry Andric
EmitKCFIOperandBundle(const CGCallee & Callee,SmallVectorImpl<llvm::OperandBundleDef> & Bundles)2798e3b55780SDimitry Andric void CodeGenFunction::EmitKCFIOperandBundle(
2799e3b55780SDimitry Andric const CGCallee &Callee, SmallVectorImpl<llvm::OperandBundleDef> &Bundles) {
2800e3b55780SDimitry Andric const FunctionProtoType *FP =
2801e3b55780SDimitry Andric Callee.getAbstractInfo().getCalleeFunctionProtoType();
2802e3b55780SDimitry Andric if (FP)
2803e3b55780SDimitry Andric Bundles.emplace_back("kcfi", CGM.CreateKCFITypeId(FP->desugar()));
2804e3b55780SDimitry Andric }
2805e3b55780SDimitry Andric
FormAArch64ResolverCondition(const MultiVersionResolverOption & RO)2806e3b55780SDimitry Andric llvm::Value *CodeGenFunction::FormAArch64ResolverCondition(
2807e3b55780SDimitry Andric const MultiVersionResolverOption &RO) {
2808e3b55780SDimitry Andric llvm::SmallVector<StringRef, 8> CondFeatures;
2809ac9a064cSDimitry Andric for (const StringRef &Feature : RO.Conditions.Features)
2810e3b55780SDimitry Andric CondFeatures.push_back(Feature);
2811e3b55780SDimitry Andric if (!CondFeatures.empty()) {
2812e3b55780SDimitry Andric return EmitAArch64CpuSupports(CondFeatures);
2813e3b55780SDimitry Andric }
2814e3b55780SDimitry Andric return nullptr;
2815e3b55780SDimitry Andric }
2816e3b55780SDimitry Andric
FormX86ResolverCondition(const MultiVersionResolverOption & RO)2817e3b55780SDimitry Andric llvm::Value *CodeGenFunction::FormX86ResolverCondition(
2818e3b55780SDimitry Andric const MultiVersionResolverOption &RO) {
2819676fbe81SDimitry Andric llvm::Value *Condition = nullptr;
282048675466SDimitry Andric
2821b1c73532SDimitry Andric if (!RO.Conditions.Architecture.empty()) {
2822b1c73532SDimitry Andric StringRef Arch = RO.Conditions.Architecture;
2823b1c73532SDimitry Andric // If arch= specifies an x86-64 micro-architecture level, test the feature
2824b1c73532SDimitry Andric // with __builtin_cpu_supports, otherwise use __builtin_cpu_is.
2825b1c73532SDimitry Andric if (Arch.starts_with("x86-64"))
2826b1c73532SDimitry Andric Condition = EmitX86CpuSupports({Arch});
2827b1c73532SDimitry Andric else
2828b1c73532SDimitry Andric Condition = EmitX86CpuIs(Arch);
2829b1c73532SDimitry Andric }
2830676fbe81SDimitry Andric
2831676fbe81SDimitry Andric if (!RO.Conditions.Features.empty()) {
2832676fbe81SDimitry Andric llvm::Value *FeatureCond = EmitX86CpuSupports(RO.Conditions.Features);
2833676fbe81SDimitry Andric Condition =
2834676fbe81SDimitry Andric Condition ? Builder.CreateAnd(Condition, FeatureCond) : FeatureCond;
283548675466SDimitry Andric }
2836676fbe81SDimitry Andric return Condition;
283748675466SDimitry Andric }
283848675466SDimitry Andric
CreateMultiVersionResolverReturn(CodeGenModule & CGM,llvm::Function * Resolver,CGBuilderTy & Builder,llvm::Function * FuncToReturn,bool SupportsIFunc)2839676fbe81SDimitry Andric static void CreateMultiVersionResolverReturn(CodeGenModule &CGM,
284048675466SDimitry Andric llvm::Function *Resolver,
2841676fbe81SDimitry Andric CGBuilderTy &Builder,
2842676fbe81SDimitry Andric llvm::Function *FuncToReturn,
2843676fbe81SDimitry Andric bool SupportsIFunc) {
2844676fbe81SDimitry Andric if (SupportsIFunc) {
2845676fbe81SDimitry Andric Builder.CreateRet(FuncToReturn);
2846676fbe81SDimitry Andric return;
2847676fbe81SDimitry Andric }
2848676fbe81SDimitry Andric
2849145449b1SDimitry Andric llvm::SmallVector<llvm::Value *, 10> Args(
2850145449b1SDimitry Andric llvm::make_pointer_range(Resolver->args()));
2851676fbe81SDimitry Andric
2852676fbe81SDimitry Andric llvm::CallInst *Result = Builder.CreateCall(FuncToReturn, Args);
2853676fbe81SDimitry Andric Result->setTailCallKind(llvm::CallInst::TCK_MustTail);
2854676fbe81SDimitry Andric
2855676fbe81SDimitry Andric if (Resolver->getReturnType()->isVoidTy())
2856676fbe81SDimitry Andric Builder.CreateRetVoid();
2857676fbe81SDimitry Andric else
2858676fbe81SDimitry Andric Builder.CreateRet(Result);
2859676fbe81SDimitry Andric }
2860676fbe81SDimitry Andric
EmitMultiVersionResolver(llvm::Function * Resolver,ArrayRef<MultiVersionResolverOption> Options)2861676fbe81SDimitry Andric void CodeGenFunction::EmitMultiVersionResolver(
2862676fbe81SDimitry Andric llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) {
2863e3b55780SDimitry Andric
2864e3b55780SDimitry Andric llvm::Triple::ArchType ArchType =
2865e3b55780SDimitry Andric getContext().getTargetInfo().getTriple().getArch();
2866e3b55780SDimitry Andric
2867e3b55780SDimitry Andric switch (ArchType) {
2868e3b55780SDimitry Andric case llvm::Triple::x86:
2869e3b55780SDimitry Andric case llvm::Triple::x86_64:
2870e3b55780SDimitry Andric EmitX86MultiVersionResolver(Resolver, Options);
2871e3b55780SDimitry Andric return;
2872e3b55780SDimitry Andric case llvm::Triple::aarch64:
2873e3b55780SDimitry Andric EmitAArch64MultiVersionResolver(Resolver, Options);
2874e3b55780SDimitry Andric return;
2875e3b55780SDimitry Andric
2876e3b55780SDimitry Andric default:
2877e3b55780SDimitry Andric assert(false && "Only implemented for x86 and AArch64 targets");
2878e3b55780SDimitry Andric }
2879e3b55780SDimitry Andric }
2880e3b55780SDimitry Andric
EmitAArch64MultiVersionResolver(llvm::Function * Resolver,ArrayRef<MultiVersionResolverOption> Options)2881e3b55780SDimitry Andric void CodeGenFunction::EmitAArch64MultiVersionResolver(
2882e3b55780SDimitry Andric llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) {
2883e3b55780SDimitry Andric assert(!Options.empty() && "No multiversion resolver options found");
2884e3b55780SDimitry Andric assert(Options.back().Conditions.Features.size() == 0 &&
2885e3b55780SDimitry Andric "Default case must be last");
2886e3b55780SDimitry Andric bool SupportsIFunc = getContext().getTargetInfo().supportsIFunc();
2887e3b55780SDimitry Andric assert(SupportsIFunc &&
2888e3b55780SDimitry Andric "Multiversion resolver requires target IFUNC support");
2889e3b55780SDimitry Andric bool AArch64CpuInitialized = false;
2890e3b55780SDimitry Andric llvm::BasicBlock *CurBlock = createBasicBlock("resolver_entry", Resolver);
2891e3b55780SDimitry Andric
2892e3b55780SDimitry Andric for (const MultiVersionResolverOption &RO : Options) {
2893e3b55780SDimitry Andric Builder.SetInsertPoint(CurBlock);
2894e3b55780SDimitry Andric llvm::Value *Condition = FormAArch64ResolverCondition(RO);
2895e3b55780SDimitry Andric
2896e3b55780SDimitry Andric // The 'default' or 'all features enabled' case.
2897e3b55780SDimitry Andric if (!Condition) {
2898e3b55780SDimitry Andric CreateMultiVersionResolverReturn(CGM, Resolver, Builder, RO.Function,
2899e3b55780SDimitry Andric SupportsIFunc);
2900e3b55780SDimitry Andric return;
2901e3b55780SDimitry Andric }
2902e3b55780SDimitry Andric
2903e3b55780SDimitry Andric if (!AArch64CpuInitialized) {
2904e3b55780SDimitry Andric Builder.SetInsertPoint(CurBlock, CurBlock->begin());
2905e3b55780SDimitry Andric EmitAArch64CpuInit();
2906e3b55780SDimitry Andric AArch64CpuInitialized = true;
2907e3b55780SDimitry Andric Builder.SetInsertPoint(CurBlock);
2908e3b55780SDimitry Andric }
2909e3b55780SDimitry Andric
2910e3b55780SDimitry Andric llvm::BasicBlock *RetBlock = createBasicBlock("resolver_return", Resolver);
2911e3b55780SDimitry Andric CGBuilderTy RetBuilder(*this, RetBlock);
2912e3b55780SDimitry Andric CreateMultiVersionResolverReturn(CGM, Resolver, RetBuilder, RO.Function,
2913e3b55780SDimitry Andric SupportsIFunc);
2914e3b55780SDimitry Andric CurBlock = createBasicBlock("resolver_else", Resolver);
2915e3b55780SDimitry Andric Builder.CreateCondBr(Condition, RetBlock, CurBlock);
2916e3b55780SDimitry Andric }
2917e3b55780SDimitry Andric
2918e3b55780SDimitry Andric // If no default, emit an unreachable.
2919e3b55780SDimitry Andric Builder.SetInsertPoint(CurBlock);
2920e3b55780SDimitry Andric llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap);
2921e3b55780SDimitry Andric TrapCall->setDoesNotReturn();
2922e3b55780SDimitry Andric TrapCall->setDoesNotThrow();
2923e3b55780SDimitry Andric Builder.CreateUnreachable();
2924e3b55780SDimitry Andric Builder.ClearInsertionPoint();
2925e3b55780SDimitry Andric }
2926e3b55780SDimitry Andric
EmitX86MultiVersionResolver(llvm::Function * Resolver,ArrayRef<MultiVersionResolverOption> Options)2927e3b55780SDimitry Andric void CodeGenFunction::EmitX86MultiVersionResolver(
2928e3b55780SDimitry Andric llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) {
292948675466SDimitry Andric
2930676fbe81SDimitry Andric bool SupportsIFunc = getContext().getTargetInfo().supportsIFunc();
293148675466SDimitry Andric
293248675466SDimitry Andric // Main function's basic block.
293348675466SDimitry Andric llvm::BasicBlock *CurBlock = createBasicBlock("resolver_entry", Resolver);
293448675466SDimitry Andric Builder.SetInsertPoint(CurBlock);
293548675466SDimitry Andric EmitX86CpuInit();
293648675466SDimitry Andric
2937676fbe81SDimitry Andric for (const MultiVersionResolverOption &RO : Options) {
293848675466SDimitry Andric Builder.SetInsertPoint(CurBlock);
2939e3b55780SDimitry Andric llvm::Value *Condition = FormX86ResolverCondition(RO);
294048675466SDimitry Andric
2941676fbe81SDimitry Andric // The 'default' or 'generic' case.
2942676fbe81SDimitry Andric if (!Condition) {
2943676fbe81SDimitry Andric assert(&RO == Options.end() - 1 &&
2944676fbe81SDimitry Andric "Default or Generic case must be last");
2945676fbe81SDimitry Andric CreateMultiVersionResolverReturn(CGM, Resolver, Builder, RO.Function,
2946676fbe81SDimitry Andric SupportsIFunc);
294748675466SDimitry Andric return;
294848675466SDimitry Andric }
2949676fbe81SDimitry Andric
295048675466SDimitry Andric llvm::BasicBlock *RetBlock = createBasicBlock("resolver_return", Resolver);
2951676fbe81SDimitry Andric CGBuilderTy RetBuilder(*this, RetBlock);
2952676fbe81SDimitry Andric CreateMultiVersionResolverReturn(CGM, Resolver, RetBuilder, RO.Function,
2953676fbe81SDimitry Andric SupportsIFunc);
295448675466SDimitry Andric CurBlock = createBasicBlock("resolver_else", Resolver);
2955676fbe81SDimitry Andric Builder.CreateCondBr(Condition, RetBlock, CurBlock);
295648675466SDimitry Andric }
295748675466SDimitry Andric
2958676fbe81SDimitry Andric // If no generic/default, emit an unreachable.
295948675466SDimitry Andric Builder.SetInsertPoint(CurBlock);
296048675466SDimitry Andric llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap);
296148675466SDimitry Andric TrapCall->setDoesNotReturn();
296248675466SDimitry Andric TrapCall->setDoesNotThrow();
296348675466SDimitry Andric Builder.CreateUnreachable();
296448675466SDimitry Andric Builder.ClearInsertionPoint();
296548675466SDimitry Andric }
296648675466SDimitry Andric
2967676fbe81SDimitry Andric // Loc - where the diagnostic will point, where in the source code this
2968676fbe81SDimitry Andric // alignment has failed.
2969676fbe81SDimitry Andric // SecondaryLoc - if present (will be present if sufficiently different from
2970676fbe81SDimitry Andric // Loc), the diagnostic will additionally point a "Note:" to this location.
2971676fbe81SDimitry Andric // It should be the location where the __attribute__((assume_aligned))
2972676fbe81SDimitry Andric // was written e.g.
emitAlignmentAssumptionCheck(llvm::Value * Ptr,QualType Ty,SourceLocation Loc,SourceLocation SecondaryLoc,llvm::Value * Alignment,llvm::Value * OffsetValue,llvm::Value * TheCheck,llvm::Instruction * Assumption)2973cfca06d7SDimitry Andric void CodeGenFunction::emitAlignmentAssumptionCheck(
2974676fbe81SDimitry Andric llvm::Value *Ptr, QualType Ty, SourceLocation Loc,
2975676fbe81SDimitry Andric SourceLocation SecondaryLoc, llvm::Value *Alignment,
2976676fbe81SDimitry Andric llvm::Value *OffsetValue, llvm::Value *TheCheck,
2977676fbe81SDimitry Andric llvm::Instruction *Assumption) {
2978ac9a064cSDimitry Andric assert(isa_and_nonnull<llvm::CallInst>(Assumption) &&
2979cfca06d7SDimitry Andric cast<llvm::CallInst>(Assumption)->getCalledOperand() ==
2980676fbe81SDimitry Andric llvm::Intrinsic::getDeclaration(
2981676fbe81SDimitry Andric Builder.GetInsertBlock()->getParent()->getParent(),
2982676fbe81SDimitry Andric llvm::Intrinsic::assume) &&
2983676fbe81SDimitry Andric "Assumption should be a call to llvm.assume().");
2984676fbe81SDimitry Andric assert(&(Builder.GetInsertBlock()->back()) == Assumption &&
2985676fbe81SDimitry Andric "Assumption should be the last instruction of the basic block, "
2986676fbe81SDimitry Andric "since the basic block is still being generated.");
2987676fbe81SDimitry Andric
2988676fbe81SDimitry Andric if (!SanOpts.has(SanitizerKind::Alignment))
2989676fbe81SDimitry Andric return;
2990676fbe81SDimitry Andric
2991676fbe81SDimitry Andric // Don't check pointers to volatile data. The behavior here is implementation-
2992676fbe81SDimitry Andric // defined.
2993676fbe81SDimitry Andric if (Ty->getPointeeType().isVolatileQualified())
2994676fbe81SDimitry Andric return;
2995676fbe81SDimitry Andric
2996676fbe81SDimitry Andric // We need to temorairly remove the assumption so we can insert the
2997676fbe81SDimitry Andric // sanitizer check before it, else the check will be dropped by optimizations.
2998676fbe81SDimitry Andric Assumption->removeFromParent();
2999676fbe81SDimitry Andric
3000676fbe81SDimitry Andric {
3001676fbe81SDimitry Andric SanitizerScope SanScope(this);
3002676fbe81SDimitry Andric
3003676fbe81SDimitry Andric if (!OffsetValue)
30046f8fc217SDimitry Andric OffsetValue = Builder.getInt1(false); // no offset.
3005676fbe81SDimitry Andric
3006676fbe81SDimitry Andric llvm::Constant *StaticData[] = {EmitCheckSourceLocation(Loc),
3007676fbe81SDimitry Andric EmitCheckSourceLocation(SecondaryLoc),
3008676fbe81SDimitry Andric EmitCheckTypeDescriptor(Ty)};
3009676fbe81SDimitry Andric llvm::Value *DynamicData[] = {EmitCheckValue(Ptr),
3010676fbe81SDimitry Andric EmitCheckValue(Alignment),
3011676fbe81SDimitry Andric EmitCheckValue(OffsetValue)};
3012676fbe81SDimitry Andric EmitCheck({std::make_pair(TheCheck, SanitizerKind::Alignment)},
3013676fbe81SDimitry Andric SanitizerHandler::AlignmentAssumption, StaticData, DynamicData);
3014676fbe81SDimitry Andric }
3015676fbe81SDimitry Andric
3016676fbe81SDimitry Andric // We are now in the (new, empty) "cont" basic block.
3017676fbe81SDimitry Andric // Reintroduce the assumption.
3018676fbe81SDimitry Andric Builder.Insert(Assumption);
3019676fbe81SDimitry Andric // FIXME: Assumption still has it's original basic block as it's Parent.
3020676fbe81SDimitry Andric }
3021676fbe81SDimitry Andric
SourceLocToDebugLoc(SourceLocation Location)3022bab175ecSDimitry Andric llvm::DebugLoc CodeGenFunction::SourceLocToDebugLoc(SourceLocation Location) {
3023bab175ecSDimitry Andric if (CGDebugInfo *DI = getDebugInfo())
3024bab175ecSDimitry Andric return DI->SourceLocToDebugLoc(Location);
3025bab175ecSDimitry Andric
3026bab175ecSDimitry Andric return llvm::DebugLoc();
3027bab175ecSDimitry Andric }
3028b60736ecSDimitry Andric
3029344a3780SDimitry Andric llvm::Value *
emitCondLikelihoodViaExpectIntrinsic(llvm::Value * Cond,Stmt::Likelihood LH)3030344a3780SDimitry Andric CodeGenFunction::emitCondLikelihoodViaExpectIntrinsic(llvm::Value *Cond,
3031344a3780SDimitry Andric Stmt::Likelihood LH) {
3032b60736ecSDimitry Andric switch (LH) {
3033b60736ecSDimitry Andric case Stmt::LH_None:
3034344a3780SDimitry Andric return Cond;
3035b60736ecSDimitry Andric case Stmt::LH_Likely:
3036344a3780SDimitry Andric case Stmt::LH_Unlikely:
3037344a3780SDimitry Andric // Don't generate llvm.expect on -O0 as the backend won't use it for
3038344a3780SDimitry Andric // anything.
3039344a3780SDimitry Andric if (CGM.getCodeGenOpts().OptimizationLevel == 0)
3040344a3780SDimitry Andric return Cond;
3041344a3780SDimitry Andric llvm::Type *CondTy = Cond->getType();
3042344a3780SDimitry Andric assert(CondTy->isIntegerTy(1) && "expecting condition to be a boolean");
3043344a3780SDimitry Andric llvm::Function *FnExpect =
3044344a3780SDimitry Andric CGM.getIntrinsic(llvm::Intrinsic::expect, CondTy);
3045344a3780SDimitry Andric llvm::Value *ExpectedValueOfCond =
3046344a3780SDimitry Andric llvm::ConstantInt::getBool(CondTy, LH == Stmt::LH_Likely);
3047344a3780SDimitry Andric return Builder.CreateCall(FnExpect, {Cond, ExpectedValueOfCond},
3048344a3780SDimitry Andric Cond->getName() + ".expval");
3049b60736ecSDimitry Andric }
3050b60736ecSDimitry Andric llvm_unreachable("Unknown Likelihood");
3051b60736ecSDimitry Andric }
3052145449b1SDimitry Andric
emitBoolVecConversion(llvm::Value * SrcVec,unsigned NumElementsDst,const llvm::Twine & Name)3053145449b1SDimitry Andric llvm::Value *CodeGenFunction::emitBoolVecConversion(llvm::Value *SrcVec,
3054145449b1SDimitry Andric unsigned NumElementsDst,
3055145449b1SDimitry Andric const llvm::Twine &Name) {
3056145449b1SDimitry Andric auto *SrcTy = cast<llvm::FixedVectorType>(SrcVec->getType());
3057145449b1SDimitry Andric unsigned NumElementsSrc = SrcTy->getNumElements();
3058145449b1SDimitry Andric if (NumElementsSrc == NumElementsDst)
3059145449b1SDimitry Andric return SrcVec;
3060145449b1SDimitry Andric
3061145449b1SDimitry Andric std::vector<int> ShuffleMask(NumElementsDst, -1);
3062145449b1SDimitry Andric for (unsigned MaskIdx = 0;
3063145449b1SDimitry Andric MaskIdx < std::min<>(NumElementsDst, NumElementsSrc); ++MaskIdx)
3064145449b1SDimitry Andric ShuffleMask[MaskIdx] = MaskIdx;
3065145449b1SDimitry Andric
3066145449b1SDimitry Andric return Builder.CreateShuffleVector(SrcVec, ShuffleMask, Name);
3067145449b1SDimitry Andric }
3068ac9a064cSDimitry Andric
EmitPointerAuthOperandBundle(const CGPointerAuthInfo & PointerAuth,SmallVectorImpl<llvm::OperandBundleDef> & Bundles)3069ac9a064cSDimitry Andric void CodeGenFunction::EmitPointerAuthOperandBundle(
3070ac9a064cSDimitry Andric const CGPointerAuthInfo &PointerAuth,
3071ac9a064cSDimitry Andric SmallVectorImpl<llvm::OperandBundleDef> &Bundles) {
3072ac9a064cSDimitry Andric if (!PointerAuth.isSigned())
3073ac9a064cSDimitry Andric return;
3074ac9a064cSDimitry Andric
3075ac9a064cSDimitry Andric auto *Key = Builder.getInt32(PointerAuth.getKey());
3076ac9a064cSDimitry Andric
3077ac9a064cSDimitry Andric llvm::Value *Discriminator = PointerAuth.getDiscriminator();
3078ac9a064cSDimitry Andric if (!Discriminator)
3079ac9a064cSDimitry Andric Discriminator = Builder.getSize(0);
3080ac9a064cSDimitry Andric
3081ac9a064cSDimitry Andric llvm::Value *Args[] = {Key, Discriminator};
3082ac9a064cSDimitry Andric Bundles.emplace_back("ptrauth", Args);
3083ac9a064cSDimitry Andric }
3084ac9a064cSDimitry Andric
EmitPointerAuthCommon(CodeGenFunction & CGF,const CGPointerAuthInfo & PointerAuth,llvm::Value * Pointer,unsigned IntrinsicID)3085ac9a064cSDimitry Andric static llvm::Value *EmitPointerAuthCommon(CodeGenFunction &CGF,
3086ac9a064cSDimitry Andric const CGPointerAuthInfo &PointerAuth,
3087ac9a064cSDimitry Andric llvm::Value *Pointer,
3088ac9a064cSDimitry Andric unsigned IntrinsicID) {
3089ac9a064cSDimitry Andric if (!PointerAuth)
3090ac9a064cSDimitry Andric return Pointer;
3091ac9a064cSDimitry Andric
3092ac9a064cSDimitry Andric auto Key = CGF.Builder.getInt32(PointerAuth.getKey());
3093ac9a064cSDimitry Andric
3094ac9a064cSDimitry Andric llvm::Value *Discriminator = PointerAuth.getDiscriminator();
3095ac9a064cSDimitry Andric if (!Discriminator) {
3096ac9a064cSDimitry Andric Discriminator = CGF.Builder.getSize(0);
3097ac9a064cSDimitry Andric }
3098ac9a064cSDimitry Andric
3099ac9a064cSDimitry Andric // Convert the pointer to intptr_t before signing it.
3100ac9a064cSDimitry Andric auto OrigType = Pointer->getType();
3101ac9a064cSDimitry Andric Pointer = CGF.Builder.CreatePtrToInt(Pointer, CGF.IntPtrTy);
3102ac9a064cSDimitry Andric
3103ac9a064cSDimitry Andric // call i64 @llvm.ptrauth.sign.i64(i64 %pointer, i32 %key, i64 %discriminator)
3104ac9a064cSDimitry Andric auto Intrinsic = CGF.CGM.getIntrinsic(IntrinsicID);
3105ac9a064cSDimitry Andric Pointer = CGF.EmitRuntimeCall(Intrinsic, {Pointer, Key, Discriminator});
3106ac9a064cSDimitry Andric
3107ac9a064cSDimitry Andric // Convert back to the original type.
3108ac9a064cSDimitry Andric Pointer = CGF.Builder.CreateIntToPtr(Pointer, OrigType);
3109ac9a064cSDimitry Andric return Pointer;
3110ac9a064cSDimitry Andric }
3111ac9a064cSDimitry Andric
3112ac9a064cSDimitry Andric llvm::Value *
EmitPointerAuthSign(const CGPointerAuthInfo & PointerAuth,llvm::Value * Pointer)3113ac9a064cSDimitry Andric CodeGenFunction::EmitPointerAuthSign(const CGPointerAuthInfo &PointerAuth,
3114ac9a064cSDimitry Andric llvm::Value *Pointer) {
3115ac9a064cSDimitry Andric if (!PointerAuth.shouldSign())
3116ac9a064cSDimitry Andric return Pointer;
3117ac9a064cSDimitry Andric return EmitPointerAuthCommon(*this, PointerAuth, Pointer,
3118ac9a064cSDimitry Andric llvm::Intrinsic::ptrauth_sign);
3119ac9a064cSDimitry Andric }
3120ac9a064cSDimitry Andric
EmitStrip(CodeGenFunction & CGF,const CGPointerAuthInfo & PointerAuth,llvm::Value * Pointer)3121ac9a064cSDimitry Andric static llvm::Value *EmitStrip(CodeGenFunction &CGF,
3122ac9a064cSDimitry Andric const CGPointerAuthInfo &PointerAuth,
3123ac9a064cSDimitry Andric llvm::Value *Pointer) {
3124ac9a064cSDimitry Andric auto StripIntrinsic = CGF.CGM.getIntrinsic(llvm::Intrinsic::ptrauth_strip);
3125ac9a064cSDimitry Andric
3126ac9a064cSDimitry Andric auto Key = CGF.Builder.getInt32(PointerAuth.getKey());
3127ac9a064cSDimitry Andric // Convert the pointer to intptr_t before signing it.
3128ac9a064cSDimitry Andric auto OrigType = Pointer->getType();
3129ac9a064cSDimitry Andric Pointer = CGF.EmitRuntimeCall(
3130ac9a064cSDimitry Andric StripIntrinsic, {CGF.Builder.CreatePtrToInt(Pointer, CGF.IntPtrTy), Key});
3131ac9a064cSDimitry Andric return CGF.Builder.CreateIntToPtr(Pointer, OrigType);
3132ac9a064cSDimitry Andric }
3133ac9a064cSDimitry Andric
3134ac9a064cSDimitry Andric llvm::Value *
EmitPointerAuthAuth(const CGPointerAuthInfo & PointerAuth,llvm::Value * Pointer)3135ac9a064cSDimitry Andric CodeGenFunction::EmitPointerAuthAuth(const CGPointerAuthInfo &PointerAuth,
3136ac9a064cSDimitry Andric llvm::Value *Pointer) {
3137ac9a064cSDimitry Andric if (PointerAuth.shouldStrip()) {
3138ac9a064cSDimitry Andric return EmitStrip(*this, PointerAuth, Pointer);
3139ac9a064cSDimitry Andric }
3140ac9a064cSDimitry Andric if (!PointerAuth.shouldAuth()) {
3141ac9a064cSDimitry Andric return Pointer;
3142ac9a064cSDimitry Andric }
3143ac9a064cSDimitry Andric
3144ac9a064cSDimitry Andric return EmitPointerAuthCommon(*this, PointerAuth, Pointer,
3145ac9a064cSDimitry Andric llvm::Intrinsic::ptrauth_auth);
3146ac9a064cSDimitry Andric }
3147