From 53907ed5081b6cfde6cbe147ab06a074a4f3e0ed Mon Sep 17 00:00:00 2001 From: Benjamin Maxwell Date: Wed, 25 Sep 2024 09:50:55 +0100 Subject: [clang][codegen] Don't mark "int" TBAA on FP libcalls with indirect args (#108853) On some targets, an FP libcall with argument types such as long double will be lowered to pass arguments indirectly via pointers. When this is the case we should not mark the libcall with "int" TBAA as it may lead to incorrect optimizations. Currently, this can be seen for long doubles on x86_64-w64-mingw32. The `load x86_fp80` after the call is (incorrectly) marked with "int" TBAA (overwriting the previous metadata for "long double"). Nothing seems to break due to this currently as the metadata is being incorrectly placed on the load and not the call. But if the metadata is moved to the call (which this patch ensures), LLVM will optimize out the setup for the arguments. --- clang/lib/CodeGen/CGExpr.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'clang/lib/CodeGen/CGExpr.cpp') diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 35b5daaf6d4b..9166db4c7412 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -5932,7 +5932,8 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Value *Chain, - llvm::CallBase **CallOrInvoke) { + llvm::CallBase **CallOrInvoke, + CGFunctionInfo const **ResolvedFnInfo) { // Get the actual function type. The callee type will always be a pointer to // function type or a block pointer type. assert(CalleeType->isFunctionPointerType() && @@ -6111,6 +6112,9 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeFreeFunctionCall( Args, FnType, /*ChainCall=*/Chain); + if (ResolvedFnInfo) + *ResolvedFnInfo = &FnInfo; + // C99 6.5.2.2p6: // If the expression that denotes the called function has a type // that does not include a prototype, [the default argument -- cgit v1.2.3 From 880ee48d5c9d88be1c611451e84f16eafcebd1a6 Mon Sep 17 00:00:00 2001 From: Youngsuk Kim Date: Fri, 27 Sep 2024 03:07:44 -0400 Subject: [clang][CGExpr] Avoid Type::getPointerTo() (NFC) (#110209) `Type::getPointerTo()` is to be removed soon. This also removes the whole code section for "C99 6.5.2.2p6"; It's essentially a no-op since llvm uses opaque pointers. --- clang/lib/CodeGen/CGExpr.cpp | 41 +++++------------------------------------ 1 file changed, 5 insertions(+), 36 deletions(-) (limited to 'clang/lib/CodeGen/CGExpr.cpp') diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 9166db4c7412..df4994ba9af6 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -122,7 +122,7 @@ RawAddress CodeGenFunction::CreateTempAlloca(llvm::Type *Ty, CharUnits Align, Builder.SetInsertPoint(getPostAllocaInsertPoint()); V = getTargetHooks().performAddrSpaceCast( *this, V, getASTAllocaAddressSpace(), LangAS::Default, - Ty->getPointerTo(DestAddrSpace), /*non-null*/ true); + Builder.getPtrTy(DestAddrSpace), /*non-null*/ true); } return RawAddress(V, Ty, Align, KnownNonNull); @@ -469,7 +469,8 @@ static RawAddress createReferenceTemporary(CodeGenFunction &CGF, if (AS != LangAS::Default) C = TCG.performAddrSpaceCast( CGF.CGM, GV, AS, LangAS::Default, - GV->getValueType()->getPointerTo( + llvm::PointerType::get( + CGF.getLLVMContext(), CGF.getContext().getTargetAddressSpace(LangAS::Default))); // FIXME: Should we put the new global into a COMDAT? return RawAddress(C, GV->getValueType(), alignment); @@ -3207,7 +3208,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { if (AS != T.getAddressSpace()) { auto TargetAS = getContext().getTargetAddressSpace(T.getAddressSpace()); - auto PtrTy = ATPO.getElementType()->getPointerTo(TargetAS); + auto PtrTy = llvm::PointerType::get(CGM.getLLVMContext(), TargetAS); auto ASC = getTargetHooks().performAddrSpaceCast( CGM, ATPO.getPointer(), AS, T.getAddressSpace(), PtrTy); ATPO = ConstantAddress(ASC, ATPO.getElementType(), ATPO.getAlignment()); @@ -3835,9 +3836,7 @@ void CodeGenFunction::EmitCfiCheckFail() { llvm::StructType::get(Int8Ty, SourceLocationTy, VoidPtrTy); llvm::Value *V = Builder.CreateConstGEP2_32( - CfiCheckFailDataTy, - Builder.CreatePointerCast(Data, CfiCheckFailDataTy->getPointerTo(0)), 0, - 0); + CfiCheckFailDataTy, Builder.CreatePointerCast(Data, UnqualPtrTy), 0, 0); Address CheckKindAddr(V, Int8Ty, getIntAlign()); llvm::Value *CheckKind = Builder.CreateLoad(CheckKindAddr); @@ -6115,36 +6114,6 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, if (ResolvedFnInfo) *ResolvedFnInfo = &FnInfo; - // C99 6.5.2.2p6: - // If the expression that denotes the called function has a type - // that does not include a prototype, [the default argument - // promotions are performed]. If the number of arguments does not - // equal the number of parameters, the behavior is undefined. If - // the function is defined with a type that includes a prototype, - // and either the prototype ends with an ellipsis (, ...) or the - // types of the arguments after promotion are not compatible with - // the types of the parameters, the behavior is undefined. If the - // function is defined with a type that does not include a - // prototype, and the types of the arguments after promotion are - // not compatible with those of the parameters after promotion, - // the behavior is undefined [except in some trivial cases]. - // That is, in the general case, we should assume that a call - // through an unprototyped function type works like a *non-variadic* - // call. The way we make this work is to cast to the exact type - // of the promoted arguments. - // - // Chain calls use this same code path to add the invisible chain parameter - // to the function type. - if (isa(FnType) || Chain) { - llvm::Type *CalleeTy = getTypes().GetFunctionType(FnInfo); - int AS = Callee.getFunctionPointer()->getType()->getPointerAddressSpace(); - CalleeTy = CalleeTy->getPointerTo(AS); - - llvm::Value *CalleePtr = Callee.getFunctionPointer(); - CalleePtr = Builder.CreateBitCast(CalleePtr, CalleeTy, "callee.knr.cast"); - Callee.setFunctionPointer(CalleePtr); - } - // HIP function pointer contains kernel handle when it is used in triple // chevron. The kernel stub needs to be loaded from kernel handle and used // as callee. -- cgit v1.2.3 From d8df118545bf0aff3b03d923ca1aa205e7e74f43 Mon Sep 17 00:00:00 2001 From: Sarah Spall Date: Tue, 1 Oct 2024 11:03:37 -0700 Subject: [HLSL] Array by-value assignment (#109323) Make Constant Arrays in HLSL assignable. Closes #109043 --- clang/lib/CodeGen/CGExpr.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'clang/lib/CodeGen/CGExpr.cpp') diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index df4994ba9af6..aaaa4c7cbf2a 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -5797,11 +5797,26 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) { return EmitComplexAssignmentLValue(E); case TEK_Aggregate: + // If the lang opt is HLSL and the LHS is a constant array + // then we are performing a copy assignment and call a special + // function because EmitAggExprToLValue emits to a temporary LValue + if (getLangOpts().HLSL && E->getLHS()->getType()->isConstantArrayType()) + return EmitHLSLArrayAssignLValue(E); + return EmitAggExprToLValue(E); } llvm_unreachable("bad evaluation kind"); } +// This function implements trivial copy assignment for HLSL's +// assignable constant arrays. +LValue CodeGenFunction::EmitHLSLArrayAssignLValue(const BinaryOperator *E) { + LValue TrivialAssignmentRHS = EmitLValue(E->getRHS()); + LValue LHS = EmitLValue(E->getLHS()); + EmitAggregateAssign(LHS, TrivialAssignmentRHS, E->getLHS()->getType()); + return LHS; +} + LValue CodeGenFunction::EmitCallExprLValue(const CallExpr *E, llvm::CallBase **CallOrInvoke) { RValue RV = EmitCallExpr(E, ReturnValueSlot(), CallOrInvoke); -- cgit v1.2.3 From 882457a2eedbe6d53161b2f78fcf769fc9a93e8a Mon Sep 17 00:00:00 2001 From: Jan Hendrik Farr Date: Thu, 3 Oct 2024 07:16:21 +0200 Subject: [Clang] Fix 'counted_by' for nested struct pointers (#110497) Fix counted_by attribute for cases where the flexible array member is accessed through struct pointer inside another struct: ``` struct variable { int a; int b; int length; short array[] __attribute__((counted_by(length))); }; struct bucket { int a; struct variable *growable; int b; }; ``` __builtin_dynamic_object_size(p->growable->array, 0); This commit makes sure that if the StructBase is both a MemberExpr and a pointer, it is treated as a pointer. Otherwise clang will generate to code to access the address of p->growable intead of loading the value of p->growable->length. Fixes #110385 --- clang/lib/CodeGen/CGExpr.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'clang/lib/CodeGen/CGExpr.cpp') diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index aaaa4c7cbf2a..52d2f6d52abf 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1095,6 +1095,8 @@ public: return Visit(E->getBase()); } const Expr *VisitCastExpr(const CastExpr *E) { + if (E->getCastKind() == CK_LValueToRValue) + return E; return Visit(E->getSubExpr()); } const Expr *VisitParenExpr(const ParenExpr *E) { @@ -1161,19 +1163,15 @@ llvm::Value *CodeGenFunction::EmitLoadOfCountedByField( return nullptr; llvm::Value *Res = nullptr; - if (const auto *DRE = dyn_cast(StructBase)) { - Res = EmitDeclRefLValue(DRE).getPointer(*this); - Res = Builder.CreateAlignedLoad(ConvertType(DRE->getType()), Res, - getPointerAlign(), "dre.load"); - } else if (const MemberExpr *ME = dyn_cast(StructBase)) { - LValue LV = EmitMemberExpr(ME); - Address Addr = LV.getAddress(); - Res = Addr.emitRawPointer(*this); - } else if (StructBase->getType()->isPointerType()) { + if (StructBase->getType()->isPointerType()) { LValueBaseInfo BaseInfo; TBAAAccessInfo TBAAInfo; Address Addr = EmitPointerWithAlignment(StructBase, &BaseInfo, &TBAAInfo); Res = Addr.emitRawPointer(*this); + } else if (StructBase->isLValue()) { + LValue LV = EmitLValue(StructBase); + Address Addr = LV.getAddress(); + Res = Addr.emitRawPointer(*this); } else { return nullptr; } -- cgit v1.2.3 From 39ac121309f5c270c8fdc97c45a845542dd78681 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Mon, 7 Oct 2024 22:53:00 +0000 Subject: [Clang] Check that we have the correct RecordDecl (#111448) Ensure we have the correct RecordDecl before returning the Expr we're looking for. --- clang/lib/CodeGen/CGExpr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'clang/lib/CodeGen/CGExpr.cpp') diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 52d2f6d52abf..451442765620 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1096,7 +1096,7 @@ public: } const Expr *VisitCastExpr(const CastExpr *E) { if (E->getCastKind() == CK_LValueToRValue) - return E; + return IsExpectedRecordDecl(E) ? E : nullptr; return Visit(E->getSubExpr()); } const Expr *VisitParenExpr(const ParenExpr *E) { -- cgit v1.2.3 From d079743fe67e05697fe55409115a3614e6fe5c45 Mon Sep 17 00:00:00 2001 From: David Spickett Date: Tue, 8 Oct 2024 15:47:35 +0000 Subject: [clang] Fix comment typos in CodeGen::EmitLoadOfGlobalRegLValue --- clang/lib/CodeGen/CGExpr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'clang/lib/CodeGen/CGExpr.cpp') diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 451442765620..ec54da0a5b25 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -2366,7 +2366,7 @@ Address CodeGenFunction::EmitExtVectorElementLValue(LValue LV) { return VectorBasePtrPlusIx; } -/// Load of global gamed gegisters are always calls to intrinsics. +/// Load of global named registers are always calls to intrinsics. RValue CodeGenFunction::EmitLoadOfGlobalRegLValue(LValue LV) { assert((LV.getType()->isIntegerType() || LV.getType()->isPointerType()) && "Bad type for register variable"); -- cgit v1.2.3