summaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CodeGenFunction.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
commitcfca06d7963fa0909f90483b42a6d7d194d01e08 (patch)
tree209fb2a2d68f8f277793fc8df46c753d31bc853b /clang/lib/CodeGen/CodeGenFunction.cpp
parent706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff)
Notes
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp355
1 files changed, 194 insertions, 161 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 2bf94f697e01c..4a7c84562deef 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -32,6 +32,7 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/CodeGen/CGFunctionInfo.h"
#include "clang/Frontend/FrontendDiagnostic.h"
+#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/FPEnv.h"
@@ -64,67 +65,36 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)
: CodeGenTypeCache(cgm), CGM(cgm), Target(cgm.getTarget()),
Builder(cgm, cgm.getModule().getContext(), llvm::ConstantFolder(),
CGBuilderInserterTy(this)),
- SanOpts(CGM.getLangOpts().Sanitize), DebugInfo(CGM.getModuleDebugInfo()),
- PGO(cgm), ShouldEmitLifetimeMarkers(shouldEmitLifetimeMarkers(
- CGM.getCodeGenOpts(), CGM.getLangOpts())) {
+ SanOpts(CGM.getLangOpts().Sanitize), CurFPFeatures(CGM.getLangOpts()),
+ DebugInfo(CGM.getModuleDebugInfo()), PGO(cgm),
+ ShouldEmitLifetimeMarkers(
+ shouldEmitLifetimeMarkers(CGM.getCodeGenOpts(), CGM.getLangOpts())) {
if (!suppressNewContext)
CGM.getCXXABI().getMangleContext().startNewFunction();
- llvm::FastMathFlags FMF;
- if (CGM.getLangOpts().FastMath)
- FMF.setFast();
- if (CGM.getLangOpts().FiniteMathOnly) {
- FMF.setNoNaNs();
- FMF.setNoInfs();
- }
- if (CGM.getCodeGenOpts().NoNaNsFPMath) {
- FMF.setNoNaNs();
- }
- if (CGM.getCodeGenOpts().NoSignedZeros) {
- FMF.setNoSignedZeros();
- }
- if (CGM.getCodeGenOpts().ReciprocalMath) {
- FMF.setAllowReciprocal();
- }
- if (CGM.getCodeGenOpts().Reassociate) {
- FMF.setAllowReassoc();
- }
- Builder.setFastMathFlags(FMF);
+ SetFastMathFlags(CurFPFeatures);
SetFPModel();
}
CodeGenFunction::~CodeGenFunction() {
assert(LifetimeExtendedCleanupStack.empty() && "failed to emit a cleanup");
- // If there are any unclaimed block infos, go ahead and destroy them
- // now. This can happen if IR-gen gets clever and skips evaluating
- // something.
- if (FirstBlockInfo)
- destroyBlockInfos(FirstBlockInfo);
-
if (getLangOpts().OpenMP && CurFn)
CGM.getOpenMPRuntime().functionFinished(*this);
-}
-
-// Map the LangOption for rounding mode into
-// the corresponding enum in the IR.
-static llvm::fp::RoundingMode ToConstrainedRoundingMD(
- LangOptions::FPRoundingModeKind Kind) {
- switch (Kind) {
- case LangOptions::FPR_ToNearest: return llvm::fp::rmToNearest;
- case LangOptions::FPR_Downward: return llvm::fp::rmDownward;
- case LangOptions::FPR_Upward: return llvm::fp::rmUpward;
- case LangOptions::FPR_TowardZero: return llvm::fp::rmTowardZero;
- case LangOptions::FPR_Dynamic: return llvm::fp::rmDynamic;
- }
- llvm_unreachable("Unsupported FP RoundingMode");
+ // If we have an OpenMPIRBuilder we want to finalize functions (incl.
+ // outlining etc) at some point. Doing it once the function codegen is done
+ // seems to be a reasonable spot. We do it here, as opposed to the deletion
+ // time of the CodeGenModule, because we have to ensure the IR has not yet
+ // been "emitted" to the outside, thus, modifications are still sensible.
+ if (CGM.getLangOpts().OpenMPIRBuilder)
+ CGM.getOpenMPRuntime().getOMPBuilder().finalize();
}
// Map the LangOption for exception behavior into
// the corresponding enum in the IR.
-static llvm::fp::ExceptionBehavior ToConstrainedExceptMD(
- LangOptions::FPExceptionModeKind Kind) {
+llvm::fp::ExceptionBehavior
+clang::ToConstrainedExceptMD(LangOptions::FPExceptionModeKind Kind) {
switch (Kind) {
case LangOptions::FPE_Ignore: return llvm::fp::ebIgnore;
@@ -135,81 +105,79 @@ static llvm::fp::ExceptionBehavior ToConstrainedExceptMD(
}
void CodeGenFunction::SetFPModel() {
- auto fpRoundingMode = ToConstrainedRoundingMD(
- getLangOpts().getFPRoundingMode());
+ llvm::RoundingMode RM = getLangOpts().getFPRoundingMode();
auto fpExceptionBehavior = ToConstrainedExceptMD(
getLangOpts().getFPExceptionMode());
- if (fpExceptionBehavior == llvm::fp::ebIgnore &&
- fpRoundingMode == llvm::fp::rmToNearest)
- // Constrained intrinsics are not used.
- ;
- else {
- Builder.setIsFPConstrained(true);
- Builder.setDefaultConstrainedRounding(fpRoundingMode);
- Builder.setDefaultConstrainedExcept(fpExceptionBehavior);
- }
-}
-
-CharUnits CodeGenFunction::getNaturalPointeeTypeAlignment(QualType T,
- LValueBaseInfo *BaseInfo,
- TBAAAccessInfo *TBAAInfo) {
- return getNaturalTypeAlignment(T->getPointeeType(), BaseInfo, TBAAInfo,
- /* forPointeeType= */ true);
-}
-
-CharUnits CodeGenFunction::getNaturalTypeAlignment(QualType T,
- LValueBaseInfo *BaseInfo,
- TBAAAccessInfo *TBAAInfo,
- bool forPointeeType) {
- if (TBAAInfo)
- *TBAAInfo = CGM.getTBAAAccessInfo(T);
-
- // Honor alignment typedef attributes even on incomplete types.
- // We also honor them straight for C++ class types, even as pointees;
- // there's an expressivity gap here.
- if (auto TT = T->getAs<TypedefType>()) {
- if (auto Align = TT->getDecl()->getMaxAlignment()) {
- if (BaseInfo)
- *BaseInfo = LValueBaseInfo(AlignmentSource::AttributedType);
- return getContext().toCharUnitsFromBits(Align);
- }
- }
+ Builder.setDefaultConstrainedRounding(RM);
+ Builder.setDefaultConstrainedExcept(fpExceptionBehavior);
+ Builder.setIsFPConstrained(fpExceptionBehavior != llvm::fp::ebIgnore ||
+ RM != llvm::RoundingMode::NearestTiesToEven);
+}
- if (BaseInfo)
- *BaseInfo = LValueBaseInfo(AlignmentSource::Type);
+void CodeGenFunction::SetFastMathFlags(FPOptions FPFeatures) {
+ llvm::FastMathFlags FMF;
+ FMF.setAllowReassoc(FPFeatures.getAllowFPReassociate());
+ FMF.setNoNaNs(FPFeatures.getNoHonorNaNs());
+ FMF.setNoInfs(FPFeatures.getNoHonorInfs());
+ FMF.setNoSignedZeros(FPFeatures.getNoSignedZero());
+ FMF.setAllowReciprocal(FPFeatures.getAllowReciprocal());
+ FMF.setApproxFunc(FPFeatures.getAllowApproxFunc());
+ FMF.setAllowContract(FPFeatures.allowFPContractAcrossStatement());
+ Builder.setFastMathFlags(FMF);
+}
- CharUnits Alignment;
- if (T->isIncompleteType()) {
- Alignment = CharUnits::One(); // Shouldn't be used, but pessimistic is best.
- } else {
- // For C++ class pointees, we don't know whether we're pointing at a
- // base or a complete object, so we generally need to use the
- // non-virtual alignment.
- const CXXRecordDecl *RD;
- if (forPointeeType && (RD = T->getAsCXXRecordDecl())) {
- Alignment = CGM.getClassPointerAlignment(RD);
- } else {
- Alignment = getContext().getTypeAlignInChars(T);
- if (T.getQualifiers().hasUnaligned())
- Alignment = CharUnits::One();
- }
+CodeGenFunction::CGFPOptionsRAII::CGFPOptionsRAII(CodeGenFunction &CGF,
+ FPOptions FPFeatures)
+ : CGF(CGF), OldFPFeatures(CGF.CurFPFeatures) {
+ CGF.CurFPFeatures = FPFeatures;
- // Cap to the global maximum type alignment unless the alignment
- // was somehow explicit on the type.
- if (unsigned MaxAlign = getLangOpts().MaxTypeAlign) {
- if (Alignment.getQuantity() > MaxAlign &&
- !getContext().isAlignmentRequired(T))
- Alignment = CharUnits::fromQuantity(MaxAlign);
- }
- }
- return Alignment;
+ if (OldFPFeatures == FPFeatures)
+ return;
+
+ FMFGuard.emplace(CGF.Builder);
+
+ llvm::RoundingMode NewRoundingBehavior =
+ static_cast<llvm::RoundingMode>(FPFeatures.getRoundingMode());
+ CGF.Builder.setDefaultConstrainedRounding(NewRoundingBehavior);
+ auto NewExceptionBehavior =
+ ToConstrainedExceptMD(static_cast<LangOptions::FPExceptionModeKind>(
+ FPFeatures.getFPExceptionMode()));
+ CGF.Builder.setDefaultConstrainedExcept(NewExceptionBehavior);
+
+ CGF.SetFastMathFlags(FPFeatures);
+
+ assert((CGF.CurFuncDecl == nullptr || CGF.Builder.getIsFPConstrained() ||
+ isa<CXXConstructorDecl>(CGF.CurFuncDecl) ||
+ isa<CXXDestructorDecl>(CGF.CurFuncDecl) ||
+ (NewExceptionBehavior == llvm::fp::ebIgnore &&
+ NewRoundingBehavior == llvm::RoundingMode::NearestTiesToEven)) &&
+ "FPConstrained should be enabled on entire function");
+
+ auto mergeFnAttrValue = [&](StringRef Name, bool Value) {
+ auto OldValue =
+ CGF.CurFn->getFnAttribute(Name).getValueAsString() == "true";
+ auto NewValue = OldValue & Value;
+ if (OldValue != NewValue)
+ CGF.CurFn->addFnAttr(Name, llvm::toStringRef(NewValue));
+ };
+ mergeFnAttrValue("no-infs-fp-math", FPFeatures.getNoHonorInfs());
+ mergeFnAttrValue("no-nans-fp-math", FPFeatures.getNoHonorNaNs());
+ mergeFnAttrValue("no-signed-zeros-fp-math", FPFeatures.getNoSignedZero());
+ mergeFnAttrValue("unsafe-fp-math", FPFeatures.getAllowFPReassociate() &&
+ FPFeatures.getAllowReciprocal() &&
+ FPFeatures.getAllowApproxFunc() &&
+ FPFeatures.getNoSignedZero());
+}
+
+CodeGenFunction::CGFPOptionsRAII::~CGFPOptionsRAII() {
+ CGF.CurFPFeatures = OldFPFeatures;
}
LValue CodeGenFunction::MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T) {
LValueBaseInfo BaseInfo;
TBAAAccessInfo TBAAInfo;
- CharUnits Alignment = getNaturalTypeAlignment(T, &BaseInfo, &TBAAInfo);
+ CharUnits Alignment = CGM.getNaturalTypeAlignment(T, &BaseInfo, &TBAAInfo);
return LValue::MakeAddr(Address(V, Alignment), T, getContext(), BaseInfo,
TBAAInfo);
}
@@ -220,8 +188,8 @@ LValue
CodeGenFunction::MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T) {
LValueBaseInfo BaseInfo;
TBAAAccessInfo TBAAInfo;
- CharUnits Align = getNaturalTypeAlignment(T, &BaseInfo, &TBAAInfo,
- /* forPointeeType= */ true);
+ CharUnits Align = CGM.getNaturalTypeAlignment(T, &BaseInfo, &TBAAInfo,
+ /* forPointeeType= */ true);
return MakeAddrLValue(Address(V, Align), T, BaseInfo, TBAAInfo);
}
@@ -259,11 +227,13 @@ TypeEvaluationKind CodeGenFunction::getEvaluationKind(QualType type) {
case Type::MemberPointer:
case Type::Vector:
case Type::ExtVector:
+ case Type::ConstantMatrix:
case Type::FunctionProto:
case Type::FunctionNoProto:
case Type::Enum:
case Type::ObjCObjectPointer:
case Type::Pipe:
+ case Type::ExtInt:
return TEK_Scalar;
// Complexes.
@@ -486,13 +456,15 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
// Scan function arguments for vector width.
for (llvm::Argument &A : CurFn->args())
if (auto *VT = dyn_cast<llvm::VectorType>(A.getType()))
- LargestVectorWidth = std::max((uint64_t)LargestVectorWidth,
- VT->getPrimitiveSizeInBits().getFixedSize());
+ LargestVectorWidth =
+ std::max((uint64_t)LargestVectorWidth,
+ VT->getPrimitiveSizeInBits().getKnownMinSize());
// Update vector width based on return type.
if (auto *VT = dyn_cast<llvm::VectorType>(CurFn->getReturnType()))
- LargestVectorWidth = std::max((uint64_t)LargestVectorWidth,
- VT->getPrimitiveSizeInBits().getFixedSize());
+ LargestVectorWidth =
+ std::max((uint64_t)LargestVectorWidth,
+ VT->getPrimitiveSizeInBits().getKnownMinSize());
// Add the required-vector-width attribute. This contains the max width from:
// 1. min-vector-width attribute used in the source program.
@@ -799,35 +771,54 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
FD->getBody()->getStmtClass() == Stmt::CoroutineBodyStmtClass)
SanOpts.Mask &= ~SanitizerKind::Null;
- if (D) {
- // Apply xray attributes to the function (as a string, for now)
- if (const auto *XRayAttr = D->getAttr<XRayInstrumentAttr>()) {
- if (CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
- XRayInstrKind::Function)) {
- if (XRayAttr->alwaysXRayInstrument() && ShouldXRayInstrumentFunction())
- Fn->addFnAttr("function-instrument", "xray-always");
- if (XRayAttr->neverXRayInstrument())
- Fn->addFnAttr("function-instrument", "xray-never");
- if (const auto *LogArgs = D->getAttr<XRayLogArgsAttr>())
- if (ShouldXRayInstrumentFunction())
- Fn->addFnAttr("xray-log-args",
- llvm::utostr(LogArgs->getArgumentCount()));
- }
- } else {
- if (ShouldXRayInstrumentFunction() && !CGM.imbueXRayAttrs(Fn, Loc))
- Fn->addFnAttr(
- "xray-instruction-threshold",
- llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold));
+ // Apply xray attributes to the function (as a string, for now)
+ if (const auto *XRayAttr = D ? D->getAttr<XRayInstrumentAttr>() : nullptr) {
+ if (CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
+ XRayInstrKind::FunctionEntry) ||
+ CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
+ XRayInstrKind::FunctionExit)) {
+ if (XRayAttr->alwaysXRayInstrument() && ShouldXRayInstrumentFunction())
+ Fn->addFnAttr("function-instrument", "xray-always");
+ if (XRayAttr->neverXRayInstrument())
+ Fn->addFnAttr("function-instrument", "xray-never");
+ if (const auto *LogArgs = D->getAttr<XRayLogArgsAttr>())
+ if (ShouldXRayInstrumentFunction())
+ Fn->addFnAttr("xray-log-args",
+ llvm::utostr(LogArgs->getArgumentCount()));
}
+ } else {
+ if (ShouldXRayInstrumentFunction() && !CGM.imbueXRayAttrs(Fn, Loc))
+ Fn->addFnAttr(
+ "xray-instruction-threshold",
+ llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold));
+ }
- if (const auto *Attr = D->getAttr<PatchableFunctionEntryAttr>()) {
- // Attr->getStart is currently ignored.
- Fn->addFnAttr("patchable-function-entry",
- std::to_string(Attr->getCount()));
- } else if (unsigned Count = CGM.getCodeGenOpts().PatchableFunctionEntryCount) {
- Fn->addFnAttr("patchable-function-entry",
- std::to_string(Count));
- }
+ if (ShouldXRayInstrumentFunction()) {
+ if (CGM.getCodeGenOpts().XRayIgnoreLoops)
+ Fn->addFnAttr("xray-ignore-loops");
+
+ if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
+ XRayInstrKind::FunctionExit))
+ Fn->addFnAttr("xray-skip-exit");
+
+ if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
+ XRayInstrKind::FunctionEntry))
+ Fn->addFnAttr("xray-skip-entry");
+ }
+
+ unsigned Count, Offset;
+ if (const auto *Attr =
+ D ? D->getAttr<PatchableFunctionEntryAttr>() : nullptr) {
+ Count = Attr->getCount();
+ Offset = Attr->getOffset();
+ } else {
+ Count = CGM.getCodeGenOpts().PatchableFunctionEntryCount;
+ Offset = CGM.getCodeGenOpts().PatchableFunctionEntryOffset;
+ }
+ if (Count && Offset <= Count) {
+ Fn->addFnAttr("patchable-function-entry", std::to_string(Count - Offset));
+ if (Offset)
+ Fn->addFnAttr("patchable-function-prefix", std::to_string(Offset));
}
// Add no-jump-tables value.
@@ -842,6 +833,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
if (CGM.getCodeGenOpts().ProfileSampleAccurate)
Fn->addFnAttr("profile-sample-accurate");
+ if (!CGM.getCodeGenOpts().SampleProfileFile.empty())
+ Fn->addFnAttr("use-sample-profile");
+
if (D && D->hasAttr<CFICanonicalJumpTableAttr>())
Fn->addFnAttr("cfi-canonical-jump-table");
@@ -889,14 +883,26 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
// If we're in C++ mode and the function name is "main", it is guaranteed
// to be norecurse by the standard (3.6.1.3 "The function main shall not be
// used within a program").
- if (getLangOpts().CPlusPlus)
- if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
- if (FD->isMain())
- Fn->addFnAttr(llvm::Attribute::NoRecurse);
-
- if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
+ //
+ // OpenCL C 2.0 v2.2-11 s6.9.i:
+ // Recursion is not supported.
+ //
+ // SYCL v1.2.1 s3.10:
+ // kernels cannot include RTTI information, exception classes,
+ // recursive code, virtual functions or make use of C++ libraries that
+ // are not compiled for the device.
+ if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
+ if ((getLangOpts().CPlusPlus && FD->isMain()) || getLangOpts().OpenCL ||
+ getLangOpts().SYCLIsDevice ||
+ (getLangOpts().CUDA && FD->hasAttr<CUDAGlobalAttr>()))
+ Fn->addFnAttr(llvm::Attribute::NoRecurse);
+ }
+
+ if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
+ Builder.setIsFPConstrained(FD->usesFPIntrin());
if (FD->usesFPIntrin())
Fn->addFnAttr(llvm::Attribute::StrictFP);
+ }
// If a custom alignment is used, force realigning to this alignment on
// any main function which certainly will need it.
@@ -1021,7 +1027,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
llvm::Value *Addr = Builder.CreateStructGEP(nullptr, &*EI, Idx);
ReturnValuePointer = Address(Addr, getPointerAlign());
Addr = Builder.CreateAlignedLoad(Addr, getPointerAlign(), "agg.result");
- ReturnValue = Address(Addr, getNaturalTypeAlignment(RetTy));
+ ReturnValue = Address(Addr, CGM.getNaturalTypeAlignment(RetTy));
} else {
ReturnValue = CreateIRTemp(RetTy, "retval");
@@ -1978,6 +1984,7 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
case Type::Complex:
case Type::Vector:
case Type::ExtVector:
+ case Type::ConstantMatrix:
case Type::Record:
case Type::Enum:
case Type::Elaborated:
@@ -1986,6 +1993,7 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
case Type::ObjCObject:
case Type::ObjCInterface:
case Type::ObjCObjectPointer:
+ case Type::ExtInt:
llvm_unreachable("type class is never variably-modified!");
case Type::Adjusted:
@@ -2141,21 +2149,47 @@ void CodeGenFunction::unprotectFromPeepholes(PeepholeProtection protection) {
protection.Inst->eraseFromParent();
}
-void CodeGenFunction::EmitAlignmentAssumption(llvm::Value *PtrValue,
+void CodeGenFunction::emitAlignmentAssumption(llvm::Value *PtrValue,
QualType Ty, SourceLocation Loc,
SourceLocation AssumptionLoc,
llvm::Value *Alignment,
llvm::Value *OffsetValue) {
- llvm::Value *TheCheck;
- llvm::Instruction *Assumption = Builder.CreateAlignmentAssumption(
- CGM.getDataLayout(), PtrValue, Alignment, OffsetValue, &TheCheck);
+ if (Alignment->getType() != IntPtrTy)
+ Alignment =
+ Builder.CreateIntCast(Alignment, IntPtrTy, false, "casted.align");
+ if (OffsetValue && OffsetValue->getType() != IntPtrTy)
+ OffsetValue =
+ Builder.CreateIntCast(OffsetValue, IntPtrTy, true, "casted.offset");
+ llvm::Value *TheCheck = nullptr;
if (SanOpts.has(SanitizerKind::Alignment)) {
- EmitAlignmentAssumptionCheck(PtrValue, Ty, Loc, AssumptionLoc, Alignment,
- OffsetValue, TheCheck, Assumption);
+ llvm::Value *PtrIntValue =
+ Builder.CreatePtrToInt(PtrValue, IntPtrTy, "ptrint");
+
+ if (OffsetValue) {
+ bool IsOffsetZero = false;
+ if (const auto *CI = dyn_cast<llvm::ConstantInt>(OffsetValue))
+ IsOffsetZero = CI->isZero();
+
+ if (!IsOffsetZero)
+ PtrIntValue = Builder.CreateSub(PtrIntValue, OffsetValue, "offsetptr");
+ }
+
+ llvm::Value *Zero = llvm::ConstantInt::get(IntPtrTy, 0);
+ llvm::Value *Mask =
+ Builder.CreateSub(Alignment, llvm::ConstantInt::get(IntPtrTy, 1));
+ llvm::Value *MaskedPtr = Builder.CreateAnd(PtrIntValue, Mask, "maskedptr");
+ TheCheck = Builder.CreateICmpEQ(MaskedPtr, Zero, "maskcond");
}
+ llvm::Instruction *Assumption = Builder.CreateAlignmentAssumption(
+ CGM.getDataLayout(), PtrValue, Alignment, OffsetValue);
+
+ if (!SanOpts.has(SanitizerKind::Alignment))
+ return;
+ emitAlignmentAssumptionCheck(PtrValue, Ty, Loc, AssumptionLoc, Alignment,
+ OffsetValue, TheCheck, Assumption);
}
-void CodeGenFunction::EmitAlignmentAssumption(llvm::Value *PtrValue,
+void CodeGenFunction::emitAlignmentAssumption(llvm::Value *PtrValue,
const Expr *E,
SourceLocation AssumptionLoc,
llvm::Value *Alignment,
@@ -2165,7 +2199,7 @@ void CodeGenFunction::EmitAlignmentAssumption(llvm::Value *PtrValue,
QualType Ty = E->getType();
SourceLocation Loc = E->getExprLoc();
- EmitAlignmentAssumption(PtrValue, Ty, Loc, AssumptionLoc, Alignment,
+ emitAlignmentAssumption(PtrValue, Ty, Loc, AssumptionLoc, Alignment,
OffsetValue);
}
@@ -2319,8 +2353,7 @@ void CodeGenFunction::checkTargetFeatures(SourceLocation Loc,
SmallVector<StringRef, 1> ReqFeatures;
llvm::StringMap<bool> CalleeFeatureMap;
- CGM.getContext().getFunctionFeatureMap(CalleeFeatureMap,
- GlobalDecl(TargetDecl));
+ CGM.getContext().getFunctionFeatureMap(CalleeFeatureMap, TargetDecl);
for (const auto &F : ParsedAttr.Features) {
if (F[0] == '+' && CalleeFeatureMap.lookup(F.substr(1)))
@@ -2433,13 +2466,13 @@ void CodeGenFunction::EmitMultiVersionResolver(
// Loc), the diagnostic will additionally point a "Note:" to this location.
// It should be the location where the __attribute__((assume_aligned))
// was written e.g.
-void CodeGenFunction::EmitAlignmentAssumptionCheck(
+void CodeGenFunction::emitAlignmentAssumptionCheck(
llvm::Value *Ptr, QualType Ty, SourceLocation Loc,
SourceLocation SecondaryLoc, llvm::Value *Alignment,
llvm::Value *OffsetValue, llvm::Value *TheCheck,
llvm::Instruction *Assumption) {
assert(Assumption && isa<llvm::CallInst>(Assumption) &&
- cast<llvm::CallInst>(Assumption)->getCalledValue() ==
+ cast<llvm::CallInst>(Assumption)->getCalledOperand() ==
llvm::Intrinsic::getDeclaration(
Builder.GetInsertBlock()->getParent()->getParent(),
llvm::Intrinsic::assume) &&