diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2023-07-26 19:03:47 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2023-07-26 19:04:23 +0000 |
| commit | 7fa27ce4a07f19b07799a767fc29416f3b625afb (patch) | |
| tree | 27825c83636c4de341eb09a74f49f5d38a15d165 /clang/lib/CodeGen/CGExpr.cpp | |
| parent | e3b557809604d036af6e00c60f012c2025b59a5e (diff) | |
Diffstat (limited to 'clang/lib/CodeGen/CGExpr.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 346 |
1 files changed, 210 insertions, 136 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index c26dd1b23321..ed6095f7cfeb 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -33,13 +33,16 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Intrinsics.h" +#include "llvm/IR/IntrinsicsWebAssembly.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/MatrixBuilder.h" +#include "llvm/Passes/OptimizationLevel.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/Path.h" #include "llvm/Support/SaveAndRestore.h" +#include "llvm/Support/xxhash.h" #include "llvm/Transforms/Utils/SanitizerStats.h" #include <optional> @@ -52,18 +55,6 @@ using namespace CodeGen; // Miscellaneous Helper Methods //===--------------------------------------------------------------------===// -llvm::Value *CodeGenFunction::EmitCastToVoidPtr(llvm::Value *value) { - unsigned addressSpace = - cast<llvm::PointerType>(value->getType())->getAddressSpace(); - - llvm::PointerType *destType = Int8PtrTy; - if (addressSpace) - destType = llvm::Type::getInt8PtrTy(getLLVMContext(), addressSpace); - - if (value->getType() == destType) return value; - return Builder.CreateBitCast(value, destType); -} - /// CreateTempAlloca - This creates a alloca and inserts it into the entry /// block. Address CodeGenFunction::CreateTempAllocaWithoutCast(llvm::Type *Ty, @@ -72,7 +63,7 @@ Address CodeGenFunction::CreateTempAllocaWithoutCast(llvm::Type *Ty, llvm::Value *ArraySize) { auto Alloca = CreateTempAlloca(Ty, Name, ArraySize); Alloca->setAlignment(Align.getAsAlign()); - return Address(Alloca, Ty, Align); + return Address(Alloca, Ty, Align, KnownNonNull); } /// CreateTempAlloca - This creates a alloca and inserts it into the entry @@ -102,7 +93,7 @@ Address CodeGenFunction::CreateTempAlloca(llvm::Type *Ty, CharUnits Align, Ty->getPointerTo(DestAddrSpace), /*non-null*/ true); } - return Address(V, Ty, Align); + return Address(V, Ty, Align, KnownNonNull); } /// CreateTempAlloca - This creates an alloca and inserts it into the entry @@ -151,7 +142,7 @@ Address CodeGenFunction::CreateMemTemp(QualType Ty, CharUnits Align, Result = Address( Builder.CreateBitCast(Result.getPointer(), VectorTy->getPointerTo()), - VectorTy, Result.getAlignment()); + VectorTy, Result.getAlignment(), KnownNonNull); } return Result; } @@ -401,7 +392,7 @@ static Address createReferenceTemporary(CodeGenFunction &CGF, QualType Ty = Inner->getType(); if (CGF.CGM.getCodeGenOpts().MergeAllConstants && (Ty->isArrayType() || Ty->isRecordType()) && - CGF.CGM.isTypeConstant(Ty, true)) + CGF.CGM.isTypeConstant(Ty, true, false)) if (auto Init = ConstantEmitter(CGF).tryEmitAbstract(Inner, Ty)) { auto AS = CGF.CGM.GetGlobalConstantAddressSpace(); auto *GV = new llvm::GlobalVariable( @@ -541,13 +532,17 @@ EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) { // Avoid creating a conditional cleanup just to hold an llvm.lifetime.end // marker. Instead, start the lifetime of a conditional temporary earlier // so that it's unconditional. Don't do this with sanitizers which need - // more precise lifetime marks. + // more precise lifetime marks. However when inside an "await.suspend" + // block, we should always avoid conditional cleanup because it creates + // boolean marker that lives across await_suspend, which can destroy coro + // frame. ConditionalEvaluation *OldConditional = nullptr; CGBuilderTy::InsertPoint OldIP; if (isInConditionalBranch() && !E->getType().isDestructedType() && - !SanOpts.has(SanitizerKind::HWAddress) && - !SanOpts.has(SanitizerKind::Memory) && - !CGM.getCodeGenOpts().SanitizeAddressUseAfterScope) { + ((!SanOpts.has(SanitizerKind::HWAddress) && + !SanOpts.has(SanitizerKind::Memory) && + !CGM.getCodeGenOpts().SanitizeAddressUseAfterScope) || + inSuspendBlock())) { OldConditional = OutermostConditional; OutermostConditional = nullptr; @@ -1035,11 +1030,10 @@ void CodeGenModule::EmitExplicitCastExprType(const ExplicitCastExpr *E, // LValue Expression Emission //===----------------------------------------------------------------------===// -/// EmitPointerWithAlignment - Given an expression of pointer type, try to -/// derive a more accurate bound on the alignment of the pointer. -Address CodeGenFunction::EmitPointerWithAlignment(const Expr *E, - LValueBaseInfo *BaseInfo, - TBAAAccessInfo *TBAAInfo) { +static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo, + TBAAAccessInfo *TBAAInfo, + KnownNonNull_t IsKnownNonNull, + CodeGenFunction &CGF) { // We allow this with ObjC object pointers because of fragile ABIs. assert(E->getType()->isPointerType() || E->getType()->isObjCObjectPointerType()); @@ -1048,7 +1042,7 @@ Address CodeGenFunction::EmitPointerWithAlignment(const Expr *E, // Casts: if (const CastExpr *CE = dyn_cast<CastExpr>(E)) { if (const auto *ECE = dyn_cast<ExplicitCastExpr>(CE)) - CGM.EmitExplicitCastExprType(ECE, this); + CGF.CGM.EmitExplicitCastExprType(ECE, &CGF); switch (CE->getCastKind()) { // Non-converting casts (but not C's implicit conversion from void*). @@ -1061,49 +1055,51 @@ Address CodeGenFunction::EmitPointerWithAlignment(const Expr *E, LValueBaseInfo InnerBaseInfo; TBAAAccessInfo InnerTBAAInfo; - Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), - &InnerBaseInfo, - &InnerTBAAInfo); + Address Addr = CGF.EmitPointerWithAlignment( + CE->getSubExpr(), &InnerBaseInfo, &InnerTBAAInfo, IsKnownNonNull); if (BaseInfo) *BaseInfo = InnerBaseInfo; if (TBAAInfo) *TBAAInfo = InnerTBAAInfo; if (isa<ExplicitCastExpr>(CE)) { LValueBaseInfo TargetTypeBaseInfo; TBAAAccessInfo TargetTypeTBAAInfo; - CharUnits Align = CGM.getNaturalPointeeTypeAlignment( + CharUnits Align = CGF.CGM.getNaturalPointeeTypeAlignment( E->getType(), &TargetTypeBaseInfo, &TargetTypeTBAAInfo); if (TBAAInfo) - *TBAAInfo = CGM.mergeTBAAInfoForCast(*TBAAInfo, - TargetTypeTBAAInfo); + *TBAAInfo = + CGF.CGM.mergeTBAAInfoForCast(*TBAAInfo, TargetTypeTBAAInfo); // If the source l-value is opaque, honor the alignment of the // casted-to type. if (InnerBaseInfo.getAlignmentSource() != AlignmentSource::Decl) { if (BaseInfo) BaseInfo->mergeForCast(TargetTypeBaseInfo); - Addr = Address(Addr.getPointer(), Addr.getElementType(), Align); + Addr = Address(Addr.getPointer(), Addr.getElementType(), Align, + IsKnownNonNull); } } - if (SanOpts.has(SanitizerKind::CFIUnrelatedCast) && + if (CGF.SanOpts.has(SanitizerKind::CFIUnrelatedCast) && CE->getCastKind() == CK_BitCast) { if (auto PT = E->getType()->getAs<PointerType>()) - EmitVTablePtrCheckForCast(PT->getPointeeType(), Addr, - /*MayBeNull=*/true, - CodeGenFunction::CFITCK_UnrelatedCast, - CE->getBeginLoc()); + CGF.EmitVTablePtrCheckForCast(PT->getPointeeType(), Addr, + /*MayBeNull=*/true, + CodeGenFunction::CFITCK_UnrelatedCast, + CE->getBeginLoc()); } - llvm::Type *ElemTy = ConvertTypeForMem(E->getType()->getPointeeType()); - Addr = Builder.CreateElementBitCast(Addr, ElemTy); + llvm::Type *ElemTy = + CGF.ConvertTypeForMem(E->getType()->getPointeeType()); + Addr = Addr.withElementType(ElemTy); if (CE->getCastKind() == CK_AddressSpaceConversion) - Addr = Builder.CreateAddrSpaceCast(Addr, ConvertType(E->getType())); + Addr = CGF.Builder.CreateAddrSpaceCast(Addr, + CGF.ConvertType(E->getType())); return Addr; } break; // Array-to-pointer decay. case CK_ArrayToPointerDecay: - return EmitArrayToPointerDecay(CE->getSubExpr(), BaseInfo, TBAAInfo); + return CGF.EmitArrayToPointerDecay(CE->getSubExpr(), BaseInfo, TBAAInfo); // Derived-to-base conversions. case CK_UncheckedDerivedToBase: @@ -1112,13 +1108,15 @@ Address CodeGenFunction::EmitPointerWithAlignment(const Expr *E, // conservatively pretend that the complete object is of the base class // type. if (TBAAInfo) - *TBAAInfo = CGM.getTBAAAccessInfo(E->getType()); - Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), BaseInfo); + *TBAAInfo = CGF.CGM.getTBAAAccessInfo(E->getType()); + Address Addr = CGF.EmitPointerWithAlignment( + CE->getSubExpr(), BaseInfo, nullptr, + (KnownNonNull_t)(IsKnownNonNull || + CE->getCastKind() == CK_UncheckedDerivedToBase)); auto Derived = CE->getSubExpr()->getType()->getPointeeCXXRecordDecl(); - return GetAddressOfBaseClass(Addr, Derived, - CE->path_begin(), CE->path_end(), - ShouldNullCheckClassCastValue(CE), - CE->getExprLoc()); + return CGF.GetAddressOfBaseClass( + Addr, Derived, CE->path_begin(), CE->path_end(), + CGF.ShouldNullCheckClassCastValue(CE), CE->getExprLoc()); } // TODO: Is there any reason to treat base-to-derived conversions @@ -1131,10 +1129,10 @@ Address CodeGenFunction::EmitPointerWithAlignment(const Expr *E, // Unary &. if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) { if (UO->getOpcode() == UO_AddrOf) { - LValue LV = EmitLValue(UO->getSubExpr()); + LValue LV = CGF.EmitLValue(UO->getSubExpr(), IsKnownNonNull); if (BaseInfo) *BaseInfo = LV.getBaseInfo(); if (TBAAInfo) *TBAAInfo = LV.getTBAAInfo(); - return LV.getAddress(*this); + return LV.getAddress(CGF); } } @@ -1146,10 +1144,10 @@ Address CodeGenFunction::EmitPointerWithAlignment(const Expr *E, case Builtin::BIaddressof: case Builtin::BI__addressof: case Builtin::BI__builtin_addressof: { - LValue LV = EmitLValue(Call->getArg(0)); + LValue LV = CGF.EmitLValue(Call->getArg(0), IsKnownNonNull); if (BaseInfo) *BaseInfo = LV.getBaseInfo(); if (TBAAInfo) *TBAAInfo = LV.getTBAAInfo(); - return LV.getAddress(*this); + return LV.getAddress(CGF); } } } @@ -1158,9 +1156,21 @@ Address CodeGenFunction::EmitPointerWithAlignment(const Expr *E, // Otherwise, use the alignment of the type. CharUnits Align = - CGM.getNaturalPointeeTypeAlignment(E->getType(), BaseInfo, TBAAInfo); - llvm::Type *ElemTy = ConvertTypeForMem(E->getType()->getPointeeType()); - return Address(EmitScalarExpr(E), ElemTy, Align); + CGF.CGM.getNaturalPointeeTypeAlignment(E->getType(), BaseInfo, TBAAInfo); + llvm::Type *ElemTy = CGF.ConvertTypeForMem(E->getType()->getPointeeType()); + return Address(CGF.EmitScalarExpr(E), ElemTy, Align, IsKnownNonNull); +} + +/// EmitPointerWithAlignment - Given an expression of pointer type, try to +/// derive a more accurate bound on the alignment of the pointer. +Address CodeGenFunction::EmitPointerWithAlignment( + const Expr *E, LValueBaseInfo *BaseInfo, TBAAAccessInfo *TBAAInfo, + KnownNonNull_t IsKnownNonNull) { + Address Addr = + ::EmitPointerWithAlignment(E, BaseInfo, TBAAInfo, IsKnownNonNull, *this); + if (IsKnownNonNull && !Addr.isKnownNonNull()) + Addr.setKnownNonNull(); + return Addr; } llvm::Value *CodeGenFunction::EmitNonNullRValueCheck(RValue RV, QualType T) { @@ -1270,7 +1280,16 @@ LValue CodeGenFunction::EmitCheckedLValue(const Expr *E, TypeCheckKind TCK) { /// type of the same size of the lvalue's type. If the lvalue has a variable /// length type, this is not possible. /// -LValue CodeGenFunction::EmitLValue(const Expr *E) { +LValue CodeGenFunction::EmitLValue(const Expr *E, + KnownNonNull_t IsKnownNonNull) { + LValue LV = EmitLValueHelper(E, IsKnownNonNull); + if (IsKnownNonNull && !LV.isKnownNonNull()) + LV.setKnownNonNull(); + return LV; +} + +LValue CodeGenFunction::EmitLValueHelper(const Expr *E, + KnownNonNull_t IsKnownNonNull) { ApplyDebugLocation DL(*this, E); switch (E->getStmtClass()) { default: return EmitUnsupportedLValue(E, "l-value expression"); @@ -1298,7 +1317,8 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) { case Expr::UserDefinedLiteralClass: return EmitCallExprLValue(cast<CallExpr>(E)); case Expr::CXXRewrittenBinaryOperatorClass: - return EmitLValue(cast<CXXRewrittenBinaryOperator>(E)->getSemanticForm()); + return EmitLValue(cast<CXXRewrittenBinaryOperator>(E)->getSemanticForm(), + IsKnownNonNull); case Expr::VAArgExprClass: return EmitVAArgExprLValue(cast<VAArgExpr>(E)); case Expr::DeclRefExprClass: @@ -1311,12 +1331,13 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) { ->getPointeeType(); return MakeNaturalAlignAddrLValue(Result, RetType); } - return EmitLValue(cast<ConstantExpr>(E)->getSubExpr()); + return EmitLValue(cast<ConstantExpr>(E)->getSubExpr(), IsKnownNonNull); } case Expr::ParenExprClass: - return EmitLValue(cast<ParenExpr>(E)->getSubExpr()); + return EmitLValue(cast<ParenExpr>(E)->getSubExpr(), IsKnownNonNull); case Expr::GenericSelectionExprClass: - return EmitLValue(cast<GenericSelectionExpr>(E)->getResultExpr()); + return EmitLValue(cast<GenericSelectionExpr>(E)->getResultExpr(), + IsKnownNonNull); case Expr::PredefinedExprClass: return EmitPredefinedLValue(cast<PredefinedExpr>(E)); case Expr::StringLiteralClass: @@ -1340,15 +1361,16 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) { case Expr::ExprWithCleanupsClass: { const auto *cleanups = cast<ExprWithCleanups>(E); RunCleanupsScope Scope(*this); - LValue LV = EmitLValue(cleanups->getSubExpr()); + LValue LV = EmitLValue(cleanups->getSubExpr(), IsKnownNonNull); if (LV.isSimple()) { // Defend against branches out of gnu statement expressions surrounded by // cleanups. Address Addr = LV.getAddress(*this); llvm::Value *V = Addr.getPointer(); Scope.ForceCleanup({&V}); - return LValue::MakeAddr(Addr.withPointer(V), LV.getType(), getContext(), - LV.getBaseInfo(), LV.getTBAAInfo()); + return LValue::MakeAddr(Addr.withPointer(V, Addr.isKnownNonNull()), + LV.getType(), getContext(), LV.getBaseInfo(), + LV.getTBAAInfo()); } // FIXME: Is it possible to create an ExprWithCleanups that produces a // bitfield lvalue or some other non-simple lvalue? @@ -1358,12 +1380,12 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) { case Expr::CXXDefaultArgExprClass: { auto *DAE = cast<CXXDefaultArgExpr>(E); CXXDefaultArgExprScope Scope(*this, DAE); - return EmitLValue(DAE->getExpr()); + return EmitLValue(DAE->getExpr(), IsKnownNonNull); } case Expr::CXXDefaultInitExprClass: { auto *DIE = cast<CXXDefaultInitExpr>(E); CXXDefaultInitExprScope Scope(*this, DIE); - return EmitLValue(DIE->getExpr()); + return EmitLValue(DIE->getExpr(), IsKnownNonNull); } case Expr::CXXTypeidExprClass: return EmitCXXTypeidLValue(cast<CXXTypeidExpr>(E)); @@ -1395,11 +1417,12 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) { case Expr::BinaryConditionalOperatorClass: return EmitConditionalOperatorLValue(cast<BinaryConditionalOperator>(E)); case Expr::ChooseExprClass: - return EmitLValue(cast<ChooseExpr>(E)->getChosenSubExpr()); + return EmitLValue(cast<ChooseExpr>(E)->getChosenSubExpr(), IsKnownNonNull); case Expr::OpaqueValueExprClass: return EmitOpaqueValueLValue(cast<OpaqueValueExpr>(E)); case Expr::SubstNonTypeTemplateParmExprClass: - return EmitLValue(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement()); + return EmitLValue(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement(), + IsKnownNonNull); case Expr::ImplicitCastExprClass: case Expr::CStyleCastExprClass: case Expr::CXXFunctionalCastExprClass: @@ -1691,7 +1714,8 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile, bool isNontemporal) { if (auto *GV = dyn_cast<llvm::GlobalValue>(Addr.getPointer())) if (GV->isThreadLocal()) - Addr = Addr.withPointer(Builder.CreateThreadLocalAddress(GV)); + Addr = Addr.withPointer(Builder.CreateThreadLocalAddress(GV), + NotKnownNonNull); if (const auto *ClangVecTy = Ty->getAs<VectorType>()) { // Boolean vectors use `iN` as storage type. @@ -1719,10 +1743,9 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile, if (!CGM.getCodeGenOpts().PreserveVec3Type && VTy->getNumElements() == 3) { - // Bitcast to vec4 type. llvm::VectorType *vec4Ty = llvm::FixedVectorType::get(VTy->getElementType(), 4); - Address Cast = Builder.CreateElementBitCast(Addr, vec4Ty, "castToVec4"); + Address Cast = Addr.withElementType(vec4Ty); // Now load value. llvm::Value *V = Builder.CreateLoad(Cast, Volatile, "loadVec4"); @@ -1743,7 +1766,7 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile, if (isNontemporal) { llvm::MDNode *Node = llvm::MDNode::get( Load->getContext(), llvm::ConstantAsMetadata::get(Builder.getInt32(1))); - Load->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); + Load->setMetadata(llvm::LLVMContext::MD_nontemporal, Node); } CGM.DecorateInstructionWithTBAA(Load, TBAAInfo); @@ -1806,7 +1829,7 @@ static Address MaybeConvertMatrixAddress(Address Addr, CodeGenFunction &CGF, auto *VectorTy = llvm::FixedVectorType::get(ArrayTy->getElementType(), ArrayTy->getNumElements()); - return Address(CGF.Builder.CreateElementBitCast(Addr, VectorTy)); + return Addr.withElementType(VectorTy); } auto *VectorTy = dyn_cast<llvm::VectorType>(Addr.getElementType()); if (VectorTy && !IsVector) { @@ -1814,7 +1837,7 @@ static Address MaybeConvertMatrixAddress(Address Addr, CodeGenFunction &CGF, VectorTy->getElementType(), cast<llvm::FixedVectorType>(VectorTy)->getNumElements()); - return Address(CGF.Builder.CreateElementBitCast(Addr, ArrayTy)); + return Addr.withElementType(ArrayTy); } return Addr; @@ -1839,7 +1862,8 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool isInit, bool isNontemporal) { if (auto *GV = dyn_cast<llvm::GlobalValue>(Addr.getPointer())) if (GV->isThreadLocal()) - Addr = Addr.withPointer(Builder.CreateThreadLocalAddress(GV)); + Addr = Addr.withPointer(Builder.CreateThreadLocalAddress(GV), + NotKnownNonNull); llvm::Type *SrcTy = Value->getType(); if (const auto *ClangVecTy = Ty->getAs<VectorType>()) { @@ -1861,7 +1885,7 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr, SrcTy = llvm::FixedVectorType::get(VecTy->getElementType(), 4); } if (Addr.getElementType() != SrcTy) { - Addr = Builder.CreateElementBitCast(Addr, SrcTy, "storetmp"); + Addr = Addr.withElementType(SrcTy); } } } @@ -1881,7 +1905,7 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr, llvm::MDNode *Node = llvm::MDNode::get(Store->getContext(), llvm::ConstantAsMetadata::get(Builder.getInt32(1))); - Store->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); + Store->setMetadata(llvm::LLVMContext::MD_nontemporal, Node); } CGM.DecorateInstructionWithTBAA(Store, TBAAInfo); @@ -2043,9 +2067,7 @@ Address CodeGenFunction::EmitExtVectorElementLValue(LValue LV) { QualType EQT = LV.getType()->castAs<VectorType>()->getElementType(); llvm::Type *VectorElementTy = CGM.getTypes().ConvertType(EQT); - Address CastToPointerElement = - Builder.CreateElementBitCast(VectorAddress, VectorElementTy, - "conv.ptr.element"); + Address CastToPointerElement = VectorAddress.withElementType(VectorElementTy); const llvm::Constant *Elts = LV.getExtVectorElts(); unsigned ix = getAccessedFieldNo(0, Elts); @@ -2488,7 +2510,7 @@ static LValue EmitThreadPrivateVarDeclLValue( Addr = CGF.CGM.getOpenMPRuntime().getAddrOfThreadPrivate(CGF, VD, Addr, Loc); - Addr = CGF.Builder.CreateElementBitCast(Addr, RealVarTy); + Addr = Addr.withElementType(RealVarTy); return CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl); } @@ -2566,7 +2588,7 @@ static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF, return CGF.CGM.getCXXABI().EmitThreadLocalVarDeclLValue(CGF, VD, T); // Check if the variable is marked as declare target with link clause in // device codegen. - if (CGF.getLangOpts().OpenMPIsDevice) { + if (CGF.getLangOpts().OpenMPIsTargetDevice) { Address Addr = emitDeclTargetVarDeclLValue(CGF, VD, T); if (Addr.isValid()) return CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl); @@ -2848,8 +2870,8 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { // Handle threadlocal function locals. if (VD->getTLSKind() != VarDecl::TLS_None) - addr = - addr.withPointer(Builder.CreateThreadLocalAddress(addr.getPointer())); + addr = addr.withPointer( + Builder.CreateThreadLocalAddress(addr.getPointer()), NotKnownNonNull); // Check for OpenMP threadprivate variables. if (getLangOpts().OpenMP && !getLangOpts().OpenMPSimd && @@ -3188,7 +3210,7 @@ enum class CheckRecoverableKind { static CheckRecoverableKind getRecoverableKind(SanitizerMask Kind) { assert(Kind.countPopulation() == 1); - if (Kind == SanitizerKind::Function || Kind == SanitizerKind::Vptr) + if (Kind == SanitizerKind::Vptr) return CheckRecoverableKind::AlwaysRecoverable; else if (Kind == SanitizerKind::Return || Kind == SanitizerKind::Unreachable) return CheckRecoverableKind::Unrecoverable; @@ -3333,7 +3355,7 @@ void CodeGenFunction::EmitCheck( CGM.getDataLayout().getDefaultGlobalsAddressSpace()); InfoPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); CGM.getSanitizerMetadata()->disableSanitizerForGlobal(InfoPtr); - Args.push_back(EmitCastToVoidPtr(InfoPtr)); + Args.push_back(InfoPtr); ArgTypes.push_back(Args.back()->getType()); } @@ -3606,7 +3628,7 @@ Address CodeGenFunction::EmitArrayToPointerDecay(const Expr *E, // If the array type was an incomplete type, we need to make sure // the decay ends up being the right type. llvm::Type *NewTy = ConvertType(E->getType()); - Addr = Builder.CreateElementBitCast(Addr, NewTy); + Addr = Addr.withElementType(NewTy); // Note that VLA pointers are always decayed, so we don't need to do // anything here. @@ -3625,7 +3647,7 @@ Address CodeGenFunction::EmitArrayToPointerDecay(const Expr *E, if (BaseInfo) *BaseInfo = LV.getBaseInfo(); if (TBAAInfo) *TBAAInfo = CGM.getTBAAAccessInfo(EltType); - return Builder.CreateElementBitCast(Addr, ConvertTypeForMem(EltType)); + return Addr.withElementType(ConvertTypeForMem(EltType)); } /// isSimpleArrayDecayOperand - If the specified expr is a simple decay from an @@ -3871,18 +3893,14 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E, // correctly, so we need to cast to i8*. FIXME: is this actually // true? A lot of other things in the fragile ABI would break... llvm::Type *OrigBaseElemTy = Addr.getElementType(); - Addr = Builder.CreateElementBitCast(Addr, Int8Ty); // Do the GEP. CharUnits EltAlign = getArrayElementAlign(Addr.getAlignment(), Idx, InterfaceSize); llvm::Value *EltPtr = - emitArraySubscriptGEP(*this, Addr.getElementType(), Addr.getPointer(), - ScaledIdx, false, SignedIndices, E->getExprLoc()); - Addr = Address(EltPtr, Addr.getElementType(), EltAlign); - - // Cast back. - Addr = Builder.CreateElementBitCast(Addr, OrigBaseElemTy); + emitArraySubscriptGEP(*this, Int8Ty, Addr.getPointer(), ScaledIdx, + false, SignedIndices, E->getExprLoc()); + Addr = Address(EltPtr, OrigBaseElemTy, EltAlign); } else if (const Expr *Array = isSimpleArrayDecayOperand(E->getBase())) { // If this is A[i] where A is an array, the frontend will have decayed the // base to be a ArrayToPointerDecay implicit cast. While correct, it is @@ -3960,7 +3978,7 @@ static Address emitOMPArraySectionBase(CodeGenFunction &CGF, const Expr *Base, // If the array type was an incomplete type, we need to make sure // the decay ends up being the right type. llvm::Type *NewTy = CGF.ConvertType(BaseTy); - Addr = CGF.Builder.CreateElementBitCast(Addr, NewTy); + Addr = Addr.withElementType(NewTy); // Note that VLA pointers are always decayed, so we don't need to do // anything here. @@ -3970,8 +3988,7 @@ static Address emitOMPArraySectionBase(CodeGenFunction &CGF, const Expr *Base, Addr = CGF.Builder.CreateConstArrayGEP(Addr, 0, "arraydecay"); } - return CGF.Builder.CreateElementBitCast(Addr, - CGF.ConvertTypeForMem(ElTy)); + return Addr.withElementType(CGF.ConvertTypeForMem(ElTy)); } LValueBaseInfo TypeBaseInfo; TBAAAccessInfo TypeTBAAInfo; @@ -4067,6 +4084,7 @@ LValue CodeGenFunction::EmitOMPArraySectionExpr(const OMPArraySectionExpr *E, } } else { auto *CAT = C.getAsConstantArrayType(ArrayTy); + assert(CAT && "unexpected type for array initializer"); ConstLength = CAT->getSize(); } if (Length) { @@ -4287,7 +4305,7 @@ static Address emitAddrOfZeroSizeField(CodeGenFunction &CGF, Address Base, CGF.getContext().getFieldOffset(Field)); if (Offset.isZero()) return Base; - Base = CGF.Builder.CreateElementBitCast(Base, CGF.Int8Ty); + Base = Base.withElementType(CGF.Int8Ty); return CGF.Builder.CreateConstInBoundsByteGEP(Base, Offset); } @@ -4375,8 +4393,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, UseVolatile ? Info.VolatileStorageSize : Info.StorageSize; // Get the access type. llvm::Type *FieldIntTy = llvm::Type::getIntNTy(getLLVMContext(), SS); - if (Addr.getElementType() != FieldIntTy) - Addr = Builder.CreateElementBitCast(Addr, FieldIntTy); + Addr = Addr.withElementType(FieldIntTy); if (UseVolatile) { const unsigned VolatileOffset = Info.VolatileStorageOffset.getQuantity(); if (VolatileOffset) @@ -4463,8 +4480,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, } if (FieldType->isReferenceType()) - addr = Builder.CreateElementBitCast( - addr, CGM.getTypes().ConvertTypeForMem(FieldType), field->getName()); + addr = addr.withElementType(CGM.getTypes().ConvertTypeForMem(FieldType)); } else { if (!IsInPreservedAIRegion && (!getDebugInfo() || !rec->hasAttr<BPFPreserveAccessIndexAttr>())) @@ -4489,11 +4505,8 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, } // Make sure that the address is pointing to the right type. This is critical - // for both unions and structs. A union needs a bitcast, a struct element - // will need a bitcast if the LLVM type laid out doesn't match the desired - // type. - addr = Builder.CreateElementBitCast( - addr, CGM.getTypes().ConvertTypeForMem(FieldType), field->getName()); + // for both unions and structs. + addr = addr.withElementType(CGM.getTypes().ConvertTypeForMem(FieldType)); if (field->hasAttr<AnnotateAttr>()) addr = EmitFieldAnnotations(field, addr); @@ -4520,7 +4533,7 @@ CodeGenFunction::EmitLValueForFieldInitialization(LValue Base, // Make sure that the address is pointing to the right type. llvm::Type *llvmType = ConvertTypeForMem(FieldType); - V = Builder.CreateElementBitCast(V, llvmType, Field->getName()); + V = V.withElementType(llvmType); // TODO: Generate TBAA information that describes this access as a structure // member access and not just an access to an object of the field's type. This @@ -4811,7 +4824,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { if (V.isValid()) { llvm::Type *T = ConvertTypeForMem(E->getType()); if (V.getElementType() != T) - LV.setAddress(Builder.CreateElementBitCast(V, T)); + LV.setAddress(V.withElementType(T)); } } return LV; @@ -4870,8 +4883,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { CGM.EmitExplicitCastExprType(CE, this); LValue LV = EmitLValue(E->getSubExpr()); - Address V = Builder.CreateElementBitCast( - LV.getAddress(*this), + Address V = LV.getAddress(*this).withElementType( ConvertTypeForMem(CE->getTypeAsWritten()->getPointeeType())); if (SanOpts.has(SanitizerKind::CFIUnrelatedCast)) @@ -4895,8 +4907,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { } case CK_ObjCObjectLValueCast: { LValue LV = EmitLValue(E->getSubExpr()); - Address V = Builder.CreateElementBitCast(LV.getAddress(*this), - ConvertType(E->getType())); + Address V = LV.getAddress(*this).withElementType(ConvertType(E->getType())); return MakeAddrLValue(V, E->getType(), LV.getBaseInfo(), CGM.getTBAAInfoForSubobject(LV, E->getType())); } @@ -5106,7 +5117,7 @@ CGCallee CodeGenFunction::EmitCallee(const Expr *E) { functionType = ptrType->getPointeeType(); } else { functionType = E->getType(); - calleePtr = EmitLValue(E).getPointer(*this); + calleePtr = EmitLValue(E, KnownNonNull).getPointer(*this); } assert(functionType->isFunctionType()); @@ -5206,8 +5217,8 @@ CodeGenFunction::EmitCXXTypeidLValue(const CXXTypeidExpr *E) { } Address CodeGenFunction::EmitCXXUuidofExpr(const CXXUuidofExpr *E) { - return Builder.CreateElementBitCast(CGM.GetAddrOfMSGuidDecl(E->getGuidDecl()), - ConvertType(E->getType())); + return CGM.GetAddrOfMSGuidDecl(E->getGuidDecl()) + .withElementType(ConvertType(E->getType())); } LValue CodeGenFunction::EmitCXXUuidofLValue(const CXXUuidofExpr *E) { @@ -5308,33 +5319,56 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee const Decl *TargetDecl = OrigCallee.getAbstractInfo().getCalleeDecl().getDecl(); + assert((!isa_and_present<FunctionDecl>(TargetDecl) || + !cast<FunctionDecl>(TargetDecl)->isImmediateFunction()) && + "trying to emit a call to an immediate function"); + CalleeType = getContext().getCanonicalType(CalleeType); auto PointeeType = cast<PointerType>(CalleeType)->getPointeeType(); CGCallee Callee = OrigCallee; - if (getLangOpts().CPlusPlus && SanOpts.has(SanitizerKind::Function) && - (!TargetDecl || !isa<FunctionDecl>(TargetDecl))) { + if (SanOpts.has(SanitizerKind::Function) && + (!TargetDecl || !isa<FunctionDecl>(TargetDecl)) && + !isa<FunctionNoProtoType>(PointeeType)) { if (llvm::Constant *PrefixSig = CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM)) { SanitizerScope SanScope(this); - // Remove any (C++17) exception specifications, to allow calling e.g. a - // noexcept function through a non-noexcept pointer. - auto ProtoTy = - getContext().getFunctionTypeWithExceptionSpec(PointeeType, EST_None); - llvm::Constant *FTRTTIConst = - CGM.GetAddrOfRTTIDescriptor(ProtoTy, /*ForEH=*/true); + auto *TypeHash = getUBSanFunctionTypeHash(PointeeType); + llvm::Type *PrefixSigType = PrefixSig->getType(); llvm::StructType *PrefixStructTy = llvm::StructType::get( CGM.getLLVMContext(), {PrefixSigType, Int32Ty}, /*isPacked=*/true); llvm::Value *CalleePtr = Callee.getFunctionPointer(); + // On 32-bit Arm, the low bit of a function pointer indicates whether + // it's using the Arm or Thumb instruction set. The actual first + // instruction lives at the same address either way, so we must clear + // that low bit before using the function address to find the prefix + // structure. + // + // This applies to both Arm and Thumb target triples, because + // either one could be used in an interworking context where it + // might be passed function pointers of both types. + llvm::Value *AlignedCalleePtr; + if (CGM.getTriple().isARM() || CGM.getTriple().isThumb()) { + llvm::Value *CalleeAddress = + Builder.CreatePtrToInt(CalleePtr, IntPtrTy); + llvm::Value *Mask = llvm::ConstantInt::get(IntPtrTy, ~1); + llvm::Value *AlignedCalleeAddress = + Builder.CreateAnd(CalleeAddress, Mask); + AlignedCalleePtr = + Builder.CreateIntToPtr(AlignedCalleeAddress, CalleePtr->getType()); + } else { + AlignedCalleePtr = CalleePtr; + } + llvm::Value *CalleePrefixStruct = Builder.CreateBitCast( - CalleePtr, llvm::PointerType::getUnqual(PrefixStructTy)); + AlignedCalleePtr, llvm::PointerType::getUnqual(PrefixStructTy)); llvm::Value *CalleeSigPtr = - Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, 0, 0); + Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, -1, 0); llvm::Value *CalleeSig = Builder.CreateAlignedLoad(PrefixSigType, CalleeSigPtr, getIntAlign()); llvm::Value *CalleeSigMatch = Builder.CreateICmpEQ(CalleeSig, PrefixSig); @@ -5344,19 +5378,17 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee Builder.CreateCondBr(CalleeSigMatch, TypeCheck, Cont); EmitBlock(TypeCheck); - llvm::Value *CalleeRTTIPtr = - Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, 0, 1); - llvm::Value *CalleeRTTIEncoded = - Builder.CreateAlignedLoad(Int32Ty, CalleeRTTIPtr, getPointerAlign()); - llvm::Value *CalleeRTTI = - DecodeAddrUsedInPrologue(CalleePtr, CalleeRTTIEncoded); - llvm::Value *CalleeRTTIMatch = - Builder.CreateICmpEQ(CalleeRTTI, FTRTTIConst); + llvm::Value *CalleeTypeHash = Builder.CreateAlignedLoad( + Int32Ty, + Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, -1, 1), + getPointerAlign()); + llvm::Value *CalleeTypeHashMatch = + Builder.CreateICmpEQ(CalleeTypeHash, TypeHash); llvm::Constant *StaticData[] = {EmitCheckSourceLocation(E->getBeginLoc()), EmitCheckTypeDescriptor(CalleeType)}; - EmitCheck(std::make_pair(CalleeRTTIMatch, SanitizerKind::Function), + EmitCheck(std::make_pair(CalleeTypeHashMatch, SanitizerKind::Function), SanitizerHandler::FunctionTypeMismatch, StaticData, - {CalleePtr, CalleeRTTI, FTRTTIConst}); + {CalleePtr}); Builder.CreateBr(Cont); EmitBlock(Cont); @@ -5549,6 +5581,48 @@ void CodeGenFunction::SetFPAccuracy(llvm::Value *Val, float Accuracy) { cast<llvm::Instruction>(Val)->setMetadata(llvm::LLVMContext::MD_fpmath, Node); } +void CodeGenFunction::SetSqrtFPAccuracy(llvm::Value *Val) { + llvm::Type *EltTy = Val->getType()->getScalarType(); + if (!EltTy->isFloatTy()) + return; + + if ((getLangOpts().OpenCL && + !CGM.getCodeGenOpts().OpenCLCorrectlyRoundedDivSqrt) || + (getLangOpts().HIP && getLangOpts().CUDAIsDevice && + !CGM.getCodeGenOpts().HIPCorrectlyRoundedDivSqrt)) { + // OpenCL v1.1 s7.4: minimum accuracy of single precision / is 3ulp + // + // OpenCL v1.2 s5.6.4.2: The -cl-fp32-correctly-rounded-divide-sqrt + // build option allows an application to specify that single precision + // floating-point divide (x/y and 1/x) and sqrt used in the program + // source are correctly rounded. + // + // TODO: CUDA has a prec-sqrt flag + SetFPAccuracy(Val, 3.0f); + } +} + +void CodeGenFunction::SetDivFPAccuracy(llvm::Value *Val) { + llvm::Type *EltTy = Val->getType()->getScalarType(); + if (!EltTy->isFloatTy()) + return; + + if ((getLangOpts().OpenCL && + !CGM.getCodeGenOpts().OpenCLCorrectlyRoundedDivSqrt) || + (getLangOpts().HIP && getLangOpts().CUDAIsDevice && + !CGM.getCodeGenOpts().HIPCorrectlyRoundedDivSqrt)) { + // OpenCL v1.1 s7.4: minimum accuracy of single precision / is 2.5ulp + // + // OpenCL v1.2 s5.6.4.2: The -cl-fp32-correctly-rounded-divide-sqrt + // build option allows an application to specify that single precision + // floating-point divide (x/y and 1/x) and sqrt used in the program + // source are correctly rounded. + // + // TODO: CUDA has a prec-div flag + SetFPAccuracy(Val, 2.5f); + } +} + namespace { struct LValueOrRValue { LValue LV; |
