[clang] [clang][c++20] Fix code coverage mapping crash with generalized NTTPs (PR #85837)

2024-05-24 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic closed 
https://github.com/llvm/llvm-project/pull/85837
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][c++20] Fix code coverage mapping crash with generalized NTTPs (PR #85837)

2024-05-24 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic approved this pull request.

LGTM

(In the future, please leave a note on the pull request when you push an 
update; as far as 
I can tell, GitHub doesn't generate a notification when you force-push to the 
branch.)

https://github.com/llvm/llvm-project/pull/85837
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Macro for constant rounding mode (PR #92699)

2024-05-24 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic approved this pull request.

LGTM, but maybe wait a few days to merge in case someone else has comments.

https://github.com/llvm/llvm-project/pull/92699
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Macro for constant rounding mode (PR #92699)

2024-05-24 Thread Eli Friedman via cfe-commits


@@ -965,6 +965,16 @@ void Preprocessor::Lex(Token ) {
   LastTokenWasAt = Result.is(tok::at);
   --LexLevel;
 
+  if (Result.is(tok::l_brace)) {
+CurlyBraceLevel++;
+  } else if (Result.is(tok::r_brace)) {
+if (!RoundingPragmas.empty() &&

efriedma-quic wrote:

Maybe we can move the `!RoundingPragmas.empty()` outside the if statement, so 
we can skip a little more of the code if the user isn't using any pragmas?  I 
mean, it probably doesn't make a big difference, but Lex() is 
performance-sensitive.

https://github.com/llvm/llvm-project/pull/92699
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Macro for constant rounding mode (PR #92699)

2024-05-24 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic commented:

This approach seems much better.

https://github.com/llvm/llvm-project/pull/92699
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Macro for constant rounding mode (PR #92699)

2024-05-24 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic edited 
https://github.com/llvm/llvm-project/pull/92699
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Fix codegen of consteval functions returning an empty class, and related issues (PR #93115)

2024-05-23 Thread Eli Friedman via cfe-commits


@@ -48,10 +48,13 @@ uint8x16x4_t test_vld4q_u8(const uint8_t *addr)
 
 // CHECK-LABEL: @test_vst2q_u32(
 // CHECK-NEXT:  entry:
-// CHECK-NEXT:[[VALUE_COERCE_FCA_0_0_EXTRACT:%.*]] = extractvalue 
[[STRUCT_UINT32X4X2_T:%.*]] [[VALUE_COERCE:%.*]], 0, 0
-// CHECK-NEXT:[[VALUE_COERCE_FCA_0_1_EXTRACT:%.*]] = extractvalue 
[[STRUCT_UINT32X4X2_T]] [[VALUE_COERCE]], 0, 1
-// CHECK-NEXT:call void @llvm.arm.mve.vst2q.p0.v4i32(ptr [[ADDR:%.*]], <4 
x i32> [[VALUE_COERCE_FCA_0_0_EXTRACT]], <4 x i32> 
[[VALUE_COERCE_FCA_0_1_EXTRACT]], i32 0)
-// CHECK-NEXT:call void @llvm.arm.mve.vst2q.p0.v4i32(ptr [[ADDR]], <4 x 
i32> [[VALUE_COERCE_FCA_0_0_EXTRACT]], <4 x i32> 
[[VALUE_COERCE_FCA_0_1_EXTRACT]], i32 1)
+// CHECK-NEXT:[[TMP0:%.*]] = extractvalue [[STRUCT_UINT32X4X2_T:%.*]] 
[[VALUE_COERCE:%.*]], 0

efriedma-quic wrote:

Apparently I've stumbled over some limitation of instcombine.

https://github.com/llvm/llvm-project/pull/93115
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Fix codegen of consteval functions returning an empty class, and related issues (PR #93115)

2024-05-23 Thread Eli Friedman via cfe-commits


@@ -44,20 +44,20 @@ struct S1 f1(struct S1 s1) { return s1; }
 
 // CHECK-SOFT: define{{.*}} void @_Z2f22S2(ptr dead_on_unwind noalias 
nocapture writable writeonly sret(%struct.S2) align 8 %agg.result, [4 x i32] 
%s2.coerce)
 // CHECK-HARD: define{{.*}} arm_aapcs_vfpcc [2 x <2 x i32>] @_Z2f22S2([2 x <2 
x i32>] returned %s2.coerce)
-// CHECK-FULL: define{{.*}} arm_aapcs_vfpcc %struct.S2 @_Z2f22S2(%struct.S2 
returned %s2.coerce)
+// CHECK-FULL: define{{.*}} arm_aapcs_vfpcc %struct.S2 @_Z2f22S2(%struct.S2 
%s2.coerce)

efriedma-quic wrote:

This is also the instcombine issue.

https://github.com/llvm/llvm-project/pull/93115
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Fix codegen of consteval functions returning an empty class, and related issues (PR #93115)

2024-05-23 Thread Eli Friedman via cfe-commits


@@ -46,9 +46,9 @@ int mane() {
 char1 f1{1};
 char1 f2{1};
 
-// CHECK: [[TMP:%.+]] = alloca i16

efriedma-quic wrote:

The revised version of casting integers is a bit more aggressive; it's hard to 
make it precisely match the old code while still preserving the correct 
semantics.

https://github.com/llvm/llvm-project/pull/93115
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Fix codegen of consteval functions returning an empty class, and related issues (PR #93115)

2024-05-23 Thread Eli Friedman via cfe-commits


@@ -177,7 +179,12 @@ kernel void KernelTwoMember(struct StructTwoMember u) {
 // AMDGCN-LABEL: define{{.*}} amdgpu_kernel void @KernelLargeTwoMember
 // AMDGCN-SAME:  (%struct.LargeStructTwoMember %[[u_coerce:.*]])
 // AMDGCN:  %[[u:.*]] = alloca %struct.LargeStructTwoMember, align 8, 
addrspace(5)
-// AMDGCN:  store %struct.LargeStructTwoMember %[[u_coerce]], ptr addrspace(5) 
%[[u]]
+// AMDGCN:  %[[U_PTR0:.*]] = getelementptr inbounds 
%struct.LargeStructTwoMember, ptr addrspace(5) %[[u]], i32 0, i32 0

efriedma-quic wrote:

Unifying the codepaths makes FCA promotion happen more often.

https://github.com/llvm/llvm-project/pull/93115
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Fix codegen of consteval functions returning an empty class, and related issues (PR #93115)

2024-05-23 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic edited 
https://github.com/llvm/llvm-project/pull/93115
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Fix codegen of consteval functions returning an empty class, and related issues (PR #93115)

2024-05-23 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic edited 
https://github.com/llvm/llvm-project/pull/93115
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Fix codegen of consteval functions returning an empty class. (PR #93115)

2024-05-23 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic updated 
https://github.com/llvm/llvm-project/pull/93115

>From 19f3b677d92ed88b825b455d738055da05f91e0d Mon Sep 17 00:00:00 2001
From: Eli Friedman 
Date: Thu, 23 May 2024 18:38:04 -0700
Subject: [PATCH] Fix codegen of consteval functions returning an empty class,
 and related issues

If a class is empty, don't store it to memory: the store might overwrite
useful data.  Similarly, if a class has tail padding that might overlap
other fields, don't store the tail padding to memory.

The problem here turned out a bit more general than I initially thought:
basically all uses of EmitAggregateStore were broken. Call lowering had
a method that did mostly the right thing, though: CreateCoercedStore.
Adapt CreateCoercedStore so it always does the conservatively right
thing, and use it for both calls and ConstantExpr.

Also, along the way, fix the "overlap" bit in AggValueSlot: the bit was
set incorrectly for empty classes in some cases.

Fixes #93040.
---
 clang/lib/CodeGen/CGCall.cpp  | 138 --
 clang/lib/CodeGen/CGExprAgg.cpp   |  23 +--
 clang/lib/CodeGen/CodeGenFunction.h   |   3 +-
 clang/test/CodeGen/arm-mve-intrinsics/vld24.c |  43 --
 clang/test/CodeGen/arm-vfp16-arguments2.cpp   |  10 +-
 .../amdgpu-kernel-arg-pointer-type.cu |  11 +-
 clang/test/CodeGenCUDA/builtins-amdgcn.cu | 121 +++
 .../CodeGenCXX/address-space-cast-coerce.cpp  |   6 +-
 clang/test/CodeGenCXX/cxx2a-consteval.cpp |  24 ++-
 clang/test/CodeGenCXX/trivial_abi.cpp |  20 +++
 clang/test/CodeGenHIP/dpp-const-fold.hip  |   8 +-
 .../CodeGenOpenCL/addr-space-struct-arg.cl|  11 +-
 .../amdgpu-abi-struct-arg-byref.cl|  42 --
 13 files changed, 253 insertions(+), 207 deletions(-)

diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 97449a5e51e73..db6feb4bf1d79 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -1336,75 +1336,54 @@ static llvm::Value *CreateCoercedLoad(Address Src, 
llvm::Type *Ty,
   return CGF.Builder.CreateLoad(Tmp);
 }
 
-// Function to store a first-class aggregate into memory.  We prefer to
-// store the elements rather than the aggregate to be more friendly to
-// fast-isel.
-// FIXME: Do we need to recurse here?
-void CodeGenFunction::EmitAggregateStore(llvm::Value *Val, Address Dest,
- bool DestIsVolatile) {
-  // Prefer scalar stores to first-class aggregate stores.
-  if (llvm::StructType *STy = dyn_cast(Val->getType())) {
-for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
-  Address EltPtr = Builder.CreateStructGEP(Dest, i);
-  llvm::Value *Elt = Builder.CreateExtractValue(Val, i);
-  Builder.CreateStore(Elt, EltPtr, DestIsVolatile);
-}
-  } else {
-Builder.CreateStore(Val, Dest, DestIsVolatile);
-  }
-}
-
 /// CreateCoercedStore - Create a store to \arg DstPtr from \arg Src,
 /// where the source and destination may have different types.  The
 /// destination is known to be aligned to \arg DstAlign bytes.
 ///
 /// This safely handles the case when the src type is larger than the
 /// destination type; the upper bits of the src will be lost.
-static void CreateCoercedStore(llvm::Value *Src,
-   Address Dst,
-   bool DstIsVolatile,
-   CodeGenFunction ) {
-  llvm::Type *SrcTy = Src->getType();
-  llvm::Type *DstTy = Dst.getElementType();
-  if (SrcTy == DstTy) {
-CGF.Builder.CreateStore(Src, Dst, DstIsVolatile);
-return;
-  }
-
-  llvm::TypeSize SrcSize = CGF.CGM.getDataLayout().getTypeAllocSize(SrcTy);
-
-  if (llvm::StructType *DstSTy = dyn_cast(DstTy)) {
-Dst = EnterStructPointerForCoercedAccess(Dst, DstSTy,
- SrcSize.getFixedValue(), CGF);
-DstTy = Dst.getElementType();
-  }
-
-  llvm::PointerType *SrcPtrTy = llvm::dyn_cast(SrcTy);
-  llvm::PointerType *DstPtrTy = llvm::dyn_cast(DstTy);
-  if (SrcPtrTy && DstPtrTy &&
-  SrcPtrTy->getAddressSpace() != DstPtrTy->getAddressSpace()) {
-Src = CGF.Builder.CreateAddrSpaceCast(Src, DstTy);
-CGF.Builder.CreateStore(Src, Dst, DstIsVolatile);
+void CodeGenFunction::CreateCoercedStore(llvm::Value *Src, Address Dst,
+ llvm::TypeSize DstSize,
+ bool DstIsVolatile) {
+  if (!DstSize)
 return;
-  }
 
-  // If the source and destination are integer or pointer types, just do an
-  // extension or truncation to the desired type.
-  if ((isa(SrcTy) || isa(SrcTy)) &&
-  (isa(DstTy) || isa(DstTy))) {
-Src = CoerceIntOrPtrToIntOrPtr(Src, DstTy, CGF);
-CGF.Builder.CreateStore(Src, Dst, DstIsVolatile);
-return;
+  llvm::Type *SrcTy = Src->getType();
+  llvm::TypeSize SrcSize = CGM.getDataLayout().getTypeAllocSize(SrcTy);
+
+  // GEP into structs to try to 

[clang] [Clang][objectsize] Generate object size calculation for sub-objects (PR #86858)

2024-05-23 Thread Eli Friedman via cfe-commits


@@ -1062,6 +1063,159 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr 
*E, unsigned Type,
   return Builder.CreateSelect(Cmp, Res, ConstantInt::get(ResType, 0, 
IsSigned));
 }
 
+namespace {
+
+class ObjectSizeVisitor
+: public ConstStmtVisitor {
+  bool SkipASE;
+
+public:
+  ObjectSizeVisitor(bool SkipASE = false) : SkipASE(SkipASE) {}
+
+  const Expr *Visit(const Expr *E) {
+return ConstStmtVisitor::Visit(E);
+  }
+
+  const Expr *VisitStmt(const Stmt *S) { return nullptr; }
+
+  const Expr *VisitDeclRefExpr(const DeclRefExpr *E) { return E; }
+  const Expr *VisitMemberExpr(const MemberExpr *E) { return E; }
+  const Expr *VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
+return SkipASE ? Visit(E->getBase()) : E;
+  }
+
+  const Expr *VisitCastExpr(const CastExpr *E) {
+return Visit(E->getSubExpr());
+  }
+  const Expr *VisitParenExpr(const ParenExpr *E) {

efriedma-quic wrote:

`IgnoreParens()` will give you better coverage of things we're supposed to 
treat like parentheses.

https://github.com/llvm/llvm-project/pull/86858
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][objectsize] Generate object size calculation for sub-objects (PR #86858)

2024-05-23 Thread Eli Friedman via cfe-commits


@@ -1052,6 +1053,165 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr 
*E, unsigned Type,
   return Builder.CreateSelect(Cmp, Res, ConstantInt::get(ResType, 0, 
IsSigned));
 }
 
+namespace {
+
+class ObjectSizeVisitor
+: public ConstStmtVisitor {
+  bool SkipASE;
+
+public:
+  ObjectSizeVisitor(bool SkipASE = false) : SkipASE(SkipASE) {}
+
+  const Expr *Visit(const Expr *E) {
+return ConstStmtVisitor::Visit(E);
+  }
+
+  const Expr *VisitStmt(const Stmt *S) { return nullptr; }
+
+  const Expr *VisitDeclRefExpr(const DeclRefExpr *E) { return E; }
+  const Expr *VisitMemberExpr(const MemberExpr *E) { return E; }
+  const Expr *VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
+return SkipASE ? Visit(E->getBase()) : E;
+  }
+
+  const Expr *VisitCastExpr(const CastExpr *E) {
+return Visit(E->getSubExpr());
+  }
+  const Expr *VisitParenExpr(const ParenExpr *E) {
+return Visit(E->getSubExpr());
+  }
+  const Expr *VisitUnaryAddrOf(const clang::UnaryOperator *E) {
+return Visit(E->getSubExpr());
+  }
+  const Expr *VisitUnaryDeref(const clang::UnaryOperator *E) {
+return Visit(E->getSubExpr());
+  }
+};
+
+} // end anonymous namespace
+
+/// getLastDecl - Return the last FieldDecl in the struct.
+static const FieldDecl *getLastDecl(const RecordDecl *RD) {
+  const Decl *LastDecl = nullptr;
+  for (const Decl *D : RD->decls())
+if (isa(D) || isa(D))
+  LastDecl = D;
+
+  if (const auto *LastRD = dyn_cast(LastDecl)) {
+LastDecl = getLastDecl(LastRD);
+  } else if (const auto *LastFD = dyn_cast(LastDecl)) {
+QualType Ty = LastFD->getType();
+if (Ty->isPointerType())
+  Ty = Ty->getPointeeType();
+
+if (const RecordDecl *Rec = Ty->getAsRecordDecl())
+  // The last FieldDecl is a structure. Look into that struct to find its
+  // last FieldDecl.
+  LastDecl = getLastDecl(Rec);
+  }
+
+  return dyn_cast_if_present(LastDecl);
+}
+
+/// tryToCalculateSubObjectSize - It may be possible to calculate the
+/// sub-object size of an array and skip the generation of the llvm.objectsize
+/// intrinsic. This avoids the complication in conveying the sub-object's
+/// information to the backend. This calculation works for an N-dimentional
+/// array.
+llvm::Value *
+CodeGenFunction::tryToCalculateSubObjectSize(const Expr *E, unsigned Type,
+ llvm::IntegerType *ResType) {
+  if ((Type & 0x01) != 1)
+// Only support sub-object calculation.
+return nullptr;
+
+  const Expr *ObjectRef = ObjectSizeVisitor().Visit(E);
+  if (!ObjectRef)
+return nullptr;
+
+  QualType ObjectRefType = ObjectRef->getType();
+  if (ObjectRefType->isPointerType())
+ObjectRefType = ObjectRefType->getPointeeType();
+
+  // Collect the base and index from the array.
+  QualType ObjectBaseRefTy;
+  const Expr *ArrayIdx = nullptr;
+
+  if (const auto *ASE = dyn_cast(ObjectRef)) {
+ArrayIdx = ASE->getIdx()->IgnoreParenImpCasts();
+
+const Expr *ArrayRefBase = ASE->getBase()->IgnoreParenImpCasts();
+if (isa(ArrayRefBase)) {
+  ObjectBaseRefTy = ArrayRefBase->getType();
+  if (ObjectBaseRefTy->isPointerType())
+ObjectBaseRefTy = ObjectBaseRefTy->getPointeeType();
+}
+  }
+
+  ASTContext  = getContext();
+  if (!ArrayIdx || ArrayIdx->HasSideEffects(Ctx))
+return nullptr;
+
+  // Check to see if the Decl is a flexible array member. Processing of the
+  // 'counted_by' attribute is done by now. So we don't have any information on
+  // its size, so return MAX_INT.
+  //
+  // Rerun the visitor to find the base expr: MemberExpr or DeclRefExpr.
+  ObjectRef = ObjectSizeVisitor(true).Visit(ObjectRef);
+  if (!ObjectRef)
+return nullptr;
+
+  if (const auto *ME = dyn_cast(ObjectRef)) {
+if (const auto *FD = dyn_cast(ME->getMemberDecl())) {
+  const LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel =
+  getLangOpts().getStrictFlexArraysLevel();
+  const RecordDecl *OuterRD =
+  FD->getParent()->getOuterLexicalRecordContext();
+  const FieldDecl *LastFD = getLastDecl(OuterRD);
+
+  if (LastFD == FD && Decl::isFlexibleArrayMemberLike(
+  Ctx, FD, FD->getType(), StrictFlexArraysLevel,
+  /*IgnoreTemplateOrMacroSubstitution=*/true))
+return ConstantInt::get(ResType, -1, /*isSigned=*/true);
+}
+  }
+
+  if (ObjectBaseRefTy.isNull()) {
+ObjectBaseRefTy = ObjectRef->getType();
+if (ObjectBaseRefTy->isPointerType())
+  ObjectBaseRefTy = ObjectBaseRefTy->getPointeeType();
+  }
+
+  // Generate the calculation:
+  //
+  // S Object[n_1][n_2]...[n_m]; /* M-dimentional array */
+  //
+  // ObjectRef = Object[n_1]...[n_x]; /* 0 < x < m */
+  // ObjectBaseRef = Object[n_1]...[n_{x-1}];
+  //
+  // ArrayRefSize = sizeof( typeof( ObjectRef ) );
+  // ArrayRefBaseSize = sizeof( typeof( ObjectBaseRef ) );
+  //
+  // Size = ArrayRefSize - 

[clang] [Clang][objectsize] Generate object size calculation for sub-objects (PR #86858)

2024-05-23 Thread Eli Friedman via cfe-commits


@@ -1062,6 +1063,159 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr 
*E, unsigned Type,
   return Builder.CreateSelect(Cmp, Res, ConstantInt::get(ResType, 0, 
IsSigned));
 }
 
+namespace {
+
+class ObjectSizeVisitor
+: public ConstStmtVisitor {
+  bool SkipASE;
+
+public:
+  ObjectSizeVisitor(bool SkipASE = false) : SkipASE(SkipASE) {}
+
+  const Expr *Visit(const Expr *E) {
+return ConstStmtVisitor::Visit(E);
+  }
+
+  const Expr *VisitStmt(const Stmt *S) { return nullptr; }
+
+  const Expr *VisitDeclRefExpr(const DeclRefExpr *E) { return E; }
+  const Expr *VisitMemberExpr(const MemberExpr *E) { return E; }
+  const Expr *VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
+return SkipASE ? Visit(E->getBase()) : E;
+  }
+
+  const Expr *VisitCastExpr(const CastExpr *E) {
+return Visit(E->getSubExpr());

efriedma-quic wrote:

Can we restrict this to specific CastKinds?  I can see why you'd want to look 
through certain casts, but some casts drastically change the meaning of the 
expression.

https://github.com/llvm/llvm-project/pull/86858
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][objectsize] Generate object size calculation for sub-objects (PR #86858)

2024-05-23 Thread Eli Friedman via cfe-commits


@@ -1062,6 +1063,159 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr 
*E, unsigned Type,
   return Builder.CreateSelect(Cmp, Res, ConstantInt::get(ResType, 0, 
IsSigned));
 }
 
+namespace {
+
+class ObjectSizeVisitor
+: public ConstStmtVisitor {
+  bool SkipASE;
+
+public:
+  ObjectSizeVisitor(bool SkipASE = false) : SkipASE(SkipASE) {}
+
+  const Expr *Visit(const Expr *E) {
+return ConstStmtVisitor::Visit(E);
+  }
+
+  const Expr *VisitStmt(const Stmt *S) { return nullptr; }
+
+  const Expr *VisitDeclRefExpr(const DeclRefExpr *E) { return E; }
+  const Expr *VisitMemberExpr(const MemberExpr *E) { return E; }
+  const Expr *VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
+return SkipASE ? Visit(E->getBase()) : E;
+  }
+
+  const Expr *VisitCastExpr(const CastExpr *E) {
+return Visit(E->getSubExpr());
+  }
+  const Expr *VisitParenExpr(const ParenExpr *E) {
+return Visit(E->getSubExpr());
+  }
+  const Expr *VisitUnaryAddrOf(const clang::UnaryOperator *E) {
+return Visit(E->getSubExpr());

efriedma-quic wrote:

For this kind of recursion, it probably makes sense to track whether we're 
looking at an lvalue or an rvalue.  If "x" is an `int*`, `__bdos(x)` is very 
different from `__bdos()`.

https://github.com/llvm/llvm-project/pull/86858
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Fix codegen of consteval functions returning an empty class. (PR #93115)

2024-05-23 Thread Eli Friedman via cfe-commits


@@ -135,6 +135,17 @@ class AggExprEmitter : public StmtVisitor {
 EnsureDest(E->getType());
 
 if (llvm::Value *Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
+  // An empty record can overlap other data (if declared with
+  // no_unique_address); omit the store for such types - as there is no

efriedma-quic wrote:

See what, exactly?  Given the derived class, computing the address of the base 
class doesn't take any instructions, because it's the same address.

https://github.com/llvm/llvm-project/pull/93115
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Fix codegen of consteval functions returning an empty class. (PR #93115)

2024-05-22 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

I didn't think so at first glance... but yes, we do, in certain obscure cases:

```
#include 
struct A { char c; A(); };
struct __attribute((packed)) S  { char a; int x; __attribute((aligned(2))) char 
y; consteval S() : x(1), a(3), y(2) {} };
struct S2 { [[no_unique_address]] S s; [[no_unique_address]] A a; };
static_assert(sizeof(S)==8 && sizeof(S2)==8);
void f2(S2 *s) { new (>s) S; }
```

I'll look into reworking this.

https://github.com/llvm/llvm-project/pull/93115
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Fix codegen of consteval functions returning an empty class. (PR #93115)

2024-05-22 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic created 
https://github.com/llvm/llvm-project/pull/93115

If a class is empty, don't store it to memory: the store might overwrite useful 
data.

(See also d60c3d08.)

Fixes #93040.

>From bdfcc729c309fc5b1092b67d7c3c803c852ae251 Mon Sep 17 00:00:00 2001
From: Eli Friedman 
Date: Wed, 22 May 2024 17:30:41 -0700
Subject: [PATCH] Fix codegen of consteval functions returning an empty class.

If a class is empty, don't store it to memory: the store might overwrite
useful data.

(See also d60c3d08.)

Fixes #93040.
---
 clang/lib/CodeGen/CGExprAgg.cpp   | 11 +++
 clang/test/CodeGenCXX/cxx2a-consteval.cpp | 24 ++-
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index bba00257fd4f0..b1638fa318270 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -135,6 +135,17 @@ class AggExprEmitter : public StmtVisitor {
 EnsureDest(E->getType());
 
 if (llvm::Value *Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
+  // An empty record can overlap other data (if declared with
+  // no_unique_address); omit the store for such types - as there is no
+  // actual data to store.
+  if (CGF.getLangOpts().CPlusPlus) {
+if (const RecordType *RT = E->getType()->getAs()) {
+  CXXRecordDecl *Record = cast(RT->getDecl());
+  if (Record->isEmpty())
+return;
+}
+  }
+
   Address StoreDest = Dest.getAddress();
   // The emitted value is guaranteed to have the same size as the
   // destination but can have a different type. Just do a bitcast in this
diff --git a/clang/test/CodeGenCXX/cxx2a-consteval.cpp 
b/clang/test/CodeGenCXX/cxx2a-consteval.cpp
index 075cab58358ab..5d5a62f9928fe 100644
--- a/clang/test/CodeGenCXX/cxx2a-consteval.cpp
+++ b/clang/test/CodeGenCXX/cxx2a-consteval.cpp
@@ -1,4 +1,3 @@
-// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
 // RUN: %clang_cc1 -emit-llvm %s -std=c++2a -triple x86_64-unknown-linux-gnu 
-o %t.ll
 // RUN: FileCheck -check-prefix=EVAL -input-file=%t.ll %s
 // RUN: FileCheck -check-prefix=EVAL-STATIC -input-file=%t.ll %s
@@ -275,3 +274,26 @@ void f() {
 // EVAL-FN: call void @_ZN7GH821542S3C2Ei
 }
 }
+
+namespace GH93040 {
+struct C { char c = 1; };
+struct Empty { consteval Empty() {} };
+struct Test : C, Empty {
+  [[no_unique_address]] Empty e;
+};
+
+void f() {
+  Test test;
+
+// Make sure we don't overwrite the initialization of c.
+
+// EVAL-FN-LABEL: define {{.*}} void @_ZN7GH930404TestC2Ev
+// EVAL-FN: entry:
+// EVAL-FN-NEXT:  [[THIS_ADDR:%.*]] = alloca ptr, align 8
+// EVAL-FN-NEXT:  store ptr {{.*}}, ptr [[THIS_ADDR]], align 8
+// EVAL-FN-NEXT:  [[THIS:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
+// EVAL-FN-NEXT:  call void @_ZN7GH930401CC2Ev(ptr noundef nonnull align 1 
dereferenceable(1) [[THIS]])
+// EVAL-FN-NEXT:  %0 = getelementptr inbounds i8, ptr [[THIS]], i64 1
+// EVAL-FN-NEXT:  ret void
+}
+}

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix PS "selective" DLL import/export of vtable & typeinfo (PR #92579)

2024-05-22 Thread Eli Friedman via cfe-commits


@@ -1793,6 +1793,37 @@ void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction 
,
 ThisTy, VTT, VTTTy, nullptr);
 }
 
+// Check if any non-inline method has the specified attribute.
+template 
+static bool CXXRecordNonInlineHasAttr(const CXXRecordDecl *RD) {
+  for (const auto *D : RD->noload_decls()) {
+if (const auto *FD = dyn_cast(D)) {
+  if (FD->isInlineSpecified() || FD->doesThisDeclarationHaveABody() ||

efriedma-quic wrote:

It's probably fine to merge as-is, sure; inline functions marked with 
import/export attributes should be pretty rare in any case.

https://github.com/llvm/llvm-project/pull/92579
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][FMV] Allow declaration of function versions in namespaces. (PR #93044)

2024-05-22 Thread Eli Friedman via cfe-commits


@@ -11868,8 +11868,10 @@ static bool CheckMultiVersionFunction(Sema , 
FunctionDecl *NewFD,
 return false;
 
   if (!OldDecl || !OldDecl->getAsFunction() ||
-  OldDecl->getDeclContext()->getRedeclContext() !=
-  NewFD->getDeclContext()->getRedeclContext()) {
+  (OldDecl->getDeclContext()->getRedeclContext() !=
+   NewFD->getDeclContext()->getRedeclContext() &&
+   OldDecl->getDeclContext()->getEnclosingNamespaceContext() !=
+   NewFD->getDeclContext()->getEnclosingNamespaceContext())) {

efriedma-quic wrote:

```suggestion
  !OldDecl->getDeclContext()->getRedeclContext()->Equals(
  NewFD->getDeclContext()->getRedeclContext())) {
```

https://github.com/llvm/llvm-project/pull/93044
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Remove parameter that shouldn't be there (PR #93086)

2024-05-22 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

Looks fine.

https://github.com/llvm/llvm-project/pull/93086
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix PS "selective" DLL import/export of vtable & typeinfo (PR #92579)

2024-05-21 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic edited 
https://github.com/llvm/llvm-project/pull/92579
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix PS "selective" DLL import/export of vtable & typeinfo (PR #92579)

2024-05-21 Thread Eli Friedman via cfe-commits


@@ -1793,6 +1793,37 @@ void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction 
,
 ThisTy, VTT, VTTTy, nullptr);
 }
 
+// Check if any non-inline method has the specified attribute.
+template 
+static bool CXXRecordNonInlineHasAttr(const CXXRecordDecl *RD) {
+  for (const auto *D : RD->noload_decls()) {
+if (const auto *FD = dyn_cast(D)) {
+  if (FD->isInlineSpecified() || FD->doesThisDeclarationHaveABody() ||

efriedma-quic wrote:

"isInlineSpecified()" specifically refers to the keyword.  `isInlined()` is 
what the C++ standard calls an "inlined function", and it includes some other 
stuff: constexpr functions, and functions where the body is written inside the 
class definition.

https://github.com/llvm/llvm-project/pull/92579
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] solve crash due to function overloading. (PR #90255)

2024-05-21 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic closed 
https://github.com/llvm/llvm-project/pull/90255
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix PS "selective" DLL import/export of vtable & typeinfo (PR #92579)

2024-05-21 Thread Eli Friedman via cfe-commits


@@ -1793,6 +1793,37 @@ void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction 
,
 ThisTy, VTT, VTTTy, nullptr);
 }
 
+// Check if any non-inline method has the specified attribute.
+template 
+static bool CXXRecordNonInlineHasAttr(const CXXRecordDecl *RD) {
+  for (const auto *D : RD->noload_decls()) {
+if (const auto *FD = dyn_cast(D)) {
+  if (FD->isInlineSpecified() || FD->doesThisDeclarationHaveABody() ||

efriedma-quic wrote:

Is there some reason you're not using `FD->isInlined()` here?

https://github.com/llvm/llvm-project/pull/92579
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [IR] Avoid creating icmp/fcmp constant expressions (PR #92885)

2024-05-21 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/92885
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][AArch64][SVE] Allow write to SVE vector elements using the subscript operator (PR #91965)

2024-05-21 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/91965
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] add unnamed_addr function attribute (PR #92499)

2024-05-21 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

I think the underlying functionality is pretty clearly useful: identical code 
folding gives significant codesize reductions. In fact, on Windows, the linker 
does this kind of folding automatically by default (despite the fact that it 
isn't standards-compliant).  I imagine if we had this implemented, libc++ would 
want to use it.

https://github.com/llvm/llvm-project/pull/92499
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][NFC] Use ptrmask for vaarg stack alignment (PR #92836)

2024-05-20 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic approved this pull request.

Please don't use "NFC" markings for patches that change the emitted IR, even if 
it doesn't significantly impact the resulting assembly in most cases.

That said, LGTM

https://github.com/llvm/llvm-project/pull/92836
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [CodeGen][AArch64] Added -mno-va-float to skip FP save in variadic functions (PR #92827)

2024-05-20 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

This patch, as proposed, doesn't seem like a good idea: it's very likely to 
miscompile user code without any diagnostic. Are you sure you don't want one of 
the following?

- A soft-float ABI (-mabi=aapcs-soft)
- Completely forbidding the use of floating-point values (-mgeneral-regs-only).
- An optimization that opportunistically skips saving float registers if we can 
prove it isn't necessary. (Not currently implemented, but not something you'd 
add a compiler option for; you'd just make it work automatically.  I can write 
up an outline of how to implement this if you're interested.)

https://github.com/llvm/llvm-project/pull/92827
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] solve crash due to function overloading. (PR #90255)

2024-05-20 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

Bot is unreliable, so copy-pasting:

> ⚠️ We detected that you are using a GitHub private e-mail address to 
> contribute to the repo.
Please turn off [Keep my email addresses 
private](https://github.com/settings/emails) setting in your account.
See [LLVM 
Discourse](https://discourse.llvm.org/t/hidden-emails-on-github-should-we-do-something-about-it)
 for more information.

https://github.com/llvm/llvm-project/pull/90255
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] solve crash due to function overloading. (PR #90255)

2024-05-20 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/90255
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [OpenCL] Fix an infinite loop in builidng AddrSpaceQualType (PR #92612)

2024-05-20 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/92612
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [BPF] Fix linking issues in static map initializers (PR #91310)

2024-05-20 Thread Eli Friedman via cfe-commits


@@ -1950,8 +1950,22 @@ ConstantLValueEmitter::tryEmitBase(const 
APValue::LValueBase ) {
 if (D->hasAttr())
   return CGM.GetWeakRefReference(D).getPointer();
 
-if (auto FD = dyn_cast(D))
-  return CGM.GetAddrOfFunction(FD);
+if (auto FD = dyn_cast(D)) {
+  auto *C = CGM.GetAddrOfFunction(FD);
+
+  // we don't normally emit debug info for extern fns referenced via
+  // variable initialisers; BPF needs it since it generates BTF from
+  // debug info and bpftool demands BTF for every symbol linked
+  if (CGM.getTarget().getTriple().isBPF() && FD->getStorageClass() == 
SC_Extern) {

efriedma-quic wrote:

Current approach seems fine.

> Sema::ActOnEndOfTranslationUnit checks whether a declaration is used (does it 
> mean referenced?)

"Used" in this context corresponds to odr-used in the C++ standard... which is 
stuff that Sema thinks the code generator might need to emit.  In some cases we 
manage to skip actually emitting some declarations due to optimizations.

https://github.com/llvm/llvm-project/pull/91310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Emit lifetime markers for non-aggregate temporary allocas (PR #90849)

2024-05-20 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/90849
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Macro for constant rounding mode (PR #92699)

2024-05-20 Thread Eli Friedman via cfe-commits


@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -emit-llvm -triple i386-linux -Wno-unknown-pragmas %s -o - 
| FileCheck %s

efriedma-quic wrote:

Is there some reason the preprocessor can't parse FENV_ROUND?  Breaking code 
with -save-temps etc. seems bad.

https://github.com/llvm/llvm-project/pull/92699
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Refactor handling of vector subscript expressions (NFC) (PR #92778)

2024-05-20 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/92778
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Macro for constant rounding mode (PR #92699)

2024-05-19 Thread Eli Friedman via cfe-commits


@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -emit-llvm -triple i386-linux -Wno-unknown-pragmas %s -o - 
| FileCheck %s

efriedma-quic wrote:

Since this is a preprocessor testcase, can you just use -E?

https://github.com/llvm/llvm-project/pull/92699
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [OpenCL] Fix an infinite loop in builidng AddrSpaceQualType (PR #92612)

2024-05-18 Thread Eli Friedman via cfe-commits


@@ -3054,6 +3054,13 @@ QualType ASTContext::removeAddrSpaceQualType(QualType T) 
const {
   if (!T.hasAddressSpace())
 return T;
 
+  // For arrays, strip the qualifier off the element type, then reconstruct the
+  // array type
+  if (T.getTypePtr()->isArrayType()) {
+Qualifiers Qualfs;
+return getUnqualifiedArrayType(T, Qualfs);

efriedma-quic wrote:

You need to preserve the non-address-space qualifiers, the same way the code 
after the loop does.  Actually, I'd just recommend restructuring to use the 
existing code, something like:

```
if (T.getTypePtr()->isArrayType()) {
  getUnqualifiedArrayType()
} else {
  while (T.hasAddressSpace()) {
 [...]
  }
}
```


https://github.com/llvm/llvm-project/pull/92612
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [OpenCL] Fix an infinite loop in builidng AddrSpaceQualType (PR #92612)

2024-05-17 Thread Eli Friedman via cfe-commits


@@ -537,8 +537,9 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr, 
llvm::ArrayType *AType,
   elementType.isTriviallyCopyableType(CGF.getContext())) {
 CodeGen::CodeGenModule  = CGF.CGM;
 ConstantEmitter Emitter(CGF);
+Qualifiers Quals;
 QualType GVArrayQTy = CGM.getContext().getAddrSpaceQualType(
-CGM.getContext().removeAddrSpaceQualType(ArrayQTy),
+CGM.getContext().getUnqualifiedArrayType(ArrayQTy, Quals),

efriedma-quic wrote:

Something like that, yes.

https://github.com/llvm/llvm-project/pull/92612
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [OpenCL] Fix an infinite loop in builidng AddrSpaceQualType (PR #92612)

2024-05-17 Thread Eli Friedman via cfe-commits


@@ -537,8 +537,9 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr, 
llvm::ArrayType *AType,
   elementType.isTriviallyCopyableType(CGF.getContext())) {
 CodeGen::CodeGenModule  = CGF.CGM;
 ConstantEmitter Emitter(CGF);
+Qualifiers Quals;
 QualType GVArrayQTy = CGM.getContext().getAddrSpaceQualType(
-CGM.getContext().removeAddrSpaceQualType(ArrayQTy),
+CGM.getContext().getUnqualifiedArrayType(ArrayQTy, Quals),

efriedma-quic wrote:

I see two issues with this fix:

1. It leaves removeAddrSpaceQualType broken for anyone else who tries to use 
it.  Ideally, removeAddrSpaceQualType should do what it says.
2. This drops other qualifiers on the floor; they might be relevant in some 
cases.

https://github.com/llvm/llvm-project/pull/92612
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][AArch64][SVE] Allow write to SVE vector elements using the subscript operator (PR #91965)

2024-05-17 Thread Eli Friedman via cfe-commits


@@ -4180,8 +4180,10 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const 
ArraySubscriptExpr *E,
 
   // If the base is a vector type, then we are forming a vector element lvalue
   // with this subscript.
-  if (E->getBase()->getType()->isVectorType() &&
-  !isa(E->getBase())) {
+  if (QualType BaseTy = E->getBase()->getType();
+  (BaseTy->isVectorType() && !isa(E->getBase())) ||
+  (BaseTy->isBuiltinType() &&
+   BaseTy->getAs()->isSveVLSBuiltinType())) {

efriedma-quic wrote:

In that case, it might make sense to introduce a helper 
Type::isSubscriptableVectorType() helper to types, so we can easily find all 
the places that care about this.

https://github.com/llvm/llvm-project/pull/91965
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] add unnamed_addr function attribute (PR #92499)

2024-05-17 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

If we're going to do this, it should probably also work for constants.

Also, I think I'd prefer to sort out the situation with the C++ standard's 
rules for constant merging before we start extending those rules. See #63628.

https://github.com/llvm/llvm-project/pull/92499
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CodeGen] Support arrays with initializers of 64-bit size (PR #92473)

2024-05-17 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/92473
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][AArch64] Use __clang_arm_builtin_alias for overloaded svreinterpret's (PR #92427)

2024-05-17 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

clang specifically diagnoses always_inline functions.  So for example, say you 
want to write something like:

```
#include 
__attribute__((always_inline, target("+sve")))
static inline void f(void* p) __arm_streaming_compatible {
  *(svuint32_t*)p = svmul_m(svptrue_b32(), *(svuint32_t*)p, *(svuint32_t*)p);
}
//
void g(void* p) __arm_streaming { f(p); }
```

Conceptually, this should be fine, but currently it's an error.  (You can sort 
of approximate it with an `#ifdef __ARM_FEATURE_SVE`, but that's pretty ugly.)

But regardless of the diagnostics, if the user specifies "+sve" on a target 
that doesn't actually have SVE, we could miscompile; for example, if you call a 
versioned function, clang uses the features specified in the caller.

https://github.com/llvm/llvm-project/pull/92427
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CodeGen] Support arrays with initializers of 64-bit size (PR #92473)

2024-05-16 Thread Eli Friedman via cfe-commits


@@ -949,11 +949,11 @@ tryEmitGlobalCompoundLiteral(ConstantEmitter ,
 
 static llvm::Constant *
 EmitArrayConstant(CodeGenModule , llvm::ArrayType *DesiredType,
-  llvm::Type *CommonElementType, unsigned ArrayBound,
+  llvm::Type *CommonElementType, uint64_t ArrayBound,
   SmallVectorImpl ,
   llvm::Constant *Filler) {
   // Figure out how long the initial prefix of non-zero elements is.
-  unsigned NonzeroLength = ArrayBound;
+  uint64_t NonzeroLength = ArrayBound;
   if (Elements.size() < NonzeroLength && Filler->isNullValue())
 NonzeroLength = Elements.size();
   if (NonzeroLength == Elements.size()) {

efriedma-quic wrote:

Do we also need to fix the type of `TrailingZeroes`?

https://github.com/llvm/llvm-project/pull/92473
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [OpenCL] Put constant initializer globals into constant addrspace (PR #90048)

2024-05-16 Thread Eli Friedman via cfe-commits


@@ -535,20 +535,23 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr, 
llvm::ArrayType *AType,
   elementType.isTriviallyCopyableType(CGF.getContext())) {
 CodeGen::CodeGenModule  = CGF.CGM;
 ConstantEmitter Emitter(CGF);
-LangAS AS = ArrayQTy.getAddressSpace();
+QualType GVArrayQTy = CGM.getContext().getAddrSpaceQualType(
+CGM.getContext().removeAddrSpaceQualType(ArrayQTy),

efriedma-quic wrote:

I think it's a bug in removeAddrSpaceQualType(): it needs to special-case 
arrays.  Arrays are weird because qualifiers on the element type also count as 
qualifiers on the type, so getSingleStepDesugaredType() can't remove the sugar 
on arrays.  So it needs to strip the qualifier off the element type, then 
reconstruct the array type.  Maybe it can use 
ASTContext::getUnqualifiedArrayType.

https://github.com/llvm/llvm-project/pull/90048
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][AArch64] Use __clang_arm_builtin_alias for overloaded svreinterpret's (PR #92427)

2024-05-16 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

> Thinking about it a bit more, maybe we can just do some magic to make things 
> work? Say, if you specify `__attribute__((target("sve"))) 
> __arm_streaming_compatible`, and the caller is in streaming mode, allow the 
> call even if the caller doesn't have SVE proper.

Thinking a bit more, this is probably not quite what we want: even if the 
function body itself is streaming compatible, it might call non-streaming 
functions that require SVE.  Maybe spell this something like 
`__attribute__((target("sve-or-streaming"))) __arm_streaming_compatible`.

https://github.com/llvm/llvm-project/pull/92427
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][AArch64] Use __clang_arm_builtin_alias for overloaded svreinterpret's (PR #92427)

2024-05-16 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

The key here is that `__arm_streaming_compatible` is the only way to write code 
that runs in both streaming and non-streaming  mode; outside of 
`__arm_streaming_compatible`, there generally isn't an issue. If you know 
you're not in streaming mode, you can just check directly for SVE/SVE2, and if 
you know you're in streaming mode, you can check directly for SME/SME2.

Thinking about it a bit more, maybe we can just do some magic to make things 
work?  Say, if you specify `__attribute__((target("sve"))) 
__arm_streaming_compatible`, and the caller is in streaming mode, allow the 
call even if the caller doesn't have SVE proper.

https://github.com/llvm/llvm-project/pull/92427
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][AArch64] Use __clang_arm_builtin_alias for overloaded svreinterpret's (PR #92427)

2024-05-16 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic edited 
https://github.com/llvm/llvm-project/pull/92427
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix P2564 handling of variable initializers (PR #89565)

2024-05-16 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

clang already generates certain diagnostics from ExprConstant; expanding the 
set of diagnostics could be reasonable.

Alternatively, we could try to add some sort of cooperation between 
DiagRuntimeBehavior and constant evaluation, to try to avoid having to diagnose 
everything twice: basically, Sema makes a list of constant-evaluated 
expressions it wants to warn about, then if ExprConstant prints a warning if it 
sees one of those expressions.

https://github.com/llvm/llvm-project/pull/89565
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [HLSL] support packoffset in clang codeGen (PR #91999)

2024-05-16 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

> The data layout will insert 4-bytes of padding between the float and the 
> vector because the vector needs to be properly aligned.

You can use `type <{ float, <2 x float>}>` if you need the tightly-packed 
layout.

https://github.com/llvm/llvm-project/pull/91999
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][AArch64] Use __clang_arm_builtin_alias for overloaded svreinterpret's (PR #92427)

2024-05-16 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

However we choose to emit this particular builtin, should we provide a way to 
write a function like this?  Like, the caller has to either support sve, or 
have streaming enabled.  Maybe call it __arm_streaming_compatible_requires_sve.

https://github.com/llvm/llvm-project/pull/92427
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Add __builtin_selectvector and use it for AVX512 intrinsics (PR #91306)

2024-05-16 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

clang already supports `?:` with a vector condition; does this add anything new 
on top of that?

https://github.com/llvm/llvm-project/pull/91306
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Coverage] Handle array decomposition correctly (PR #88881)

2024-05-15 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic closed 
https://github.com/llvm/llvm-project/pull/1
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Coverage] Handle `CoroutineSuspendExpr` correctly (PR #88898)

2024-05-15 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic closed 
https://github.com/llvm/llvm-project/pull/88898
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Coverage] Handle `CoroutineSuspendExpr` correctly (PR #88898)

2024-05-15 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/88898
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Coverage] Handle array decomposition correctly (PR #88881)

2024-05-15 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic approved this pull request.

LGTM.

I'm not completely convinced by your argument here... but let's try to move 
forward and land this and #88898 so we can do the refactor to use isUnique().  
Then we can revisit later if necessary.

https://github.com/llvm/llvm-project/pull/1
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Emit lifetime markers for non-aggregate temporary allocas (PR #90849)

2024-05-15 Thread Eli Friedman via cfe-commits


@@ -1,13 +1,15 @@
-// RUN: %clang_cc1 -emit-llvm -triple arm64-- -o - %s -O0 | FileCheck %s 
--check-prefix=CHECK-O0
-// RUN: %clang_cc1 -emit-llvm -disable-llvm-optzns -triple arm64-- -o - %s -O3 
| FileCheck %s --check-prefix=CHECK-O3
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 4

efriedma-quic wrote:

It looks like the existing checks didn't get regenerated?  Did you modify the 
output of update_cc_test_checks hand?  (Don't do that; someone will regenerate 
the test at some point and destroy your customizations.)

https://github.com/llvm/llvm-project/pull/90849
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [clang][SPIR-V] Add support for AMDGCN flavoured SPIRV (PR #89796)

2024-05-15 Thread Eli Friedman via cfe-commits


@@ -6088,6 +6088,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
   StringRef Prefix =
   llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch());
   if (!Prefix.empty()) {
+if (Prefix == "spv" &&
+getTarget().getTriple().getOS() == llvm::Triple::OSType::AMDHSA)
+  Prefix = "amdgcn";

efriedma-quic wrote:

We can look at it as a followup, sure; the code in its current form seems okay 
for now.

https://github.com/llvm/llvm-project/pull/89796
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [AArch64][SME] Save VG for unwind info when changing streaming-mode (PR #83301)

2024-05-15 Thread Eli Friedman via cfe-commits


@@ -8287,6 +8289,13 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo ,
 
   SDValue InGlue;
   if (RequiresSMChange) {
+
+if (Subtarget->hasSVE()) {

efriedma-quic wrote:

I'm not sure I follow what the issue is... I think we discussed before that we 
want debuggers to be able to unwind the stack even if a function is nounwind.

https://github.com/llvm/llvm-project/pull/83301
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [AArch64][SME] Save VG for unwind info when changing streaming-mode (PR #83301)

2024-05-15 Thread Eli Friedman via cfe-commits


@@ -3768,6 +3768,12 @@ def err_conflicting_attributes_arm_state : Error<
   "conflicting attributes for state '%0'">;
 def err_sme_streaming_cannot_be_multiversioned : Error<
   "streaming function cannot be multi-versioned">;
+def err_sme_streaming_mode_change_no_sve : Error<
+  "function requires a streaming-mode change, unwinding is not possible 
without 'sve'. "
+  "Consider marking this function as 'noexcept' or 
'__attribute__((nothrow))'">;

efriedma-quic wrote:

If we call new functions, they need to be part of the ABI.  If you're happy to 
work with your ABI people to document the new interface, I guess it's not a 
problem.

https://github.com/llvm/llvm-project/pull/83301
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][objectsize] Generate object size calculation for sub-objects (PR #86858)

2024-05-14 Thread Eli Friedman via cfe-commits


@@ -1052,6 +1053,165 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr 
*E, unsigned Type,
   return Builder.CreateSelect(Cmp, Res, ConstantInt::get(ResType, 0, 
IsSigned));
 }
 
+namespace {
+
+class ObjectSizeVisitor
+: public ConstStmtVisitor {
+  bool SkipASE;
+
+public:
+  ObjectSizeVisitor(bool SkipASE = false) : SkipASE(SkipASE) {}
+
+  const Expr *Visit(const Expr *E) {
+return ConstStmtVisitor::Visit(E);
+  }
+
+  const Expr *VisitStmt(const Stmt *S) { return nullptr; }
+
+  const Expr *VisitDeclRefExpr(const DeclRefExpr *E) { return E; }
+  const Expr *VisitMemberExpr(const MemberExpr *E) { return E; }
+  const Expr *VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
+return SkipASE ? Visit(E->getBase()) : E;
+  }
+
+  const Expr *VisitCastExpr(const CastExpr *E) {
+return Visit(E->getSubExpr());
+  }
+  const Expr *VisitParenExpr(const ParenExpr *E) {
+return Visit(E->getSubExpr());
+  }
+  const Expr *VisitUnaryAddrOf(const clang::UnaryOperator *E) {
+return Visit(E->getSubExpr());
+  }
+  const Expr *VisitUnaryDeref(const clang::UnaryOperator *E) {
+return Visit(E->getSubExpr());
+  }
+};
+
+} // end anonymous namespace
+
+/// getLastDecl - Return the last FieldDecl in the struct.
+static const FieldDecl *getLastDecl(const RecordDecl *RD) {
+  const Decl *LastDecl = nullptr;
+  for (const Decl *D : RD->decls())
+if (isa(D) || isa(D))

efriedma-quic wrote:

Why are you visiting RecordDecls?

https://github.com/llvm/llvm-project/pull/86858
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][objectsize] Generate object size calculation for sub-objects (PR #86858)

2024-05-14 Thread Eli Friedman via cfe-commits


@@ -1052,6 +1053,165 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr 
*E, unsigned Type,
   return Builder.CreateSelect(Cmp, Res, ConstantInt::get(ResType, 0, 
IsSigned));
 }
 
+namespace {
+
+class ObjectSizeVisitor
+: public ConstStmtVisitor {
+  bool SkipASE;
+
+public:
+  ObjectSizeVisitor(bool SkipASE = false) : SkipASE(SkipASE) {}
+
+  const Expr *Visit(const Expr *E) {
+return ConstStmtVisitor::Visit(E);
+  }
+
+  const Expr *VisitStmt(const Stmt *S) { return nullptr; }
+
+  const Expr *VisitDeclRefExpr(const DeclRefExpr *E) { return E; }
+  const Expr *VisitMemberExpr(const MemberExpr *E) { return E; }
+  const Expr *VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
+return SkipASE ? Visit(E->getBase()) : E;
+  }
+
+  const Expr *VisitCastExpr(const CastExpr *E) {
+return Visit(E->getSubExpr());
+  }
+  const Expr *VisitParenExpr(const ParenExpr *E) {
+return Visit(E->getSubExpr());
+  }
+  const Expr *VisitUnaryAddrOf(const clang::UnaryOperator *E) {
+return Visit(E->getSubExpr());
+  }
+  const Expr *VisitUnaryDeref(const clang::UnaryOperator *E) {
+return Visit(E->getSubExpr());

efriedma-quic wrote:

This recursion seems too aggressive; if you have __bdos(x), is "x" really 
relevant?

https://github.com/llvm/llvm-project/pull/86858
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][objectsize] Generate object size calculation for sub-objects (PR #86858)

2024-05-14 Thread Eli Friedman via cfe-commits


@@ -1052,6 +1053,165 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr 
*E, unsigned Type,
   return Builder.CreateSelect(Cmp, Res, ConstantInt::get(ResType, 0, 
IsSigned));
 }
 
+namespace {
+
+class ObjectSizeVisitor
+: public ConstStmtVisitor {
+  bool SkipASE;
+
+public:
+  ObjectSizeVisitor(bool SkipASE = false) : SkipASE(SkipASE) {}
+
+  const Expr *Visit(const Expr *E) {
+return ConstStmtVisitor::Visit(E);
+  }
+
+  const Expr *VisitStmt(const Stmt *S) { return nullptr; }
+
+  const Expr *VisitDeclRefExpr(const DeclRefExpr *E) { return E; }
+  const Expr *VisitMemberExpr(const MemberExpr *E) { return E; }
+  const Expr *VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
+return SkipASE ? Visit(E->getBase()) : E;
+  }
+
+  const Expr *VisitCastExpr(const CastExpr *E) {
+return Visit(E->getSubExpr());
+  }
+  const Expr *VisitParenExpr(const ParenExpr *E) {
+return Visit(E->getSubExpr());
+  }
+  const Expr *VisitUnaryAddrOf(const clang::UnaryOperator *E) {
+return Visit(E->getSubExpr());
+  }
+  const Expr *VisitUnaryDeref(const clang::UnaryOperator *E) {
+return Visit(E->getSubExpr());
+  }
+};
+
+} // end anonymous namespace
+
+/// getLastDecl - Return the last FieldDecl in the struct.
+static const FieldDecl *getLastDecl(const RecordDecl *RD) {
+  const Decl *LastDecl = nullptr;
+  for (const Decl *D : RD->decls())
+if (isa(D) || isa(D))
+  LastDecl = D;
+
+  if (const auto *LastRD = dyn_cast(LastDecl)) {
+LastDecl = getLastDecl(LastRD);
+  } else if (const auto *LastFD = dyn_cast(LastDecl)) {
+QualType Ty = LastFD->getType();
+if (Ty->isPointerType())
+  Ty = Ty->getPointeeType();
+
+if (const RecordDecl *Rec = Ty->getAsRecordDecl())
+  // The last FieldDecl is a structure. Look into that struct to find its
+  // last FieldDecl.
+  LastDecl = getLastDecl(Rec);
+  }
+
+  return dyn_cast_if_present(LastDecl);
+}
+
+/// tryToCalculateSubObjectSize - It may be possible to calculate the
+/// sub-object size of an array and skip the generation of the llvm.objectsize
+/// intrinsic. This avoids the complication in conveying the sub-object's
+/// information to the backend. This calculation works for an N-dimentional
+/// array.
+llvm::Value *
+CodeGenFunction::tryToCalculateSubObjectSize(const Expr *E, unsigned Type,
+ llvm::IntegerType *ResType) {
+  if ((Type & 0x01) != 1)
+// Only support sub-object calculation.
+return nullptr;
+
+  const Expr *ObjectRef = ObjectSizeVisitor().Visit(E);
+  if (!ObjectRef)
+return nullptr;
+
+  QualType ObjectRefType = ObjectRef->getType();
+  if (ObjectRefType->isPointerType())
+ObjectRefType = ObjectRefType->getPointeeType();
+
+  // Collect the base and index from the array.
+  QualType ObjectBaseRefTy;
+  const Expr *ArrayIdx = nullptr;
+
+  if (const auto *ASE = dyn_cast(ObjectRef)) {
+ArrayIdx = ASE->getIdx()->IgnoreParenImpCasts();
+
+const Expr *ArrayRefBase = ASE->getBase()->IgnoreParenImpCasts();
+if (isa(ArrayRefBase)) {
+  ObjectBaseRefTy = ArrayRefBase->getType();
+  if (ObjectBaseRefTy->isPointerType())
+ObjectBaseRefTy = ObjectBaseRefTy->getPointeeType();
+}
+  }
+
+  ASTContext  = getContext();
+  if (!ArrayIdx || ArrayIdx->HasSideEffects(Ctx))
+return nullptr;
+
+  // Check to see if the Decl is a flexible array member. Processing of the
+  // 'counted_by' attribute is done by now. So we don't have any information on
+  // its size, so return MAX_INT.
+  //
+  // Rerun the visitor to find the base expr: MemberExpr or DeclRefExpr.
+  ObjectRef = ObjectSizeVisitor(true).Visit(ObjectRef);
+  if (!ObjectRef)
+return nullptr;
+
+  if (const auto *ME = dyn_cast(ObjectRef)) {
+if (const auto *FD = dyn_cast(ME->getMemberDecl())) {
+  const LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel =
+  getLangOpts().getStrictFlexArraysLevel();
+  const RecordDecl *OuterRD =
+  FD->getParent()->getOuterLexicalRecordContext();
+  const FieldDecl *LastFD = getLastDecl(OuterRD);
+
+  if (LastFD == FD && Decl::isFlexibleArrayMemberLike(
+  Ctx, FD, FD->getType(), StrictFlexArraysLevel,
+  /*IgnoreTemplateOrMacroSubstitution=*/true))
+return ConstantInt::get(ResType, -1, /*isSigned=*/true);
+}
+  }
+
+  if (ObjectBaseRefTy.isNull()) {
+ObjectBaseRefTy = ObjectRef->getType();
+if (ObjectBaseRefTy->isPointerType())
+  ObjectBaseRefTy = ObjectBaseRefTy->getPointeeType();
+  }
+
+  // Generate the calculation:
+  //
+  // S Object[n_1][n_2]...[n_m]; /* M-dimentional array */
+  //
+  // ObjectRef = Object[n_1]...[n_x]; /* 0 < x < m */
+  // ObjectBaseRef = Object[n_1]...[n_{x-1}];
+  //
+  // ArrayRefSize = sizeof( typeof( ObjectRef ) );
+  // ArrayRefBaseSize = sizeof( typeof( ObjectBaseRef ) );
+  //
+  // Size = ArrayRefSize - 

[clang] [Clang] Fix incorrect passing of _BitInt args (PR #90741)

2024-05-14 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/90741
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [clang][SPIR-V] Add support for AMDGCN flavoured SPIRV (PR #89796)

2024-05-14 Thread Eli Friedman via cfe-commits


@@ -6088,6 +6088,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
   StringRef Prefix =
   llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch());
   if (!Prefix.empty()) {
+if (Prefix == "spv" &&
+getTarget().getTriple().getOS() == llvm::Triple::OSType::AMDHSA)
+  Prefix = "amdgcn";

efriedma-quic wrote:

If we want to allow this choice to be target-specific, we can just make the 
"IntrinsicPrefix" a property of the TargetInfo, instead of trying to derive it 
directly from the target triple.  The default constructor would derive it from 
the triple, but specific targets could override the field.

I'm more concerned this is going to prevent us from using builtins which shoud 
be usable; do we need to getIntrinsicForClangBuiltin() for both "spv" and 
"amdgcn"?

https://github.com/llvm/llvm-project/pull/89796
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][AArch64][SVE] Allow write to SVE vector elements using the subscript operator (PR #91965)

2024-05-13 Thread Eli Friedman via cfe-commits


@@ -88,3 +88,13 @@ float subscript_float32(svfloat32_t a, size_t b) {
 double subscript_float64(svfloat64_t a, size_t b) {
   return a[b];
 }
+
+// CHECK-LABEL: @subscript_write_float32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[VECINS:%.*]] = insertelement  
[[A:%.*]], float 1.00e+00, i64 [[B:%.*]]
+// CHECK-NEXT:ret  [[VECINS]]
+//
+svfloat32_t subscript_write_float32(svfloat32_t a, size_t b) {
+  a[b] = 1.0f;

efriedma-quic wrote:

Please also add a test for a compound op (`a[b]+=1.f`).

https://github.com/llvm/llvm-project/pull/91965
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][AArch64][SVE] Allow write to SVE vector elements using the subscript operator (PR #91965)

2024-05-13 Thread Eli Friedman via cfe-commits


@@ -4180,8 +4180,10 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const 
ArraySubscriptExpr *E,
 
   // If the base is a vector type, then we are forming a vector element lvalue
   // with this subscript.
-  if (E->getBase()->getType()->isVectorType() &&
-  !isa(E->getBase())) {
+  if (QualType BaseTy = E->getBase()->getType();
+  (BaseTy->isVectorType() && !isa(E->getBase())) ||
+  (BaseTy->isBuiltinType() &&
+   BaseTy->getAs()->isSveVLSBuiltinType())) {

efriedma-quic wrote:

isSizelessVectorType()?

https://github.com/llvm/llvm-project/pull/91965
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [BPF] Fix linking issues in static map initializers (PR #91310)

2024-05-12 Thread Eli Friedman via cfe-commits


@@ -1950,8 +1950,22 @@ ConstantLValueEmitter::tryEmitBase(const 
APValue::LValueBase ) {
 if (D->hasAttr())
   return CGM.GetWeakRefReference(D).getPointer();
 
-if (auto FD = dyn_cast(D))
-  return CGM.GetAddrOfFunction(FD);
+if (auto FD = dyn_cast(D)) {
+  auto *C = CGM.GetAddrOfFunction(FD);
+
+  // we don't normally emit debug info for extern fns referenced via
+  // variable initialisers; BPF needs it since it generates BTF from
+  // debug info and bpftool demands BTF for every symbol linked
+  if (CGM.getTarget().getTriple().isBPF() && FD->getStorageClass() == 
SC_Extern) {

efriedma-quic wrote:

Looking at the code again, I guess the ultimate question is whether we want to 
emit debug info for all external functions/variables, or only 
functions/variables that are actually referenced.

If we want all functions/variables, we want to extend ExternalDeclarations to 
include them.  Maybe put the code in Sema::ActOnFunctionDeclarator, or 
something like that.

If you just want referenced functions/variables, probably the code should be in 
GetAddrOfFunction() (and something similar for variables).

https://github.com/llvm/llvm-project/pull/91310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [X86][vectorcall] Pass built types byval when xmm0~6 exhausted (PR #91846)

2024-05-12 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/91846
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [X86][vectorcall] Pass built types byval when xmm0~6 exhausted (PR #91846)

2024-05-11 Thread Eli Friedman via cfe-commits


@@ -792,7 +792,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, 
CCState ,
 return ABIArgInfo::getDirect();
   return ABIArgInfo::getExpand();
 }
-return getIndirectResult(Ty, /*ByVal=*/false, State);
+return getIndirectResult(Ty, IsVectorCall && Ty->isBuiltinType(), State);

efriedma-quic wrote:

Maybe try to avoid byval overhead:

```
if (IsVectorCall && Ty->isBuiltinType())
  return ABIArgInfo::getDirect();
return getIndirectResult(Ty, /*ByVal=*/false, State);
```

https://github.com/llvm/llvm-project/pull/91846
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix incorrect passing of _BitInt args (PR #90741)

2024-05-10 Thread Eli Friedman via cfe-commits


@@ -0,0 +1,14 @@
+// REQUIRES: arm-registered-target
+// RUN: %clang_cc1 -triple aarch64-none-elf \
+// RUN:   -O2 \
+// RUN:   -emit-llvm -fexperimental-max-bitint-width=1024 -o - %s | FileCheck 
%s

efriedma-quic wrote:

Digging a bit into the history, I found clang/test/CodeGen/ext-int-cc.c .  
Which apparently has broken CHECK-NOT lines.

https://github.com/llvm/llvm-project/pull/90741
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Sema] Fix handling of fields with initializers in nested anonymous unions. (PR #91692)

2024-05-09 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic created 
https://github.com/llvm/llvm-project/pull/91692

Make sure we count the anonymous union as an initialized field, so we properly 
construct the AST.

Included bonus testcase Test3, which shows a remaining gap: an anonymous union 
can contain a partially initialized anonymous struct, and we handle that 
inconsistently.

Fixes #91257

>From 44c9e4b9920ab23db93a8a716695a6e712edcf01 Mon Sep 17 00:00:00 2001
From: Eli Friedman 
Date: Thu, 9 May 2024 19:40:46 -0700
Subject: [PATCH] [Sema] Fix handling of fields with initializers in nested
 anonymous unions.

Make sure we count the anonymous union as an initialized field, so we
properly construct the AST.

Included bonus testcase Test3, which shows a remaining gap: an anonymous
union can contain a partially initialized anonymous struct, and we
handle that inconsistently.

Fixes #91257
---
 clang/lib/Sema/SemaInit.cpp   | 19 +-
 .../test/AST/ast-dump-APValue-anon-union.cpp  |  2 +-
 .../SemaCXX/cxx1y-initializer-aggregates.cpp  | 35 +++
 3 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 7d9eaf6720461..0a3d3ea019b1c 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -813,19 +813,13 @@ InitListChecker::FillInEmptyInitializations(const 
InitializedEntity ,
 
   if (const RecordType *RType = ILE->getType()->getAs()) {
 const RecordDecl *RDecl = RType->getDecl();
-if (RDecl->isUnion() && ILE->getInitializedFieldInUnion())
+if (RDecl->isUnion() && ILE->getInitializedFieldInUnion()) {
   FillInEmptyInitForField(0, ILE->getInitializedFieldInUnion(),
   Entity, ILE, RequiresSecondPass, FillWithNoInit);
-else if (RDecl->isUnion() && isa(RDecl) &&
- cast(RDecl)->hasInClassInitializer()) {
-  for (auto *Field : RDecl->fields()) {
-if (Field->hasInClassInitializer()) {
-  FillInEmptyInitForField(0, Field, Entity, ILE, RequiresSecondPass,
-  FillWithNoInit);
-  break;
-}
-  }
 } else {
+  assert((!RDecl->isUnion() || !isa(RDecl) ||
+  !cast(RDecl)->hasInClassInitializer()) &&
+ "We should have computed initialized fields already");
   // The fields beyond ILE->getNumInits() are default initialized, so in
   // order to leave them uninitialized, the ILE is expanded and the extra
   // fields are then filled with NoInitExpr.
@@ -2163,12 +2157,15 @@ void InitListChecker::CheckStructUnionTypes(
 return;
   for (RecordDecl::field_iterator FieldEnd = RD->field_end();
Field != FieldEnd; ++Field) {
-if (Field->hasInClassInitializer()) {
+if (Field->hasInClassInitializer() ||
+(Field->isAnonymousStructOrUnion() &&
+ Field->getType()->getAsCXXRecordDecl()->hasInClassInitializer())) 
{
   StructuredList->setInitializedFieldInUnion(*Field);
   // FIXME: Actually build a CXXDefaultInitExpr?
   return;
 }
   }
+  llvm_unreachable("Couldn't find in-class initializer");
 }
 
 // Value-initialize the first member of the union that isn't an unnamed
diff --git a/clang/test/AST/ast-dump-APValue-anon-union.cpp 
b/clang/test/AST/ast-dump-APValue-anon-union.cpp
index 0e6466ee1fd73..ffe14ed7322de 100644
--- a/clang/test/AST/ast-dump-APValue-anon-union.cpp
+++ b/clang/test/AST/ast-dump-APValue-anon-union.cpp
@@ -36,7 +36,7 @@ void Test() {
 
   constexpr U0 u0a{};
   // CHECK:  | `-VarDecl {{.*}}  col:{{.*}} u0a 'const 
U0' constexpr listinit
-  // CHECK-NEXT:  |   |-value: Union None
+  // CHECK-NEXT:  |   |-value: Union .U0::(anonymous union at {{.*}}) Union .f 
Float 3.141500e+00
 
   constexpr U0 u0b{3.1415f};
   // CHECK:  | `-VarDecl {{.*}}  col:{{.*}} u0b 'const 
U0' constexpr listinit
diff --git a/clang/test/SemaCXX/cxx1y-initializer-aggregates.cpp 
b/clang/test/SemaCXX/cxx1y-initializer-aggregates.cpp
index 3d5e7726a17e5..ca60cf513b4a2 100644
--- a/clang/test/SemaCXX/cxx1y-initializer-aggregates.cpp
+++ b/clang/test/SemaCXX/cxx1y-initializer-aggregates.cpp
@@ -77,3 +77,38 @@ namespace use_self {
 
   int fib(int n) { return FibTree{n}.v; }
 }
+
+namespace nested_union {
+  union Test1 {
+union {
+  int inner { 42 };
+};
+int outer;
+  };
+  static_assert(Test1{}.inner == 42, "");
+  struct Test2 {
+union {
+  struct {
+int inner : 32 { 42 }; // expected-warning {{C++20 extension}}
+  };
+  int outer;
+};
+  };
+  static_assert(Test2{}.inner == 42, "");
+  struct Int { int x; };
+  struct Test3 {
+int x;
+union {
+  struct {
+const int& y;
+int inner : 32 { 42 }; // expected-warning {{C++20 extension}}
+  };
+  int outer;
+};
+  };
+  constexpr char f(Test3) { return 1; } // expected-note {{candidate function}}
+  constexpr char f(Int) { return 

[clang] [Clang] Fix incorrect passing of _BitInt args (PR #90741)

2024-05-09 Thread Eli Friedman via cfe-commits


@@ -0,0 +1,14 @@
+// REQUIRES: arm-registered-target
+// RUN: %clang_cc1 -triple aarch64-none-elf \
+// RUN:   -O2 \
+// RUN:   -emit-llvm -fexperimental-max-bitint-width=1024 -o - %s | FileCheck 
%s

efriedma-quic wrote:

Can we integrate this into some existing test file for aarch64 calling 
conventions?

https://github.com/llvm/llvm-project/pull/90741
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [AArch64][SME] Save VG for unwind info when changing streaming-mode (PR #83301)

2024-05-09 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/83301
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][AArch64] Fixed incorrect _BitInt alignment (PR #90602)

2024-05-08 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/90602
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Lower _BitInt(129+) to a different type in LLVM IR (PR #91364)

2024-05-07 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

You're suggesting we should fork ConvertTypeForMem into two functions?  So 
there's actually three types: the "register" type, the "load/store" type, and 
the "in-memory" type.  I guess that makes sense from a theoretical perspective, 
but... as a practical matter, I'm not sure how many places need to call the 
proposed "ConvertTypeForLoadStore".

In EmitLoadOfScalar(), instead of checking for BitInt, you just unconditionally 
do `Addr = Addr.withElementType(ConvertTypeForLoadStore(Ty));`.  Logical 
cleanup, I guess.  In EmitStoreOfScalar, you don't really need the interface 
because you can assume the result of EmitToMemory() has the load/store type.  
And then... what else calls it?

https://github.com/llvm/llvm-project/pull/91364
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [clang][hlsl] Add tan intrinsic part 1 (PR #90276)

2024-05-07 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic approved this pull request.

Okay.  I mostly just want to make sure the plan isn't "land all the intrinsics 
from the RFC, then eventually investigate the constrained intrinsics".

LGTM

https://github.com/llvm/llvm-project/pull/90276
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [clang][hlsl] Add tan intrinsic part 1 (PR #90276)

2024-05-07 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

> I didn't want the current set of changes to go stale.

How many changes are we talking about here?  If it's just the tan() ones, 
that's fine; it probably makes sense to land constrained-tan separately anyway.

https://github.com/llvm/llvm-project/pull/90276
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)

2024-05-07 Thread Eli Friedman via cfe-commits


@@ -529,9 +529,325 @@ bool SystemZTargetCodeGenInfo::isVectorTypeBased(const 
Type *Ty,
   return false;
 }
 
+//===--===//
+// z/OS XPLINK ABI Implementation
+//===--===//
+
+namespace {
+
+class ZOSXPLinkABIInfo : public ABIInfo {
+  static const unsigned GPRBits = 64;
+  bool HasVector;
+
+public:
+  ZOSXPLinkABIInfo(CodeGenTypes , bool HV) : ABIInfo(CGT), HasVector(HV) {}
+
+  bool isPromotableIntegerType(QualType Ty) const;
+  bool isCompoundType(QualType Ty) const;
+  bool isVectorArgumentType(QualType Ty) const;
+  bool isFPArgumentType(QualType Ty) const;
+  QualType GetSingleElementType(QualType Ty) const;
+  bool IsLikeComplexType(QualType Ty) const;
+
+  ABIArgInfo classifyReturnType(QualType RetTy) const;
+  ABIArgInfo classifyArgumentType(QualType ArgTy, bool IsNamedArg) const;
+
+  void computeInfo(CGFunctionInfo ) const override {
+if (!getCXXABI().classifyReturnType(FI))
+  FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+
+unsigned NumRequiredArgs = FI.getNumRequiredArgs();
+unsigned ArgNo = 0;
+
+for (auto  : FI.arguments()) {
+  bool IsNamedArg = ArgNo < NumRequiredArgs;
+  I.info = classifyArgumentType(I.type, IsNamedArg);
+  ++ArgNo;
+}
+  }
+
+  Address EmitVAArg(CodeGenFunction , Address VAListAddr,
+QualType Ty) const override;
+};
+
+class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  ZOSXPLinkTargetCodeGenInfo(CodeGenTypes , bool HasVector)
+  : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) {
+SwiftInfo =
+std::make_unique(CGT, /*SwiftErrorInRegister=*/false);
+  }
+};
+
+} // namespace
+
+// Return true if the ABI requires Ty to be passed sign- or zero-
+// extended to 64 bits.
+bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const {
+  // Treat an enum type as its underlying type.
+  if (const EnumType *EnumTy = Ty->getAs())
+Ty = EnumTy->getDecl()->getIntegerType();
+
+  // Promotable integer types are required to be promoted by the ABI.
+  if (getContext().isPromotableIntegerType(Ty))
+return true;
+
+  // In addition to the usual promotable integer types, we also need to
+  // extend all 32-bit types, since the ABI requires promotion to 64 bits.
+  if (const BuiltinType *BT = Ty->getAs())
+switch (BT->getKind()) {
+case BuiltinType::Int:
+case BuiltinType::UInt:
+  return true;
+default:
+  break;
+}
+
+  return false;
+}
+
+bool ZOSXPLinkABIInfo::isCompoundType(QualType Ty) const {
+  return (Ty->isAnyComplexType() || Ty->isVectorType() ||
+  isAggregateTypeForABI(Ty));
+}
+
+bool ZOSXPLinkABIInfo::isVectorArgumentType(QualType Ty) const {
+  return (HasVector && Ty->isVectorType() &&
+  getContext().getTypeSize(Ty) <= 128);
+}
+
+bool ZOSXPLinkABIInfo::isFPArgumentType(QualType Ty) const {
+  if (const BuiltinType *BT = Ty->getAs())
+switch (BT->getKind()) {
+case BuiltinType::Float:
+case BuiltinType::Double:
+case BuiltinType::LongDouble:
+  return true;
+default:
+  return false;
+}
+
+  return false;
+}
+
+QualType ZOSXPLinkABIInfo::GetSingleElementType(QualType Ty) const {
+  if (const RecordType *RT = Ty->getAsStructureType()) {
+const RecordDecl *RD = RT->getDecl();
+QualType Found;
+
+// If this is a C++ record, check the bases first.
+if (const CXXRecordDecl *CXXRD = dyn_cast(RD))
+  for (const auto  : CXXRD->bases()) {
+QualType Base = I.getType();
+
+// Empty bases don't affect things either way.
+if (isEmptyRecord(getContext(), Base, true))
+  continue;
+
+if (!Found.isNull())
+  return Ty;
+Found = GetSingleElementType(Base);
+  }
+
+// Check the fields.
+for (const auto *FD : RD->fields()) {
+  // For compatibility with GCC, ignore empty bitfields in C++ mode.
+  // Unlike isSingleElementStruct(), empty structure and array fields
+  // do count.  So do anonymous bitfields that aren't zero-sized.
+  if (getContext().getLangOpts().CPlusPlus &&
+  FD->isZeroLengthBitField(getContext()))
+continue;
+
+  // Unlike isSingleElementStruct(), arrays do not count.
+  // Nested structures still do though.
+  if (!Found.isNull())
+return Ty;
+  Found = GetSingleElementType(FD->getType());
+}
+
+// Unlike isSingleElementStruct(), trailing padding is allowed.
+// An 8-byte aligned struct s { float f; } is passed as a double.
+if (!Found.isNull())
+  return Found;
+  }
+
+  return Ty;
+}
+
+bool ZOSXPLinkABIInfo::IsLikeComplexType(QualType Ty) const {
+  if (const RecordType *RT = Ty->getAsStructureType()) {
+const RecordDecl *RD = RT->getDecl();
+int i = 0;
+clang::BuiltinType::Kind elemKind;
+
+// Check for exactly two elements with 

[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)

2024-05-07 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic commented:

At first glance, making a separate ABI seemed weird, but I guess it's pretty 
different from the normal SystemZ ABI.

https://github.com/llvm/llvm-project/pull/91384
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)

2024-05-07 Thread Eli Friedman via cfe-commits


@@ -529,9 +529,325 @@ bool SystemZTargetCodeGenInfo::isVectorTypeBased(const 
Type *Ty,
   return false;
 }
 
+//===--===//
+// z/OS XPLINK ABI Implementation
+//===--===//
+
+namespace {
+
+class ZOSXPLinkABIInfo : public ABIInfo {
+  static const unsigned GPRBits = 64;
+  bool HasVector;
+
+public:
+  ZOSXPLinkABIInfo(CodeGenTypes , bool HV) : ABIInfo(CGT), HasVector(HV) {}
+
+  bool isPromotableIntegerType(QualType Ty) const;
+  bool isCompoundType(QualType Ty) const;
+  bool isVectorArgumentType(QualType Ty) const;
+  bool isFPArgumentType(QualType Ty) const;
+  QualType GetSingleElementType(QualType Ty) const;
+  bool IsLikeComplexType(QualType Ty) const;
+
+  ABIArgInfo classifyReturnType(QualType RetTy) const;
+  ABIArgInfo classifyArgumentType(QualType ArgTy, bool IsNamedArg) const;
+
+  void computeInfo(CGFunctionInfo ) const override {
+if (!getCXXABI().classifyReturnType(FI))
+  FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+
+unsigned NumRequiredArgs = FI.getNumRequiredArgs();
+unsigned ArgNo = 0;
+
+for (auto  : FI.arguments()) {
+  bool IsNamedArg = ArgNo < NumRequiredArgs;
+  I.info = classifyArgumentType(I.type, IsNamedArg);
+  ++ArgNo;
+}
+  }
+
+  Address EmitVAArg(CodeGenFunction , Address VAListAddr,
+QualType Ty) const override;
+};
+
+class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  ZOSXPLinkTargetCodeGenInfo(CodeGenTypes , bool HasVector)
+  : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) {
+SwiftInfo =
+std::make_unique(CGT, /*SwiftErrorInRegister=*/false);
+  }
+};
+
+} // namespace
+
+// Return true if the ABI requires Ty to be passed sign- or zero-
+// extended to 64 bits.
+bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const {
+  // Treat an enum type as its underlying type.
+  if (const EnumType *EnumTy = Ty->getAs())
+Ty = EnumTy->getDecl()->getIntegerType();
+
+  // Promotable integer types are required to be promoted by the ABI.
+  if (getContext().isPromotableIntegerType(Ty))
+return true;
+
+  // In addition to the usual promotable integer types, we also need to
+  // extend all 32-bit types, since the ABI requires promotion to 64 bits.
+  if (const BuiltinType *BT = Ty->getAs())
+switch (BT->getKind()) {
+case BuiltinType::Int:
+case BuiltinType::UInt:
+  return true;
+default:
+  break;
+}
+
+  return false;
+}
+
+bool ZOSXPLinkABIInfo::isCompoundType(QualType Ty) const {
+  return (Ty->isAnyComplexType() || Ty->isVectorType() ||
+  isAggregateTypeForABI(Ty));
+}
+
+bool ZOSXPLinkABIInfo::isVectorArgumentType(QualType Ty) const {
+  return (HasVector && Ty->isVectorType() &&
+  getContext().getTypeSize(Ty) <= 128);
+}
+
+bool ZOSXPLinkABIInfo::isFPArgumentType(QualType Ty) const {
+  if (const BuiltinType *BT = Ty->getAs())
+switch (BT->getKind()) {
+case BuiltinType::Float:
+case BuiltinType::Double:
+case BuiltinType::LongDouble:
+  return true;
+default:
+  return false;
+}
+
+  return false;
+}
+
+QualType ZOSXPLinkABIInfo::GetSingleElementType(QualType Ty) const {
+  if (const RecordType *RT = Ty->getAsStructureType()) {
+const RecordDecl *RD = RT->getDecl();
+QualType Found;
+
+// If this is a C++ record, check the bases first.
+if (const CXXRecordDecl *CXXRD = dyn_cast(RD))
+  for (const auto  : CXXRD->bases()) {
+QualType Base = I.getType();
+
+// Empty bases don't affect things either way.
+if (isEmptyRecord(getContext(), Base, true))
+  continue;
+
+if (!Found.isNull())
+  return Ty;
+Found = GetSingleElementType(Base);
+  }
+
+// Check the fields.
+for (const auto *FD : RD->fields()) {
+  // For compatibility with GCC, ignore empty bitfields in C++ mode.
+  // Unlike isSingleElementStruct(), empty structure and array fields
+  // do count.  So do anonymous bitfields that aren't zero-sized.
+  if (getContext().getLangOpts().CPlusPlus &&
+  FD->isZeroLengthBitField(getContext()))
+continue;
+
+  // Unlike isSingleElementStruct(), arrays do not count.
+  // Nested structures still do though.
+  if (!Found.isNull())
+return Ty;
+  Found = GetSingleElementType(FD->getType());
+}
+
+// Unlike isSingleElementStruct(), trailing padding is allowed.
+// An 8-byte aligned struct s { float f; } is passed as a double.
+if (!Found.isNull())
+  return Found;
+  }
+
+  return Ty;
+}
+
+bool ZOSXPLinkABIInfo::IsLikeComplexType(QualType Ty) const {
+  if (const RecordType *RT = Ty->getAsStructureType()) {
+const RecordDecl *RD = RT->getDecl();
+int i = 0;
+clang::BuiltinType::Kind elemKind;
+
+// Check for exactly two elements with 

[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)

2024-05-07 Thread Eli Friedman via cfe-commits


@@ -529,9 +529,325 @@ bool SystemZTargetCodeGenInfo::isVectorTypeBased(const 
Type *Ty,
   return false;
 }
 
+//===--===//
+// z/OS XPLINK ABI Implementation
+//===--===//
+
+namespace {
+
+class ZOSXPLinkABIInfo : public ABIInfo {
+  static const unsigned GPRBits = 64;
+  bool HasVector;
+
+public:
+  ZOSXPLinkABIInfo(CodeGenTypes , bool HV) : ABIInfo(CGT), HasVector(HV) {}
+
+  bool isPromotableIntegerType(QualType Ty) const;
+  bool isCompoundType(QualType Ty) const;
+  bool isVectorArgumentType(QualType Ty) const;
+  bool isFPArgumentType(QualType Ty) const;
+  QualType GetSingleElementType(QualType Ty) const;
+  bool IsLikeComplexType(QualType Ty) const;
+
+  ABIArgInfo classifyReturnType(QualType RetTy) const;
+  ABIArgInfo classifyArgumentType(QualType ArgTy, bool IsNamedArg) const;
+
+  void computeInfo(CGFunctionInfo ) const override {
+if (!getCXXABI().classifyReturnType(FI))
+  FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+
+unsigned NumRequiredArgs = FI.getNumRequiredArgs();
+unsigned ArgNo = 0;
+
+for (auto  : FI.arguments()) {
+  bool IsNamedArg = ArgNo < NumRequiredArgs;
+  I.info = classifyArgumentType(I.type, IsNamedArg);
+  ++ArgNo;
+}
+  }
+
+  Address EmitVAArg(CodeGenFunction , Address VAListAddr,
+QualType Ty) const override;
+};
+
+class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  ZOSXPLinkTargetCodeGenInfo(CodeGenTypes , bool HasVector)
+  : TargetCodeGenInfo(std::make_unique(CGT, HasVector)) {
+SwiftInfo =
+std::make_unique(CGT, /*SwiftErrorInRegister=*/false);
+  }
+};
+
+} // namespace
+
+// Return true if the ABI requires Ty to be passed sign- or zero-
+// extended to 64 bits.
+bool ZOSXPLinkABIInfo::isPromotableIntegerType(QualType Ty) const {
+  // Treat an enum type as its underlying type.
+  if (const EnumType *EnumTy = Ty->getAs())
+Ty = EnumTy->getDecl()->getIntegerType();
+
+  // Promotable integer types are required to be promoted by the ABI.
+  if (getContext().isPromotableIntegerType(Ty))
+return true;
+
+  // In addition to the usual promotable integer types, we also need to
+  // extend all 32-bit types, since the ABI requires promotion to 64 bits.
+  if (const BuiltinType *BT = Ty->getAs())
+switch (BT->getKind()) {
+case BuiltinType::Int:
+case BuiltinType::UInt:
+  return true;
+default:
+  break;
+}
+
+  return false;
+}
+
+bool ZOSXPLinkABIInfo::isCompoundType(QualType Ty) const {
+  return (Ty->isAnyComplexType() || Ty->isVectorType() ||
+  isAggregateTypeForABI(Ty));
+}
+
+bool ZOSXPLinkABIInfo::isVectorArgumentType(QualType Ty) const {
+  return (HasVector && Ty->isVectorType() &&
+  getContext().getTypeSize(Ty) <= 128);
+}
+
+bool ZOSXPLinkABIInfo::isFPArgumentType(QualType Ty) const {
+  if (const BuiltinType *BT = Ty->getAs())
+switch (BT->getKind()) {
+case BuiltinType::Float:
+case BuiltinType::Double:
+case BuiltinType::LongDouble:
+  return true;
+default:
+  return false;
+}
+
+  return false;
+}
+
+QualType ZOSXPLinkABIInfo::GetSingleElementType(QualType Ty) const {
+  if (const RecordType *RT = Ty->getAsStructureType()) {
+const RecordDecl *RD = RT->getDecl();
+QualType Found;
+
+// If this is a C++ record, check the bases first.
+if (const CXXRecordDecl *CXXRD = dyn_cast(RD))
+  for (const auto  : CXXRD->bases()) {
+QualType Base = I.getType();
+
+// Empty bases don't affect things either way.
+if (isEmptyRecord(getContext(), Base, true))
+  continue;
+
+if (!Found.isNull())
+  return Ty;
+Found = GetSingleElementType(Base);
+  }
+
+// Check the fields.
+for (const auto *FD : RD->fields()) {
+  // For compatibility with GCC, ignore empty bitfields in C++ mode.
+  // Unlike isSingleElementStruct(), empty structure and array fields
+  // do count.  So do anonymous bitfields that aren't zero-sized.
+  if (getContext().getLangOpts().CPlusPlus &&
+  FD->isZeroLengthBitField(getContext()))
+continue;
+
+  // Unlike isSingleElementStruct(), arrays do not count.
+  // Nested structures still do though.
+  if (!Found.isNull())
+return Ty;
+  Found = GetSingleElementType(FD->getType());
+}
+
+// Unlike isSingleElementStruct(), trailing padding is allowed.
+// An 8-byte aligned struct s { float f; } is passed as a double.
+if (!Found.isNull())
+  return Found;
+  }
+
+  return Ty;
+}
+
+bool ZOSXPLinkABIInfo::IsLikeComplexType(QualType Ty) const {
+  if (const RecordType *RT = Ty->getAsStructureType()) {
+const RecordDecl *RD = RT->getDecl();
+int i = 0;
+clang::BuiltinType::Kind elemKind;
+
+// Check for exactly two elements with 

[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)

2024-05-07 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic edited 
https://github.com/llvm/llvm-project/pull/91384
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [BPF] Fix linking issues in static map initializers (PR #91310)

2024-05-07 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic edited 
https://github.com/llvm/llvm-project/pull/91310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [BPF] Fix linking issues in static map initializers (PR #91310)

2024-05-07 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic commented:

Is it possible you could put this code into CompleteExternalDeclaration(), 
instead of writing it out in every place that can refer to the address of a 
function?

https://github.com/llvm/llvm-project/pull/91310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [BPF] Fix linking issues in static map initializers (PR #91310)

2024-05-07 Thread Eli Friedman via cfe-commits


@@ -1950,8 +1950,22 @@ ConstantLValueEmitter::tryEmitBase(const 
APValue::LValueBase ) {
 if (D->hasAttr())
   return CGM.GetWeakRefReference(D).getPointer();
 
-if (auto FD = dyn_cast(D))
-  return CGM.GetAddrOfFunction(FD);
+if (auto FD = dyn_cast(D)) {
+  auto *C = CGM.GetAddrOfFunction(FD);
+
+  // we don't normally emit debug info for extern fns referenced via
+  // variable initialisers; BPF needs it since it generates BTF from
+  // debug info and bpftool demands BTF for every symbol linked
+  if (CGM.getTarget().getTriple().isBPF() && FD->getStorageClass() == 
SC_Extern) {

efriedma-quic wrote:

There's an existing hook allowDebugInfoForExternalRef() for which targets want 
this.

You almost never want getStorageClass(); if you care about linkage, we have 
different methods for that.

https://github.com/llvm/llvm-project/pull/91310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Lower _BitInt(129+) to a different type in LLVM IR (PR #91364)

2024-05-07 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

I don't think FPGA folks will run into any practical issue with this; this only 
impacts the in-memory types, and backends shouldn't really be using in-memory 
types for anything anyways.

https://github.com/llvm/llvm-project/pull/91364
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Lower _BitInt(129+) to a different type in LLVM IR (PR #91364)

2024-05-07 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

> It seems to me this is a case where we're trying to work -around an llvm bug? 
> Should we just be fixing that instead?

You mean, revert https://reviews.llvm.org/D86310 ?  Making any changes in LLVM 
here is painful; I'd rather not revisit that.  CC @hvdijk @rnk

https://github.com/llvm/llvm-project/pull/91364
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Lower _BitInt(129+) to a different type in LLVM IR (PR #91364)

2024-05-07 Thread Eli Friedman via cfe-commits


@@ -5348,6 +5348,13 @@ Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
 return llvm::UndefValue::get(ArgTy);
   }
 
+  if (const auto *BIT = Ty->getAs()) {
+if (BIT->getNumBits() > 128) {

efriedma-quic wrote:

This seems a little fragile; specifically for _BitInt, we assume the pointer is 
wrong and the return type is right, but in other cases, we assume the pointer 
is right and we need to do some sort of conversion.

Can we fix the interface of EmitVAArg so we can just EmitLoadOfScalar() here?

https://github.com/llvm/llvm-project/pull/91364
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Lower _BitInt(129+) to a different type in LLVM IR (PR #91364)

2024-05-07 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic commented:

Maybe add a helper somewhere to check "is this type a bitint wider than 128 
bits"?

https://github.com/llvm/llvm-project/pull/91364
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Lower _BitInt(129+) to a different type in LLVM IR (PR #91364)

2024-05-07 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic edited 
https://github.com/llvm/llvm-project/pull/91364
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Lower _BitInt(129+) to a different type in LLVM IR (PR #91364)

2024-05-07 Thread Eli Friedman via cfe-commits


@@ -1774,6 +1774,18 @@ llvm::Constant 
*ConstantEmitter::emitForMemory(CodeGenModule ,
 return Res;
   }
 
+  if (const auto *BIT = destType->getAs()) {
+if (BIT->getNumBits() > 128) {
+  // Long _BitInt has array of bytes as in-memory type.
+  ConstantAggregateBuilder Builder(CGM);
+  llvm::Type *DesiredTy = CGM.getTypes().ConvertTypeForMem(destType);
+  auto *CI = cast(C);

efriedma-quic wrote:

I'm not sure this cast is guaranteed to succeed?  At least in some cases, we 
emit constant expressions involving a ptrtoint.  Maybe at the widths in 
question, that can't happen, but this deserves a comment explaining what's 
going on.

https://github.com/llvm/llvm-project/pull/91364
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][AArch64] Fixed incorrect _BitInt alignment (PR #90602)

2024-05-07 Thread Eli Friedman via cfe-commits


@@ -518,6 +518,16 @@ class TargetInfo : public TransferrableTargetInfo,
   /// getInt128Align() - Returns the alignment of Int128.
   unsigned getInt128Align() const { return Int128Align; }
 
+  /// getBitIntAlign/Width - Return aligned size of '_BitInt' and
+  /// 'unsigned _BitInt' for this target, in bits.
+  unsigned getBitIntWidth(unsigned NumBits) const {
+return llvm::alignTo(NumBits, getBitIntAlign(NumBits));
+  }
+  virtual unsigned getBitIntAlign(unsigned NumBits) const {

efriedma-quic wrote:

```
unsigned getBitIntMaxAlign() {
  return BitIntMaxAlign.or(LongLongAlign);
}
unsigned getBitIntAlign(unsigned NumBits) const {
return std::clamp(llvm::PowerOf2Ceil(NumBits), getCharWidth(),
getBitIntMaxAlign());
}
```

https://github.com/llvm/llvm-project/pull/90602
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Arm64EC] Fix compilation of arm_acle.h (PR #91281)

2024-05-06 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic closed 
https://github.com/llvm/llvm-project/pull/91281
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Arm64EC] Fix compilation of arm_acle.h (PR #91281)

2024-05-06 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic created 
https://github.com/llvm/llvm-project/pull/91281

None

>From 5a5512aa5a84e2c89efd9e9ade043061d73d25fb Mon Sep 17 00:00:00 2001
From: Eli Friedman 
Date: Fri, 3 May 2024 21:13:32 -0700
Subject: [PATCH] [Arm64EC] Fix compilation of arm_acle.h

---
 clang/lib/Headers/arm_acle.h | 2 +-
 clang/test/Headers/arm-acle-header.c | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Headers/arm_acle.h b/clang/lib/Headers/arm_acle.h
index 6e557eda1dddca..5785954c9171ab 100644
--- a/clang/lib/Headers/arm_acle.h
+++ b/clang/lib/Headers/arm_acle.h
@@ -109,7 +109,7 @@ __swp(uint32_t __x, volatile uint32_t *__p) {
 #endif
 
 /* 7.7 NOP */
-#if !defined(_MSC_VER) || !defined(__aarch64__)
+#if !defined(_MSC_VER) || (!defined(__aarch64__) && !defined(__arm64ec__))
 static __inline__ void __attribute__((__always_inline__, __nodebug__)) 
__nop(void) {
   __builtin_arm_nop();
 }
diff --git a/clang/test/Headers/arm-acle-header.c 
b/clang/test/Headers/arm-acle-header.c
index f04c7e1f0f35f7..fea8472183c871 100644
--- a/clang/test/Headers/arm-acle-header.c
+++ b/clang/test/Headers/arm-acle-header.c
@@ -7,6 +7,7 @@
 // RUN: %clang_cc1 -x c++ -triple thumbv7-windows -target-cpu cortex-a15 
-fsyntax-only -ffreestanding -fms-extensions -fms-compatibility 
-fms-compatibility-version=19.11 %s
 // RUN: %clang_cc1 -x c++ -triple aarch64-windows -target-cpu cortex-a53 
-fsyntax-only -ffreestanding -fms-extensions -fms-compatibility 
-fms-compatibility-version=19.11 %s
 // RUN: %clang_cc1 -x c++ -triple arm64-apple-ios -target-cpu apple-a7 
-fsyntax-only -ffreestanding -fms-extensions %s
+// RUN: %clang_cc1 -x c++ -triple arm64ec-windows -target-cpu cortex-a53 
-fsyntax-only -ffreestanding -fms-extensions -fms-compatibility 
-fms-compatibility-version=19.11 %s
 // expected-no-diagnostics
 
 #include 

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [ARM] Save floating point registers and status registers with save_fp function attribute (PR #89654)

2024-05-06 Thread Eli Friedman via cfe-commits


@@ -2239,6 +2239,20 @@ The semantics are as follows:
   }];
 }
 
+def ARMInterruptSaveFPDocs : Documentation {
+let Category = DocCatFunction;
+  let Heading = "interrupt_save_fp (ARM)";
+  let Content = [{
+Clang supports the GNU style ``__attribute__((interrupt_save_fp("TYPE")))``
+on ARM targets. This attribute behaves the same way as the ARM interrupt
+attribute, except the general purpose floating point registers are also saved. 
+If the FPEXC or FPSCR are needed, that state must be saved manually. Note, 
even 

efriedma-quic wrote:

This says FPSCR isn't saved... but some of the tests show FPSCR getting saved.  
Which is right?

https://github.com/llvm/llvm-project/pull/89654
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


  1   2   3   4   5   6   7   8   >