ahatanak updated this revision to Diff 492860. ahatanak added a comment. Fix a few typos that were causing compile errors.
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D142584/new/ https://reviews.llvm.org/D142584 Files: clang/lib/CodeGen/Address.h clang/lib/CodeGen/CGBuilder.h clang/lib/CodeGen/CGCall.cpp clang/lib/CodeGen/CGClass.cpp clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CGExprCXX.cpp clang/lib/CodeGen/CGNonTrivialStruct.cpp clang/lib/CodeGen/CGValue.h clang/lib/CodeGen/CodeGenFunction.cpp clang/lib/CodeGen/CodeGenFunction.h
Index: clang/lib/CodeGen/CodeGenFunction.h =================================================================== --- clang/lib/CodeGen/CodeGenFunction.h +++ clang/lib/CodeGen/CodeGenFunction.h @@ -3164,7 +3164,8 @@ Address getIndirectAddress() const { assert(isIndirect()); - return Address(Value, ElementType, CharUnits::fromQuantity(Alignment)); + return Address(Value, ElementType, CharUnits::fromQuantity(Alignment), + KnownNonNull); } }; @@ -3771,8 +3772,13 @@ /// an LLVM type of the same size of the lvalue's type. If the lvalue has a /// variable length type, this is not possible. /// - LValue EmitLValue(const Expr *E); + LValue EmitLValue(const Expr *E, + KnownNonNull_t IsKnownNonNull = NotKnownNonNull); +private: + LValue EmitLValueHelper(const Expr *E, KnownNonNull_t IsKnownNonNull); + +public: /// Same as EmitLValue but additionally we generate checking code to /// guard against undefined behavior. This is only suitable when we know /// that the address will be used to access the object. @@ -4783,9 +4789,10 @@ /// into the address of a local variable. In such a case, it's quite /// reasonable to just ignore the returned alignment when it isn't from an /// explicit source. - Address EmitPointerWithAlignment(const Expr *Addr, - LValueBaseInfo *BaseInfo = nullptr, - TBAAAccessInfo *TBAAInfo = nullptr); + Address + EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo = nullptr, + TBAAAccessInfo *TBAAInfo = nullptr, + KnownNonNull_t IsKnownNonNull = NotKnownNonNull); /// If \p E references a parameter with pass_object_size info or a constant /// array size modifier, emit the object size divided by the size of \p EltTy. Index: clang/lib/CodeGen/CodeGenFunction.cpp =================================================================== --- clang/lib/CodeGen/CodeGenFunction.cpp +++ clang/lib/CodeGen/CodeGenFunction.cpp @@ -1104,8 +1104,9 @@ auto AI = CurFn->arg_begin(); if (CurFnInfo->getReturnInfo().isSRetAfterThis()) ++AI; - ReturnValue = Address(&*AI, ConvertType(RetTy), - CurFnInfo->getReturnInfo().getIndirectAlign()); + ReturnValue = + Address(&*AI, ConvertType(RetTy), + CurFnInfo->getReturnInfo().getIndirectAlign(), KnownNonNull); if (!CurFnInfo->getReturnInfo().getIndirectByVal()) { ReturnValuePointer = CreateDefaultAlignTempAlloca(Int8PtrTy, "result.ptr"); @@ -1125,8 +1126,8 @@ cast<llvm::GetElementPtrInst>(Addr)->getResultElementType(); ReturnValuePointer = Address(Addr, Ty, getPointerAlign()); Addr = Builder.CreateAlignedLoad(Ty, Addr, getPointerAlign(), "agg.result"); - ReturnValue = - Address(Addr, ConvertType(RetTy), CGM.getNaturalTypeAlignment(RetTy)); + ReturnValue = Address(Addr, ConvertType(RetTy), + CGM.getNaturalTypeAlignment(RetTy), KnownNonNull); } else { ReturnValue = CreateIRTemp(RetTy, "retval"); Index: clang/lib/CodeGen/CGValue.h =================================================================== --- clang/lib/CodeGen/CGValue.h +++ clang/lib/CodeGen/CGValue.h @@ -178,7 +178,7 @@ MatrixElt // This is a matrix element, use getVector* } LVType; - llvm::Value *V; + llvm::PointerIntPair<llvm::Value *, 1, bool> V; llvm::Type *ElementType; union { @@ -238,7 +238,7 @@ if (isGlobalReg()) assert(ElementType == nullptr && "Global reg does not store elem type"); else - assert(llvm::cast<llvm::PointerType>(V->getType()) + assert(llvm::cast<llvm::PointerType>(V.getPointer()->getType()) ->isOpaqueOrPointeeTypeMatches(ElementType) && "Pointer element type mismatch"); @@ -333,28 +333,36 @@ LValueBaseInfo getBaseInfo() const { return BaseInfo; } void setBaseInfo(LValueBaseInfo Info) { BaseInfo = Info; } + KnownNonNull_t isKnownNonNull() const { return (KnownNonNull_t)V.getInt(); } + LValue setKnownNonNull() { + V.setInt(true); + return *this; + } + // simple lvalue llvm::Value *getPointer(CodeGenFunction &CGF) const { assert(isSimple()); - return V; + return V.getPointer(); } Address getAddress(CodeGenFunction &CGF) const { - return Address(getPointer(CGF), ElementType, getAlignment()); + return Address(getPointer(CGF), ElementType, getAlignment(), + (KnownNonNull_t)isKnownNonNull()); } void setAddress(Address address) { assert(isSimple()); - V = address.getPointer(); + V = {address.getPointer(), (bool)address.isKnownNonNull()}; ElementType = address.getElementType(); Alignment = address.getAlignment().getQuantity(); } // vector elt lvalue Address getVectorAddress() const { - return Address(getVectorPointer(), ElementType, getAlignment()); + return Address(getVectorPointer(), ElementType, getAlignment(), + (KnownNonNull_t)isKnownNonNull()); } llvm::Value *getVectorPointer() const { assert(isVectorElt()); - return V; + return V.getPointer(); } llvm::Value *getVectorIdx() const { assert(isVectorElt()); @@ -362,11 +370,12 @@ } Address getMatrixAddress() const { - return Address(getMatrixPointer(), ElementType, getAlignment()); + return Address(getMatrixPointer(), ElementType, getAlignment(), + (KnownNonNull_t)isKnownNonNull()); } llvm::Value *getMatrixPointer() const { assert(isMatrixElt()); - return V; + return V.getPointer(); } llvm::Value *getMatrixIdx() const { assert(isMatrixElt()); @@ -375,11 +384,12 @@ // extended vector elements. Address getExtVectorAddress() const { - return Address(getExtVectorPointer(), ElementType, getAlignment()); + return Address(getExtVectorPointer(), ElementType, getAlignment(), + (KnownNonNull_t)isKnownNonNull()); } llvm::Value *getExtVectorPointer() const { assert(isExtVectorElt()); - return V; + return V.getPointer(); } llvm::Constant *getExtVectorElts() const { assert(isExtVectorElt()); @@ -388,16 +398,23 @@ // bitfield lvalue Address getBitFieldAddress() const { - return Address(getBitFieldPointer(), ElementType, getAlignment()); + return Address(getBitFieldPointer(), ElementType, getAlignment(), + (KnownNonNull_t)isKnownNonNull()); + } + llvm::Value *getBitFieldPointer() const { + assert(isBitField()); + return V.getPointer(); } - llvm::Value *getBitFieldPointer() const { assert(isBitField()); return V; } const CGBitFieldInfo &getBitFieldInfo() const { assert(isBitField()); return *BitFieldInfo; } // global register lvalue - llvm::Value *getGlobalReg() const { assert(isGlobalReg()); return V; } + llvm::Value *getGlobalReg() const { + assert(isGlobalReg()); + return V.getPointer(); + } static LValue MakeAddr(Address address, QualType type, ASTContext &Context, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) { @@ -407,7 +424,7 @@ LValue R; R.LVType = Simple; assert(address.getPointer()->getType()->isPointerTy()); - R.V = address.getPointer(); + R.V = {address.getPointer(), (bool)address.isKnownNonNull()}; R.ElementType = address.getElementType(); R.Initialize(type, qs, address.getAlignment(), BaseInfo, TBAAInfo); return R; @@ -418,7 +435,7 @@ TBAAAccessInfo TBAAInfo) { LValue R; R.LVType = VectorElt; - R.V = vecAddress.getPointer(); + R.V = {vecAddress.getPointer(), (bool)vecAddress.isKnownNonNull()}; R.ElementType = vecAddress.getElementType(); R.VectorIdx = Idx; R.Initialize(type, type.getQualifiers(), vecAddress.getAlignment(), @@ -431,7 +448,7 @@ TBAAAccessInfo TBAAInfo) { LValue R; R.LVType = ExtVectorElt; - R.V = vecAddress.getPointer(); + R.V = {vecAddress.getPointer(), (bool)vecAddress.isKnownNonNull()}; R.ElementType = vecAddress.getElementType(); R.VectorElts = Elts; R.Initialize(type, type.getQualifiers(), vecAddress.getAlignment(), @@ -450,7 +467,7 @@ TBAAAccessInfo TBAAInfo) { LValue R; R.LVType = BitField; - R.V = Addr.getPointer(); + R.V = {Addr.getPointer(), (bool)Addr.isKnownNonNull()}; R.ElementType = Addr.getElementType(); R.BitFieldInfo = &Info; R.Initialize(type, type.getQualifiers(), Addr.getAlignment(), BaseInfo, @@ -462,7 +479,7 @@ QualType type) { LValue R; R.LVType = GlobalReg; - R.V = V; + R.V = {V, true}; R.ElementType = nullptr; R.Initialize(type, type.getQualifiers(), alignment, LValueBaseInfo(AlignmentSource::Decl), TBAAAccessInfo()); @@ -474,7 +491,7 @@ TBAAAccessInfo TBAAInfo) { LValue R; R.LVType = MatrixElt; - R.V = matAddress.getPointer(); + R.V = {matAddress.getPointer(), (bool)matAddress.isKnownNonNull()}; R.ElementType = matAddress.getElementType(); R.VectorIdx = Idx; R.Initialize(type, type.getQualifiers(), matAddress.getAlignment(), @@ -579,6 +596,8 @@ Overlap_t mayOverlap, IsZeroed_t isZeroed = IsNotZeroed, IsSanitizerChecked_t isChecked = IsNotSanitizerChecked) { + if (addr.isValid()) + addr.setKnownNonNull(); return AggValueSlot(addr, quals, isDestructed, needsGC, isZeroed, isAliased, mayOverlap, isChecked); } Index: clang/lib/CodeGen/CGNonTrivialStruct.cpp =================================================================== --- clang/lib/CodeGen/CGNonTrivialStruct.cpp +++ clang/lib/CodeGen/CGNonTrivialStruct.cpp @@ -327,7 +327,7 @@ CodeGenFunction *CGF) { return std::array<Address, N>{ {Address(CGF->Builder.CreateLoad(CGF->GetAddrOfLocalVar(Args[Ints])), - CGF->VoidPtrTy, Alignments[Ints])...}}; + CGF->VoidPtrTy, Alignments[Ints], KnownNonNull)...}}; } // Template classes that are used as bases for classes that emit special Index: clang/lib/CodeGen/CGExprCXX.cpp =================================================================== --- clang/lib/CodeGen/CGExprCXX.cpp +++ clang/lib/CodeGen/CGExprCXX.cpp @@ -443,9 +443,9 @@ // Emit the 'this' pointer. Address This = Address::invalid(); if (BO->getOpcode() == BO_PtrMemI) - This = EmitPointerWithAlignment(BaseExpr); + This = EmitPointerWithAlignment(BaseExpr, nullptr, nullptr, KnownNonNull); else - This = EmitLValue(BaseExpr).getAddress(*this); + This = EmitLValue(BaseExpr, KnownNonNull).getAddress(*this); EmitTypeCheck(TCK_MemberCall, E->getExprLoc(), This.getPointer(), QualType(MPT->getClass(), 0)); @@ -2071,6 +2071,7 @@ Builder.CreateCondBr(IsNull, DeleteEnd, DeleteNotNull); EmitBlock(DeleteNotNull); + Ptr.setKnownNonNull(); QualType DeleteTy = E->getDestroyedType(); @@ -2103,7 +2104,8 @@ Ptr = Address(Builder.CreateInBoundsGEP(Ptr.getElementType(), Ptr.getPointer(), GEP, "del.first"), - ConvertTypeForMem(DeleteTy), Ptr.getAlignment()); + ConvertTypeForMem(DeleteTy), Ptr.getAlignment(), + Ptr.isKnownNonNull()); } assert(ConvertTypeForMem(DeleteTy) == Ptr.getElementType()); Index: clang/lib/CodeGen/CGExpr.cpp =================================================================== --- clang/lib/CodeGen/CGExpr.cpp +++ clang/lib/CodeGen/CGExpr.cpp @@ -72,7 +72,7 @@ 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 +102,7 @@ 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 +151,7 @@ Result = Address( Builder.CreateBitCast(Result.getPointer(), VectorTy->getPointerTo()), - VectorTy, Result.getAlignment()); + VectorTy, Result.getAlignment(), KnownNonNull); } return Result; } @@ -1035,11 +1035,10 @@ // 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 +1047,7 @@ // 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 +1060,51 @@ 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 = CGF.Builder.CreateElementBitCast(Addr, 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 +1113,15 @@ // 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 +1134,10 @@ // 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 +1149,10 @@ 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 +1161,21 @@ // 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 +1285,16 @@ /// 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 +1322,8 @@ 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 +1336,13 @@ ->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,7 +1366,7 @@ 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. @@ -1358,12 +1384,12 @@ 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 +1421,12 @@ 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: @@ -5106,7 +5133,7 @@ functionType = ptrType->getPointeeType(); } else { functionType = E->getType(); - calleePtr = EmitLValue(E).getPointer(*this); + calleePtr = EmitLValue(E, KnownNonNull).getPointer(*this); } assert(functionType->isFunctionType()); Index: clang/lib/CodeGen/CGClass.cpp =================================================================== --- clang/lib/CodeGen/CGClass.cpp +++ clang/lib/CodeGen/CGClass.cpp @@ -139,7 +139,7 @@ } llvm::Type *Ty = ConvertType(MD->getThisType()->getPointeeType()); - return Address(LoadCXXThis(), Ty, CXXThisAlignment); + return Address(LoadCXXThis(), Ty, CXXThisAlignment, KnownNonNull); } /// Emit the address of a field using a member data pointer. Index: clang/lib/CodeGen/CGCall.cpp =================================================================== --- clang/lib/CodeGen/CGCall.cpp +++ clang/lib/CodeGen/CGCall.cpp @@ -2805,7 +2805,7 @@ case ABIArgInfo::IndirectAliased: { assert(NumIRArgs == 1); Address ParamAddr = Address(Fn->getArg(FirstIRArg), ConvertTypeForMem(Ty), - ArgI.getIndirectAlign()); + ArgI.getIndirectAlign(), KnownNonNull); if (!hasScalarEvaluationKind(Ty)) { // Aggregates and complex variables are accessed by reference. All we Index: clang/lib/CodeGen/CGBuilder.h =================================================================== --- clang/lib/CodeGen/CGBuilder.h +++ clang/lib/CodeGen/CGBuilder.h @@ -169,7 +169,7 @@ const llvm::Twine &Name = "") { auto *PtrTy = Ty->getPointerTo(Addr.getAddressSpace()); return Address(CreateBitCast(Addr.getPointer(), PtrTy, Name), Ty, - Addr.getAlignment()); + Addr.getAlignment(), Addr.isKnownNonNull()); } using CGBuilderBaseTy::CreatePointerBitCastOrAddrSpaceCast; @@ -178,7 +178,7 @@ const llvm::Twine &Name = "") { llvm::Value *Ptr = CreatePointerBitCastOrAddrSpaceCast(Addr.getPointer(), Ty, Name); - return Address(Ptr, ElementTy, Addr.getAlignment()); + return Address(Ptr, ElementTy, Addr.getAlignment(), Addr.isKnownNonNull()); } /// Given @@ -199,7 +199,7 @@ return Address( CreateStructGEP(Addr.getElementType(), Addr.getPointer(), Index, Name), ElTy->getElementType(Index), - Addr.getAlignment().alignmentAtOffset(Offset)); + Addr.getAlignment().alignmentAtOffset(Offset), Addr.isKnownNonNull()); } /// Given @@ -221,7 +221,8 @@ CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(), {getSize(CharUnits::Zero()), getSize(Index)}, Name), ElTy->getElementType(), - Addr.getAlignment().alignmentAtOffset(Index * EltSize)); + Addr.getAlignment().alignmentAtOffset(Index * EltSize), + Addr.isKnownNonNull()); } /// Given @@ -237,8 +238,8 @@ return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(), getSize(Index), Name), - ElTy, - Addr.getAlignment().alignmentAtOffset(Index * EltSize)); + ElTy, Addr.getAlignment().alignmentAtOffset(Index * EltSize), + Addr.isKnownNonNull()); } /// Given @@ -255,7 +256,8 @@ return Address(CreateGEP(Addr.getElementType(), Addr.getPointer(), getSize(Index), Name), Addr.getElementType(), - Addr.getAlignment().alignmentAtOffset(Index * EltSize)); + Addr.getAlignment().alignmentAtOffset(Index * EltSize), + Addr.isKnownNonNull()); } /// Create GEP with single dynamic index. The address alignment is reduced @@ -270,7 +272,8 @@ return Address( CreateGEP(Addr.getElementType(), Addr.getPointer(), Index, Name), Addr.getElementType(), - Addr.getAlignment().alignmentOfArrayElement(EltSize)); + Addr.getAlignment().alignmentOfArrayElement(EltSize), + Addr.isKnownNonNull()); } /// Given a pointer to i8, adjust it by a given constant offset. @@ -280,7 +283,8 @@ return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(), getSize(Offset), Name), Addr.getElementType(), - Addr.getAlignment().alignmentAtOffset(Offset)); + Addr.getAlignment().alignmentAtOffset(Offset), + Addr.isKnownNonNull()); } Address CreateConstByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name = "") { @@ -288,7 +292,8 @@ return Address(CreateGEP(Addr.getElementType(), Addr.getPointer(), getSize(Offset), Name), Addr.getElementType(), - Addr.getAlignment().alignmentAtOffset(Offset)); + Addr.getAlignment().alignmentAtOffset(Offset), + Addr.isKnownNonNull()); } using CGBuilderBaseTy::CreateConstInBoundsGEP2_32; @@ -305,7 +310,8 @@ llvm_unreachable("offset of GEP with constants is always computable"); return Address(GEP, GEP->getResultElementType(), Addr.getAlignment().alignmentAtOffset( - CharUnits::fromQuantity(Offset.getSExtValue()))); + CharUnits::fromQuantity(Offset.getSExtValue())), + Addr.isKnownNonNull()); } using CGBuilderBaseTy::CreateMemCpy; Index: clang/lib/CodeGen/Address.h =================================================================== --- clang/lib/CodeGen/Address.h +++ clang/lib/CodeGen/Address.h @@ -22,52 +22,67 @@ namespace clang { namespace CodeGen { +// Indicates whether a pointer is known not to be null. +enum KnownNonNull_t { NotKnownNonNull, KnownNonNull }; + // We try to save some space by using 6 bits over two PointerIntPairs to store // the alignment. However, some arches don't support 3 bits in a PointerIntPair // so we fallback to storing the alignment separately. template <typename T, bool = alignof(llvm::Value *) >= 8> class AddressImpl {}; template <typename T> class AddressImpl<T, false> { - llvm::Value *Pointer; + llvm::PointerIntPair<llvm::Value *, 1, bool> PointerAndKnownNonNull; llvm::Type *ElementType; CharUnits Alignment; public: AddressImpl(llvm::Value *Pointer, llvm::Type *ElementType, - CharUnits Alignment) - : Pointer(Pointer), ElementType(ElementType), Alignment(Alignment) {} - llvm::Value *getPointer() const { return Pointer; } + CharUnits Alignment, KnownNonNull_t IsKnownNonNull) + : PointerAndKnownNonNull(Pointer, IsKnownNonNull), + ElementType(ElementType), Alignment(Alignment) {} + llvm::Value *getPointer() const { + return PointerAndKnownNonNull.getPointer(); + } llvm::Type *getElementType() const { return ElementType; } CharUnits getAlignment() const { return Alignment; } + KnownNonNull_t isKnownNonNull() const { + return (KnownNonNull_t)PointerAndKnownNonNull.getInt(); + } + void setKnownNonNull() { PointerAndKnownNonNull.setInt(true); } }; template <typename T> class AddressImpl<T, true> { - // Int portion stores upper 3 bits of the log of the alignment. + // Int portion stores the non-null bit and the upper 2 bits of the log of the + // alignment. llvm::PointerIntPair<llvm::Value *, 3, unsigned> Pointer; // Int portion stores lower 3 bits of the log of the alignment. llvm::PointerIntPair<llvm::Type *, 3, unsigned> ElementType; public: AddressImpl(llvm::Value *Pointer, llvm::Type *ElementType, - CharUnits Alignment) + CharUnits Alignment, KnownNonNull_t IsKnownNonNull) : Pointer(Pointer), ElementType(ElementType) { if (Alignment.isZero()) return; - // Currently the max supported alignment is much less than 1 << 63 and is + // Currently the max supported alignment is much less than 1 << 32 and is // guaranteed to be a power of 2, so we can store the log of the alignment - // into 6 bits. + // into 5 bits. assert(Alignment.isPowerOfTwo() && "Alignment cannot be zero"); auto AlignLog = llvm::Log2_64(Alignment.getQuantity()); - assert(AlignLog < (1 << 6) && "cannot fit alignment into 6 bits"); - this->Pointer.setInt(AlignLog >> 3); + assert(AlignLog < (1 << 5) && "cannot fit alignment into 5 bits"); + this->Pointer.setInt(IsKnownNonNull << 2 | AlignLog >> 3); this->ElementType.setInt(AlignLog & 7); } llvm::Value *getPointer() const { return Pointer.getPointer(); } llvm::Type *getElementType() const { return ElementType.getPointer(); } CharUnits getAlignment() const { - unsigned AlignLog = (Pointer.getInt() << 3) | ElementType.getInt(); + unsigned AlignLog = ((Pointer.getInt() & 0x3) << 3) | ElementType.getInt(); return CharUnits::fromQuantity(CharUnits::QuantityType(1) << AlignLog); } + KnownNonNull_t isKnownNonNull() const { + return (KnownNonNull_t)(!!(Pointer.getInt() & 0x4)); + } + void setKnownNonNull() { Pointer.setInt(Pointer.getInt() | 0x4); } }; /// An aligned address. @@ -75,11 +90,13 @@ AddressImpl<void> A; protected: - Address(std::nullptr_t) : A(nullptr, nullptr, CharUnits::Zero()) {} + Address(std::nullptr_t) + : A(nullptr, nullptr, CharUnits::Zero(), NotKnownNonNull) {} public: - Address(llvm::Value *Pointer, llvm::Type *ElementType, CharUnits Alignment) - : A(Pointer, ElementType, Alignment) { + Address(llvm::Value *Pointer, llvm::Type *ElementType, CharUnits Alignment, + KnownNonNull_t IsKnownNonNull = NotKnownNonNull) + : A(Pointer, ElementType, Alignment, IsKnownNonNull) { assert(Pointer != nullptr && "Pointer cannot be null"); assert(ElementType != nullptr && "Element type cannot be null"); assert(llvm::cast<llvm::PointerType>(Pointer->getType()) @@ -125,7 +142,8 @@ /// Return address with different pointer, but same element type and /// alignment. Address withPointer(llvm::Value *NewPointer) const { - return Address(NewPointer, getElementType(), getAlignment()); + return Address(NewPointer, getElementType(), getAlignment(), + isKnownNonNull()); } /// Return address with different alignment, but same pointer and element @@ -133,6 +151,19 @@ Address withAlignment(CharUnits NewAlignment) const { return Address(getPointer(), getElementType(), NewAlignment); } + + /// Whether the pointer is known not to be null. + KnownNonNull_t isKnownNonNull() const { + assert(isValid()); + return A.isKnownNonNull(); + } + + /// Set the non-null bit. + Address setKnownNonNull() { + assert(isValid()); + A.setKnownNonNull(); + return *this; + } }; /// A specialization of Address that requires the address to be an
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits