[clang] [clang] Strict aliasing warning ala GCC [PR50066] (PR #74155)

2023-12-06 Thread Nathan Sidwell via cfe-commits

https://github.com/urnathan updated 
https://github.com/llvm/llvm-project/pull/74155

>From 89c05618bb75fd073343046f3b54bde5f2254719 Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Wed, 15 Nov 2023 15:27:16 -0500
Subject: [PATCH 1/5] [clang] Strict aliasing warning ala GCC [PR50066]

This implements -Wstrict-aliasing(=[123])? along the same lines as
GCC. It's not 100% the same for reasons expanded on below. The default
is level 3, and I have verified that bootstrapping does not trigger
any warnings (just like building with GCC).

As with GCC, higher levels result in fewer warnings, reducing the
number of false positives at the cost of missing (some) potential
cases. Unlike GCC, this is entirely in the FE, we do not propagate any
checking into the IR (so there are cases GCC will detect we do not, I
have not encountered any). GCC's documentation is not very specific
about which cases are detected. I examined GCC's source code to reverse
engineer the algorithm[*], and as can be seen from the testcases, noted
GCC's behaviour.

The strict aliasing check relies on TBAA. LLVM's representation is
semantically different to GCCs for structured types. I have tried to
keep with the spirit of the warning.

The warning checks reinterpret_casts that are CK_BitCast or
CK_LValueBitCast. It also checks C-style casts that are equivalent (to
the extent available, as a C-style bitcast could be a well-formed
static cast).

level=1 looks for reinterpret casts from T * to U * (or an lvalue of
type T to U &), where T and U are not TBAA compatible.

level=2 requires the src expression be an lvalue something of
known(ish) static type. I.e a variable, array dereference or member
access.

level=3 requires level 2 and that the resultant pointer is actually
referenced (lvalue->rvalue or lvalue written). Here we can do better
than GCC, which doesn't represent this in the IR -- we merely get a
dereference (and reference types are modeled as pointers with
auto-dereference semantics). There is one exception to this, which is
by-value aggregate arguments. These end up invoking a copy constructor
(passing a reference of course), but are IMHO morally an rvalue -- so
should trigger.

The warning hooks into clang's code-generator's TBAA machinery. For
scalar types the TBAA is straight forwards, comparing LLVM's MDNode
representaion. For record & union types we check if one of the types
is (recursively) the same (or TBAA compatible) as the first direct
base or a field(s) of the record at offset zero (i.e. the first member
of a record, or any members of a union). This covers both C++ and
C-Style inheritance. Also. the member maybe alias_any, or in
ubiquitous-char's alias set, which is also permissible.

The warning is similar to the alignment check that
CheckCompatibleReinterpretCast does, perhaps some merging could occur
if this is accepted?

[*] I implemented what turned into GCC's level=1 way back when.

WIP: adjust tests
---
 clang/include/clang/AST/ASTConsumer.h |   25 +
 clang/include/clang/Basic/DiagnosticGroups.td |6 -
 clang/include/clang/Basic/DiagnosticOptions.h |4 +
 .../clang/Basic/DiagnosticSemaKinds.td|8 +
 clang/include/clang/Driver/Options.td |6 +
 clang/include/clang/Sema/Sema.h   |   11 +
 clang/lib/CodeGen/BackendConsumer.h   |1 +
 clang/lib/CodeGen/CodeGenAction.cpp   |4 +
 clang/lib/CodeGen/CodeGenModule.h |1 +
 clang/lib/CodeGen/CodeGenTBAA.cpp |  134 ++
 clang/lib/CodeGen/CodeGenTBAA.h   |5 +-
 clang/lib/CodeGen/ModuleBuilder.cpp   |2 +
 clang/lib/Frontend/CompilerInvocation.cpp |3 +
 clang/lib/Frontend/FrontendAction.cpp |8 +
 clang/lib/Sema/SemaCast.cpp   |  139 ++
 clang/lib/Sema/SemaExpr.cpp   |   17 +-
 clang/lib/Sema/SemaExprMember.cpp |2 +
 clang/lib/Sema/SemaInit.cpp   |5 +
 clang/test/Misc/warning-flags-tree.c  |4 -
 clang/test/Sema/strict-aliasing-warn.c|  192 +++
 clang/test/SemaCXX/strict-aliasing-warn.cpp   | 1375 +
 21 files changed, 1939 insertions(+), 13 deletions(-)
 create mode 100644 clang/test/Sema/strict-aliasing-warn.c
 create mode 100644 clang/test/SemaCXX/strict-aliasing-warn.cpp

diff --git a/clang/include/clang/AST/ASTConsumer.h 
b/clang/include/clang/AST/ASTConsumer.h
index ebcd8059284d8..d5731ed6adf63 100644
--- a/clang/include/clang/AST/ASTConsumer.h
+++ b/clang/include/clang/AST/ASTConsumer.h
@@ -21,6 +21,7 @@ namespace clang {
   class DeclGroupRef;
   class ASTMutationListener;
   class ASTDeserializationListener; // layering violation because void* is ugly
+  class QualType;
   class SemaConsumer; // layering violation required for safe SemaConsumer
   class TagDecl;
   class VarDecl;
@@ -37,6 +38,27 @@ class ASTConsumer {
 
   friend class SemaConsumer;
 
+public:
+  /// Allow type-based aliasing information to be interrogated by the

[clang] [clang] Strict aliasing warning ala GCC [PR50066] (PR #74155)

2023-12-06 Thread Nathan Sidwell via cfe-commits


@@ -498,3 +498,137 @@ 
CodeGenTBAA::mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo,
   // access type regardless of their base types.
   return TBAAAccessInfo::getMayAliasInfo();
 }
+
+// Determine the aliasing kind bit-converting from type Src to type Dst.
+CodeGenTBAA::AliasingKind CodeGenTBAA::getAliasingKind(QualType &Dst,
+   QualType &Src) {
+  assert(!Src->isVoidType() && !Dst->isVoidType());
+  if (TypeHasMayAlias(Src) || TypeHasMayAlias(Dst))
+return AK_Ok;
+
+  Src = QualType{Src->getBaseElementTypeUnsafe(), 0};
+  Dst = QualType{Dst->getBaseElementTypeUnsafe(), 0};
+
+  auto *SrcDecl = Src->getAsRecordDecl();
+  auto *DstDecl = Dst->getAsRecordDecl();
+
+  const llvm::MDNode *AnyTBAA = getChar();
+  const llvm::MDNode *SrcTBAA = nullptr;
+  const llvm::MDNode *DstTBAA = nullptr;
+
+  if (!SrcDecl) {
+SrcTBAA = getTypeInfo(Src);
+if (!SrcTBAA || SrcTBAA == AnyTBAA)

urnathan wrote:

Yeah, I didn't because it was a class member, but scoped is better. done.

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


[clang] [clang] Strict aliasing warning ala GCC [PR50066] (PR #74155)

2023-12-06 Thread Nathan Sidwell via cfe-commits


@@ -498,3 +498,137 @@ 
CodeGenTBAA::mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo,
   // access type regardless of their base types.
   return TBAAAccessInfo::getMayAliasInfo();
 }
+
+// Determine the aliasing kind bit-converting from type Src to type Dst.
+CodeGenTBAA::AliasingKind CodeGenTBAA::getAliasingKind(QualType &Dst,
+   QualType &Src) {
+  assert(!Src->isVoidType() && !Dst->isVoidType());
+  if (TypeHasMayAlias(Src) || TypeHasMayAlias(Dst))
+return AK_Ok;
+
+  Src = QualType{Src->getBaseElementTypeUnsafe(), 0};
+  Dst = QualType{Dst->getBaseElementTypeUnsafe(), 0};
+
+  auto *SrcDecl = Src->getAsRecordDecl();
+  auto *DstDecl = Dst->getAsRecordDecl();
+
+  const llvm::MDNode *AnyTBAA = getChar();
+  const llvm::MDNode *SrcTBAA = nullptr;
+  const llvm::MDNode *DstTBAA = nullptr;
+
+  if (!SrcDecl) {
+SrcTBAA = getTypeInfo(Src);
+if (!SrcTBAA || SrcTBAA == AnyTBAA)
+  return AK_Ok;
+  }
+  if (!DstDecl) {
+DstTBAA = getTypeInfo(Dst);
+if (!DstTBAA || DstTBAA == AnyTBAA)
+  return AK_Ok;
+  }
+
+  auto IsAncestor = [](const llvm::MDNode *Ancestor,
+   const llvm::MDNode *Descendant) {
+assert(Ancestor != Descendant && "Identical TBAA");
+while (Descendant->getNumOperands() != 1) {
+  Descendant = cast(Descendant->getOperand(1));
+  if (Descendant == Ancestor)
+return true;
+}
+return false;
+  };
+
+  assert(SrcTBAA != AnyTBAA && DstTBAA != AnyTBAA &&

urnathan wrote:

Ah, I found the current placement better -- as a reminder to the code below 
that that particular condition did not need to be handled.  The assert got 
added explicitly when I needed that reminder!

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


[clang] [clang] Strict aliasing warning ala GCC [PR50066] (PR #74155)

2023-12-06 Thread Nathan Sidwell via cfe-commits


@@ -2026,6 +2027,137 @@ static TryCastResult TryConstCast(Sema &Self, 
ExprResult &SrcExpr,
   return TC_Success;
 }
 
+// We're dereferencing E, either by turning into an RValue, or by dereferencing
+// it. Check whether it's a deref of a reinterpret cast that has aliasing
+// issues.
+void Sema::CheckStrictAliasingDeref(Expr const *E, bool IsLValue) {
+  if (Diags.getDiagnosticOptions().StrictAliasing < 3)
+return;
+
+  assert(IsLValue || E->getType()->isAnyPointerType());
+  CastExpr const *CE = nullptr;
+  for (;;) {
+CE = dyn_cast(E->IgnoreParens());
+if (!CE)
+  return;
+
+if (IsLValue || CE->getCastKind() != CK_ArrayToPointerDecay)
+  break;
+
+E = CE->getSubExpr();
+IsLValue = true;
+  }
+
+  if (CE->getCastKind() != (IsLValue ? CK_LValueBitCast : CK_BitCast))
+return;
+
+  if (CE->getSubExpr()->getType()->isVoidPointerType())
+return;
+
+  QualType DestTy = CE->getType();
+  if (!IsLValue)
+DestTy = DestTy->getPointeeType();
+
+  CheckStrictAliasing(CE->getSubExpr(), DestTy, IsLValue, 
CE->getSourceRange());
+}
+
+/// We're building a cast from E to pointer type DestType. If ISLValueCast is
+/// true, DestType is the pointer equivalent of the reference type we're 
casting
+/// to.
+void Sema::CheckStrictAliasingCast(Expr const *E, QualType DestType,
+   bool IsLValueCast, SourceRange Range) {
+  if (Diags.getDiagnosticOptions().StrictAliasing < 1 ||

urnathan wrote:

Heh, that's amusing :)  this started as a switch, and then changed when I found 
the switch to be line noise..

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


[clang] [clang] Strict aliasing warning ala GCC [PR50066] (PR #74155)

2023-12-06 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

> Making Sema pull the TBAA info out of clang/lib/CodeGen is a layering 
> violation (and probably breaks if we aren't actually generating code). If we 
> need some notion of "aliasing" in Sema, we should pull the relevant code into 
> clang/lib/AST.

That's unfortunate.  The code will not call the TBAA stuff if the code 
generator doesn't provide that predicate -- so if not generating optimized code 
the warning is inactive.  This is the same as with GCC btw. To be clear what's 
exposed is a new predicate allowing querying of type conversion's TBAAness -- 
the representations of TBAA etc are not exposed.  The CodeGen TBAA machinery 
builds on llvm's aliasing MDNodes. It would seem a large task to replicate that 
in AST (and I presume propagating llvm's bits further into AST is even worse?)

> I don't have any experience with this warning, so I'm not sure how effective 
> it is at detecting issues; do a significant fraction of issues actually show 
> up at a pure syntactic level? Do you have any idea what false positive rate 
> we should expect?

I think at level 3 the false positive rate is very low. Given GCC's extended 
this over the years from the simple check I had (IIRC any reinterpret_cast 
between pointers/references to TBAA incompatible types) to the semantics it has 
now suggests the warning is useful. and the level 3 default is satisfactory. 
But I don't have hard data.

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


[clang] [clang] Strict aliasing warning ala GCC [PR50066] (PR #74155)

2023-12-06 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

> FWIW the GCC doc is 
> https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wstrict-aliasing_003dn
>  It says for Level 3 "If optimization is enabled, it also runs in the back 
> end, where it deals with multiple statement cases using flow-sensitive 
> points-to information."
> 
> Do you know how it works? Any example?

I do not now how it works -- didn't go poking there.  Neither do I have 
examples.

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


[clang] [clang] Strict aliasing warning ala GCC [PR50066] (PR #74155)

2023-12-06 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

> Thank you for your efforts! I scratched the surface a bit; not qualified to 
> do an in-depth review. Can you also add a release note?

Thanks for your comments.  A release note is added.

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


[clang] [clang] Strict aliasing warning ala GCC [PR50066] (PR #74155)

2023-12-06 Thread Nathan Sidwell via cfe-commits

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


[clang] [clang] Strict aliasing warning ala GCC [PR50066] (PR #74155)

2023-12-06 Thread Nathan Sidwell via cfe-commits


@@ -128,6 +128,10 @@ class DiagnosticOptions : public 
RefCountedBase{
   /// whether -Wsystem-headers is enabled on a per-module basis.
   std::vector SystemHeaderWarningsModules;
 
+  /// Level of scrutiny reinterpret_casts get for type-unsafe aliasing
+  /// checks. Requires an ASTConsumer that provides TBAA information.
+  unsigned StrictAliasing;

urnathan wrote:

I was misled by the -Wundef-prefix pattern that I followed.  Should have looked 
closer and found the DiagnosticOptions.def file.

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


[clang] [clang] Strict aliasing warning ala GCC [PR50066] (PR #74155)

2023-12-06 Thread Nathan Sidwell via cfe-commits

https://github.com/urnathan updated 
https://github.com/llvm/llvm-project/pull/74155

>From 89c05618bb75fd073343046f3b54bde5f2254719 Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Wed, 15 Nov 2023 15:27:16 -0500
Subject: [PATCH 1/6] [clang] Strict aliasing warning ala GCC [PR50066]

This implements -Wstrict-aliasing(=[123])? along the same lines as
GCC. It's not 100% the same for reasons expanded on below. The default
is level 3, and I have verified that bootstrapping does not trigger
any warnings (just like building with GCC).

As with GCC, higher levels result in fewer warnings, reducing the
number of false positives at the cost of missing (some) potential
cases. Unlike GCC, this is entirely in the FE, we do not propagate any
checking into the IR (so there are cases GCC will detect we do not, I
have not encountered any). GCC's documentation is not very specific
about which cases are detected. I examined GCC's source code to reverse
engineer the algorithm[*], and as can be seen from the testcases, noted
GCC's behaviour.

The strict aliasing check relies on TBAA. LLVM's representation is
semantically different to GCCs for structured types. I have tried to
keep with the spirit of the warning.

The warning checks reinterpret_casts that are CK_BitCast or
CK_LValueBitCast. It also checks C-style casts that are equivalent (to
the extent available, as a C-style bitcast could be a well-formed
static cast).

level=1 looks for reinterpret casts from T * to U * (or an lvalue of
type T to U &), where T and U are not TBAA compatible.

level=2 requires the src expression be an lvalue something of
known(ish) static type. I.e a variable, array dereference or member
access.

level=3 requires level 2 and that the resultant pointer is actually
referenced (lvalue->rvalue or lvalue written). Here we can do better
than GCC, which doesn't represent this in the IR -- we merely get a
dereference (and reference types are modeled as pointers with
auto-dereference semantics). There is one exception to this, which is
by-value aggregate arguments. These end up invoking a copy constructor
(passing a reference of course), but are IMHO morally an rvalue -- so
should trigger.

The warning hooks into clang's code-generator's TBAA machinery. For
scalar types the TBAA is straight forwards, comparing LLVM's MDNode
representaion. For record & union types we check if one of the types
is (recursively) the same (or TBAA compatible) as the first direct
base or a field(s) of the record at offset zero (i.e. the first member
of a record, or any members of a union). This covers both C++ and
C-Style inheritance. Also. the member maybe alias_any, or in
ubiquitous-char's alias set, which is also permissible.

The warning is similar to the alignment check that
CheckCompatibleReinterpretCast does, perhaps some merging could occur
if this is accepted?

[*] I implemented what turned into GCC's level=1 way back when.

WIP: adjust tests
---
 clang/include/clang/AST/ASTConsumer.h |   25 +
 clang/include/clang/Basic/DiagnosticGroups.td |6 -
 clang/include/clang/Basic/DiagnosticOptions.h |4 +
 .../clang/Basic/DiagnosticSemaKinds.td|8 +
 clang/include/clang/Driver/Options.td |6 +
 clang/include/clang/Sema/Sema.h   |   11 +
 clang/lib/CodeGen/BackendConsumer.h   |1 +
 clang/lib/CodeGen/CodeGenAction.cpp   |4 +
 clang/lib/CodeGen/CodeGenModule.h |1 +
 clang/lib/CodeGen/CodeGenTBAA.cpp |  134 ++
 clang/lib/CodeGen/CodeGenTBAA.h   |5 +-
 clang/lib/CodeGen/ModuleBuilder.cpp   |2 +
 clang/lib/Frontend/CompilerInvocation.cpp |3 +
 clang/lib/Frontend/FrontendAction.cpp |8 +
 clang/lib/Sema/SemaCast.cpp   |  139 ++
 clang/lib/Sema/SemaExpr.cpp   |   17 +-
 clang/lib/Sema/SemaExprMember.cpp |2 +
 clang/lib/Sema/SemaInit.cpp   |5 +
 clang/test/Misc/warning-flags-tree.c  |4 -
 clang/test/Sema/strict-aliasing-warn.c|  192 +++
 clang/test/SemaCXX/strict-aliasing-warn.cpp   | 1375 +
 21 files changed, 1939 insertions(+), 13 deletions(-)
 create mode 100644 clang/test/Sema/strict-aliasing-warn.c
 create mode 100644 clang/test/SemaCXX/strict-aliasing-warn.cpp

diff --git a/clang/include/clang/AST/ASTConsumer.h 
b/clang/include/clang/AST/ASTConsumer.h
index ebcd8059284d8..d5731ed6adf63 100644
--- a/clang/include/clang/AST/ASTConsumer.h
+++ b/clang/include/clang/AST/ASTConsumer.h
@@ -21,6 +21,7 @@ namespace clang {
   class DeclGroupRef;
   class ASTMutationListener;
   class ASTDeserializationListener; // layering violation because void* is ugly
+  class QualType;
   class SemaConsumer; // layering violation required for safe SemaConsumer
   class TagDecl;
   class VarDecl;
@@ -37,6 +38,27 @@ class ASTConsumer {
 
   friend class SemaConsumer;
 
+public:
+  /// Allow type-based aliasing information to be interrogated by the

[clang] [clang] Strict aliasing warning ala GCC [PR50066] (PR #74155)

2023-12-06 Thread Nathan Sidwell via cfe-commits


@@ -0,0 +1,192 @@
+// RUN: %clang_cc1 %s -O0 -Wstrict-aliasing -S -o %t -verify=quiet
+// RUN: %clang_cc1 %s -O2 -Wstrict-aliasing=0 -S -o %t -verify=quiet
+// RUN: %clang_cc1 %s -O2 -Wno-strict-aliasing -S -o %t -verify=quiet
+// RUN: %clang_cc1 %s -O2 -Wstrict-aliasing=1 -S -o %t 
-verify=level1,level12,level123
+// RUN: %clang_cc1 %s -O2 -Wstrict-aliasing=2 -S -o %t 
-verify=level2,level23,level12,level123
+// RUN: %clang_cc1 %s -O2 -Wstrict-aliasing=3 -S -o %t -verify=level23,level123
+// RUN: %clang_cc1 %s -O2 -Wstrict-aliasing -S -o %t -verify=level23,level123
+// RUN: %clang_cc1 %s -O2 -S -o %t -verify=level23,level123
+
+// quiet-no-diagnostics
+
+#if _LP64
+// These names make more sense on an ilp32 machine
+typedef long INT;
+typedef long long LONG;
+typedef unsigned long UINT;
+#else
+typedef int INT;
+typedef long LONG;
+typedef unsigned int UINT;
+#endif
+typedef short SHORT;
+
+INT ScalarINT;
+INT Ary[2];
+struct {int m;} Struct;
+
+_Complex int CPLx;
+
+void ByVal(long long);
+void ByPtr(void *);
+
+void VarPtr(INT *Ptr) {
+  // GCC: 1
+  // level1-warning@+1{{type-punned pointer might break}}
+  ByPtr((LONG *)(Ptr));
+  // level1-note@-1{{not alias compatible}}
+
+  // GCC:
+  ByPtr((LONG *)((void *)(Ptr)));
+
+  // GCC: 1
+  // level1-warning@+1{{type-punned pointer might break}}
+  ByVal(*(LONG *)(Ptr));
+  // level1-note@-1{{not alias compatible}}
+}
+
+void Object() {
+  // GCC: 1, 2
+  // level2-warning@+2{{type-punned pointer breaks}}
+  // level1-warning@+1{{type-punned pointer might break}}
+  ByPtr((LONG *)(&ScalarINT));
+  // level12-note@-1{{not alias compatible}}
+
+  // GCC:
+  ByPtr((LONG *)((void *)(&ScalarINT)));
+
+  // GCC: 1, 2, 3
+  // level23-warning@+2{{type-punned pointer breaks}}
+  // level1-warning@+1{{type-punned pointer might break}}
+  ByVal(*(LONG *)(&ScalarINT));
+  // level123-note@-1{{not alias compatible}}
+}
+
+// Level 1, 2, 3 - 1, 2, 3
+void DetectedVariants() {
+  // GCC: 1, 2, 3
+  // level23-warning@+2{{type-punned pointer breaks}}
+  // level1-warning@+1{{type-punned pointer might break}}
+  ByVal(*(LONG *)(&Ary[1]));
+  // level123-note@-1{{not alias compatible}}
+
+  // GCC: 1, 2, 3
+  // level23-warning@+2{{type-punned pointer breaks}}
+  // level1-warning@+1{{type-punned pointer might break}}
+  ByVal(*(LONG *)(&Struct.m));
+  // level123-note@-1{{not alias compatible}}
+
+  // GCC: 1, 2, 3
+  // level23-warning@+2{{type-punned pointer breaks}}
+  // level1-warning@+1{{type-punned pointer might break}}
+  ByVal(*(LONG *)(&(&Struct)->m));
+  // level123-note@-1{{not alias compatible}}
+
+  // GCC: 1, 2, 3
+  // level23-warning@+2{{type-punned pointer breaks}}
+  // level1-warning@+1{{type-punned pointer might break}}
+  ByVal(*(LONG *)(&__real__(CPLx)));
+  // level123-note@-1{{not alias compatible}}
+
+  // GCC: 1, 2, 3
+  // level23-warning@+2{{type-punned pointer breaks}}
+  // level1-warning@+1{{type-punned pointer might break}}
+  ByVal(*(LONG *)(&__imag__(CPLx)));
+  // level123-note@-1{{not alias compatible}}
+}
+
+void Ok() {
+  // GCC:
+  ByPtr((UINT *)(&ScalarINT));
+  // GCC:
+  ByPtr((UINT *)((void *)(&ScalarINT)));
+  // GCC:
+  ByVal(*(UINT *)(&ScalarINT));
+}
+
+// Level 1, 2, 3 - 1, 2, 3
+void Parens() {
+  // GCC: 1, 2, 3
+  // level23-warning@+2{{type-punned pointer breaks}}
+  // level1-warning@+1{{type-punned pointer might break}}
+  ByVal(*((LONG *)((&(ScalarINT);
+  // level123-note@-1{{not alias compatible}}
+
+  // GCC: 1, 2, 3
+  // level23-warning@+2{{type-punned pointer breaks}}
+  // level1-warning@+1{{type-punned pointer might break}}
+  ByVal(*((LONG *)((&(Ary[1]);
+  // level123-note@-1{{not alias compatible}}
+}
+
+// Clang models may_alias as a decl attribute, not a type attribute.
+
+typedef int MA __attribute__((may_alias));
+
+void Frob(MA *a) {
+  ByPtr((short *)(a));
+  ByVal(*(short *)(a));
+}
+
+struct Inner { int m; };
+struct Outer1 { struct Inner i; };
+struct Outer2 { struct Outer1 o; };
+struct Inner i;
+struct Outer2 o;
+
+void ByValInner (struct Inner);
+void ByValOuter2 (struct Outer2);
+
+void Inherit() {
+  // Check we see through multiple levels
+  int in;
+
+  ByValOuter2(*(struct Outer2 *)&in);
+  ByValOuter2(*(struct Outer2 *)&i);
+  ByValInner(*(struct Inner *)&o.o);
+  ByValInner(*(struct Inner *)&o);
+  ByVal(*(int *)&o);
+}
+
+// PR 50066
+typedef unsigned char uchar;
+
+void Double(double);
+
+int main() {
+  double d = 2.34;
+  int i[2];
+  Double(d);
+
+  // GCC: 1, 2, 3
+  // level23-warning@+2{{type-punned pointer breaks}}
+  // level1-warning@+1{{type-punned pointer might break}}
+  *(long long *)i =
+  // level123-note@-1{{not alias compatible}}
+
+  // GCC: 1, 2, 3
+  // level23-warning@+2{{type-punned pointer breaks}}
+  // level1-warning@+1{{type-punned pointer might break}}
+  *(long long *)&d;
+  // level123-note@-1{{not alias compatible}}
+
+  // GCC: 1, 2, 3
+  // level23-warning@+2{{type-punned pointer breaks}}
+  // level1-warnin

[clang] [clang] Better bitfield access units (PR #65742)

2023-12-08 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

> I'm planning to take a closer look at this when I have more time. Sorry I 
> haven't been more responsive here.

When might that be?


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


[clang] [clang] Adjust TargetInfo bitfield (PR #74893)

2023-12-08 Thread Nathan Sidwell via cfe-commits

https://github.com/urnathan created 
https://github.com/llvm/llvm-project/pull/74893

An 8 bit bitfield with preferred bool type? Seems confused.

>From f7cac332123f6ea6c78dcffbcac2d58f356b6396 Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Fri, 8 Dec 2023 17:43:22 -0500
Subject: [PATCH] [clang] Adjust TargetInfo bitfield

An 8 bit bitfield with preferred bool type? Seems confused.
---
 clang/include/clang/Basic/TargetInfo.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang/include/clang/Basic/TargetInfo.h 
b/clang/include/clang/Basic/TargetInfo.h
index 41f3c2e403cbe..ec0189627dfbd 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -266,7 +266,6 @@ class TargetInfo : public TransferrableTargetInfo,
   LLVM_PREFERRED_TYPE(bool)
   unsigned AllowAMDGPUUnsafeFPAtomics : 1;
 
-  LLVM_PREFERRED_TYPE(bool)
   unsigned ARMCDECoprocMask : 8;
 
   unsigned MaxOpenCLWorkGroupSize;

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


[clang] [clang] Adjust TargetInfo bitfield (PR #74893)

2023-12-09 Thread Nathan Sidwell via cfe-commits

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


[clang] [clang] Adjust TargetInfo bitfield (PR #74893)

2023-12-09 Thread Nathan Sidwell via cfe-commits

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


[clang] [clang] Better bitfield access units (PR #65742)

2023-12-10 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

Rebased

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


[clang] [clang][NFC] Adjust TBAA Base Info API (PR #73263)

2023-12-10 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

> I'd tend to prefer to keep the simpler name for the external interface, and 
> use a more complicated one for use within the class. So maybe introduce 
> getValidBaseTypeInfo().

This naming scheme better?

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


[clang] [clang] Better bitfield access units (PR #65742)

2023-11-14 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

thanks @yonghong-song!

Taking the opportunity for a ping :)

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


[llvm] [clang] Fix python escapes (PR #71170)

2023-11-19 Thread Nathan Sidwell via cfe-commits

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


[clang] [clang] Refactor TBAA Base Info construction (PR #70499)

2023-11-22 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

I'm going to break this apart, as I've realized this has conflated two separate 
problems.

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


[clang] [clang] Robustify openmp test (PR #69739)

2023-10-27 Thread Nathan Sidwell via cfe-commits

https://github.com/urnathan updated 
https://github.com/llvm/llvm-project/pull/69739

>From bb391aa466577f4187af6b284ee5107090778a03 Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Fri, 20 Oct 2023 11:43:08 -0400
Subject: [PATCH 1/2] [clang] Robustify open mp test

If the source path contains 'alias' this would spuriously fail.  Be
more specific about not wanting [no]alias annotations.
---
 clang/test/OpenMP/declare_variant_device_kind_codegen.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/OpenMP/declare_variant_device_kind_codegen.cpp 
b/clang/test/OpenMP/declare_variant_device_kind_codegen.cpp
index daa14f1e3a93129..aec71bd5b5da20e 100644
--- a/clang/test/OpenMP/declare_variant_device_kind_codegen.cpp
+++ b/clang/test/OpenMP/declare_variant_device_kind_codegen.cpp
@@ -80,7 +80,7 @@
 
 // expected-no-diagnostics
 
-// CHECK-NOT: alias
+// CHECK-NOT: {{ (no)?alias }}
 
 // CHECK-NOT: ret i32 {{1|4|81|84}}
 // CHECK-DAG: declare {{.*}}i32 @_Z5bazzzv()

>From 47ccce0676a39eb64e5305325d88b9b101e03a26 Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Fri, 27 Oct 2023 16:38:11 -0400
Subject: [PATCH 2/2] [clang] Robustify open mp test

If the source path contains 'alias' this would spuriously fail.  Be
more specific about not wanting global aliases, which is what
introduced this check.
---
 clang/test/OpenMP/declare_variant_device_kind_codegen.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/test/OpenMP/declare_variant_device_kind_codegen.cpp 
b/clang/test/OpenMP/declare_variant_device_kind_codegen.cpp
index aec71bd5b5da20e..4f9a86f1e0080d9 100644
--- a/clang/test/OpenMP/declare_variant_device_kind_codegen.cpp
+++ b/clang/test/OpenMP/declare_variant_device_kind_codegen.cpp
@@ -80,7 +80,8 @@
 
 // expected-no-diagnostics
 
-// CHECK-NOT: {{ (no)?alias }}
+// Verify no unexpected global symbol aliasing
+// CHECK-NOT: @{{[^ ]+}} = {{.*}}alias
 
 // CHECK-NOT: ret i32 {{1|4|81|84}}
 // CHECK-DAG: declare {{.*}}i32 @_Z5bazzzv()

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


[clang] [clang] Robustify openmp test (PR #69739)

2023-10-27 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

@jdoerfert thanks for that, here's an update that focusses the check-not more 
precisely.

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


[clang] [clang][NFC] Assert not llvm_unreachable (PR #70149)

2023-10-30 Thread Nathan Sidwell via cfe-commits

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


[clang] [clang] Robustify openmp test (PR #69739)

2023-10-30 Thread Nathan Sidwell via cfe-commits

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


[clang] [clang] Refactor TBAA Base Info construction (PR #70499)

2023-10-30 Thread Nathan Sidwell via cfe-commits

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


[clang] [clang] Better bitfield access units (PR #65742)

2023-10-30 Thread Nathan Sidwell via cfe-commits

urnathan wrote:


> One very brief note: in the comments in the code, you might want to 
> distinguish between the semantic width of a bitfield (i.e. the C standard 
> notion of a "memory location", which has ABI significance), vs. the accesses 
> we choose to generate (we don't need to generate no-op reads/writes).

Indeed, the naming here is unfortunately overloaded. SysV psABIs use 'Storage 
Unit' (at least 86 does, and IIRC others follow the same nomenclature).  But 
Clang also uses 'StorageInfo' and 'Storage$FOO' in its bitfield structures, 
which is unfortunate.  I've used 'Access Unit' to describe the latter in this 
patch.  If you meant something else, please clarify (or if I've missed some 
places?).


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


[llvm] [clang] Fix python escapes (PR #71170)

2023-11-03 Thread Nathan Sidwell via cfe-commits

https://github.com/urnathan created 
https://github.com/llvm/llvm-project/pull/71170

With Fedora 39, I encountered 2 new python warnings:

/home/nathan/gh/llvm/push/strict-aliasing/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py:28:
 SyntaxWarning: invalid escape sequence '\*'
  self.implementationContent += """

/home/nathan/gh/llvm/push/strict-aliasing/llvm/test/lit.cfg.py:274: 
SyntaxWarning: invalid escape sequence '\d'
  match = re.search("release (\d+)\.(\d+)", ptxas_out)

Use raw strings here. I guess python got pickier or something?

While there, might as well fix the blank line caused by """NEWLINE ...
""" by dropping its first char.

>From 9b5cb1ac8d4b9a2aaa4c06e41620e38b6c3cae8c Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Thu, 2 Nov 2023 18:14:05 -0400
Subject: [PATCH] Fix python escapes

With Fedora 39, I encountered 2 new python warnings:

/home/nathan/gh/llvm/push/strict-aliasing/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py:28:
 SyntaxWarning: invalid escape sequence '\*'
  self.implementationContent += """

/home/nathan/gh/llvm/push/strict-aliasing/llvm/test/lit.cfg.py:274: 
SyntaxWarning: invalid escape sequence '\d'
  match = re.search("release (\d+)\.(\d+)", ptxas_out)

Use raw strings here. I guess python got pickier or something?

May as well fix the blank line caused by """NEWLINE
...
"""
---
 clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py | 4 ++--
 llvm/test/lit.cfg.py| 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py 
b/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py
index dafb332961ede86..54cfd0741f9d122 100755
--- a/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py
+++ b/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py
@@ -25,7 +25,7 @@ def __init__(self, templateClasses):
 
 def GeneratePrologue(self):
 
-self.implementationContent += """
+self.implementationContent += R"""
 /*===- Generated file ---*- C++ 
-*-===*\
 |*
*|
 |* Introspection of available AST node SourceLocations
*|
@@ -58,7 +58,7 @@ def GeneratePrologue(self):
 private:
 std::vector &TLRG;
 };
-"""
+"""[1:]
 
 def GenerateBaseGetLocationsDeclaration(self, CladeName):
 InstanceDecoration = "*"
diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py
index ab245b71cdd16a5..cf050bbfe3b1413 100644
--- a/llvm/test/lit.cfg.py
+++ b/llvm/test/lit.cfg.py
@@ -271,7 +271,7 @@ def ptxas_version(ptxas):
 ptxas_cmd = subprocess.Popen([ptxas, "--version"], stdout=subprocess.PIPE)
 ptxas_out = ptxas_cmd.stdout.read().decode("ascii")
 ptxas_cmd.wait()
-match = re.search("release (\d+)\.(\d+)", ptxas_out)
+match = re.search(R"release (\d+)\.(\d+)", ptxas_out)
 if match:
 return (int(match.group(1)), int(match.group(2)))
 print("couldn't determine ptxas version")

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


[llvm] [clang] Fix python escapes (PR #71170)

2023-11-03 Thread Nathan Sidwell via cfe-commits

https://github.com/urnathan updated 
https://github.com/llvm/llvm-project/pull/71170

>From 9b5cb1ac8d4b9a2aaa4c06e41620e38b6c3cae8c Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Thu, 2 Nov 2023 18:14:05 -0400
Subject: [PATCH 1/2] Fix python escapes

With Fedora 39, I encountered 2 new python warnings:

/home/nathan/gh/llvm/push/strict-aliasing/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py:28:
 SyntaxWarning: invalid escape sequence '\*'
  self.implementationContent += """

/home/nathan/gh/llvm/push/strict-aliasing/llvm/test/lit.cfg.py:274: 
SyntaxWarning: invalid escape sequence '\d'
  match = re.search("release (\d+)\.(\d+)", ptxas_out)

Use raw strings here. I guess python got pickier or something?

May as well fix the blank line caused by """NEWLINE
...
"""
---
 clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py | 4 ++--
 llvm/test/lit.cfg.py| 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py 
b/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py
index dafb332961ede86..54cfd0741f9d122 100755
--- a/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py
+++ b/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py
@@ -25,7 +25,7 @@ def __init__(self, templateClasses):
 
 def GeneratePrologue(self):
 
-self.implementationContent += """
+self.implementationContent += R"""
 /*===- Generated file ---*- C++ 
-*-===*\
 |*
*|
 |* Introspection of available AST node SourceLocations
*|
@@ -58,7 +58,7 @@ def GeneratePrologue(self):
 private:
 std::vector &TLRG;
 };
-"""
+"""[1:]
 
 def GenerateBaseGetLocationsDeclaration(self, CladeName):
 InstanceDecoration = "*"
diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py
index ab245b71cdd16a5..cf050bbfe3b1413 100644
--- a/llvm/test/lit.cfg.py
+++ b/llvm/test/lit.cfg.py
@@ -271,7 +271,7 @@ def ptxas_version(ptxas):
 ptxas_cmd = subprocess.Popen([ptxas, "--version"], stdout=subprocess.PIPE)
 ptxas_out = ptxas_cmd.stdout.read().decode("ascii")
 ptxas_cmd.wait()
-match = re.search("release (\d+)\.(\d+)", ptxas_out)
+match = re.search(R"release (\d+)\.(\d+)", ptxas_out)
 if match:
 return (int(match.group(1)), int(match.group(2)))
 print("couldn't determine ptxas version")

>From 0cf6eb5b293752525cace1dee1ba26e143386809 Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Fri, 3 Nov 2023 07:44:11 -0400
Subject: [PATCH 2/2] Lower case raw string

---
 clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py | 2 +-
 llvm/test/lit.cfg.py| 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py 
b/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py
index 54cfd0741f9d122..a6843f70adedae9 100755
--- a/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py
+++ b/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py
@@ -25,7 +25,7 @@ def __init__(self, templateClasses):
 
 def GeneratePrologue(self):
 
-self.implementationContent += R"""
+self.implementationContent += r"""
 /*===- Generated file ---*- C++ 
-*-===*\
 |*
*|
 |* Introspection of available AST node SourceLocations
*|
diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py
index cf050bbfe3b1413..5f4cff424f073b8 100644
--- a/llvm/test/lit.cfg.py
+++ b/llvm/test/lit.cfg.py
@@ -271,7 +271,7 @@ def ptxas_version(ptxas):
 ptxas_cmd = subprocess.Popen([ptxas, "--version"], stdout=subprocess.PIPE)
 ptxas_out = ptxas_cmd.stdout.read().decode("ascii")
 ptxas_cmd.wait()
-match = re.search(R"release (\d+)\.(\d+)", ptxas_out)
+match = re.search(r"release (\d+)\.(\d+)", ptxas_out)
 if match:
 return (int(match.group(1)), int(match.group(2)))
 print("couldn't determine ptxas version")

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


[llvm] [clang] Fix python escapes (PR #71170)

2023-11-03 Thread Nathan Sidwell via cfe-commits

https://github.com/urnathan updated 
https://github.com/llvm/llvm-project/pull/71170

>From 9b5cb1ac8d4b9a2aaa4c06e41620e38b6c3cae8c Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Thu, 2 Nov 2023 18:14:05 -0400
Subject: [PATCH 1/3] Fix python escapes

With Fedora 39, I encountered 2 new python warnings:

/home/nathan/gh/llvm/push/strict-aliasing/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py:28:
 SyntaxWarning: invalid escape sequence '\*'
  self.implementationContent += """

/home/nathan/gh/llvm/push/strict-aliasing/llvm/test/lit.cfg.py:274: 
SyntaxWarning: invalid escape sequence '\d'
  match = re.search("release (\d+)\.(\d+)", ptxas_out)

Use raw strings here. I guess python got pickier or something?

May as well fix the blank line caused by """NEWLINE
...
"""
---
 clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py | 4 ++--
 llvm/test/lit.cfg.py| 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py 
b/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py
index dafb332961ede86..54cfd0741f9d122 100755
--- a/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py
+++ b/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py
@@ -25,7 +25,7 @@ def __init__(self, templateClasses):
 
 def GeneratePrologue(self):
 
-self.implementationContent += """
+self.implementationContent += R"""
 /*===- Generated file ---*- C++ 
-*-===*\
 |*
*|
 |* Introspection of available AST node SourceLocations
*|
@@ -58,7 +58,7 @@ def GeneratePrologue(self):
 private:
 std::vector &TLRG;
 };
-"""
+"""[1:]
 
 def GenerateBaseGetLocationsDeclaration(self, CladeName):
 InstanceDecoration = "*"
diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py
index ab245b71cdd16a5..cf050bbfe3b1413 100644
--- a/llvm/test/lit.cfg.py
+++ b/llvm/test/lit.cfg.py
@@ -271,7 +271,7 @@ def ptxas_version(ptxas):
 ptxas_cmd = subprocess.Popen([ptxas, "--version"], stdout=subprocess.PIPE)
 ptxas_out = ptxas_cmd.stdout.read().decode("ascii")
 ptxas_cmd.wait()
-match = re.search("release (\d+)\.(\d+)", ptxas_out)
+match = re.search(R"release (\d+)\.(\d+)", ptxas_out)
 if match:
 return (int(match.group(1)), int(match.group(2)))
 print("couldn't determine ptxas version")

>From 0cf6eb5b293752525cace1dee1ba26e143386809 Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Fri, 3 Nov 2023 07:44:11 -0400
Subject: [PATCH 2/3] Lower case raw string

---
 clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py | 2 +-
 llvm/test/lit.cfg.py| 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py 
b/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py
index 54cfd0741f9d122..a6843f70adedae9 100755
--- a/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py
+++ b/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py
@@ -25,7 +25,7 @@ def __init__(self, templateClasses):
 
 def GeneratePrologue(self):
 
-self.implementationContent += R"""
+self.implementationContent += r"""
 /*===- Generated file ---*- C++ 
-*-===*\
 |*
*|
 |* Introspection of available AST node SourceLocations
*|
diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py
index cf050bbfe3b1413..5f4cff424f073b8 100644
--- a/llvm/test/lit.cfg.py
+++ b/llvm/test/lit.cfg.py
@@ -271,7 +271,7 @@ def ptxas_version(ptxas):
 ptxas_cmd = subprocess.Popen([ptxas, "--version"], stdout=subprocess.PIPE)
 ptxas_out = ptxas_cmd.stdout.read().decode("ascii")
 ptxas_cmd.wait()
-match = re.search(R"release (\d+)\.(\d+)", ptxas_out)
+match = re.search(r"release (\d+)\.(\d+)", ptxas_out)
 if match:
 return (int(match.group(1)), int(match.group(2)))
 print("couldn't determine ptxas version")

>From c483141c81052828a1a3793377b0bffdb2300a65 Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Fri, 3 Nov 2023 08:18:33 -0400
Subject: [PATCH 3/3] lose [1:]

---
 clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py 
b/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py
index a6843f70adedae9..7671f9691c09610 100755
--- a/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py
+++ b/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py
@@ -58,7 +58,7 @@ def GeneratePrologue(self):
 private:
 std::vector &TLRG;
 };
-"""[1:]
+"""
 
 def GenerateBaseGetLocationsDeclaration(self, CladeName):
 InstanceDecoration = "*"

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm

[llvm] [clang] Fix python escapes (PR #71170)

2023-11-03 Thread Nathan Sidwell via cfe-commits

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


[llvm] [clang] Fix python escapes (PR #71170)

2023-11-03 Thread Nathan Sidwell via cfe-commits

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


[clang] [clang] Strict aliasing warning ala GCC [PR50066] (PR #74155)

2023-12-15 Thread Nathan Sidwell via cfe-commits


@@ -37,6 +38,27 @@ class ASTConsumer {
 
   friend class SemaConsumer;
 
+public:
+  /// Allow type-based aliasing information to be interrogated by the AST
+  /// producer (for diagnostics).
+  class TypeAliasing {

urnathan wrote:

Oh, we also endup deriving from the TypeAliasing class to override the virtual 
function it provides.

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


[clang] [clang] Strict aliasing warning ala GCC [PR50066] (PR #74155)

2023-12-15 Thread Nathan Sidwell via cfe-commits


@@ -498,3 +498,137 @@ 
CodeGenTBAA::mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo,
   // access type regardless of their base types.
   return TBAAAccessInfo::getMayAliasInfo();
 }
+
+// Determine the aliasing kind bit-converting from type Src to type Dst.
+CodeGenTBAA::AliasingKind CodeGenTBAA::getAliasingKind(QualType &Dst,
+   QualType &Src) {
+  assert(!Src->isVoidType() && !Dst->isVoidType());
+  if (TypeHasMayAlias(Src) || TypeHasMayAlias(Dst))
+return AK_Ok;
+
+  Src = QualType{Src->getBaseElementTypeUnsafe(), 0};
+  Dst = QualType{Dst->getBaseElementTypeUnsafe(), 0};
+
+  auto *SrcDecl = Src->getAsRecordDecl();
+  auto *DstDecl = Dst->getAsRecordDecl();
+
+  const llvm::MDNode *AnyTBAA = getChar();
+  const llvm::MDNode *SrcTBAA = nullptr;
+  const llvm::MDNode *DstTBAA = nullptr;
+
+  if (!SrcDecl) {
+SrcTBAA = getTypeInfo(Src);
+if (!SrcTBAA || SrcTBAA == AnyTBAA)

urnathan wrote:

Pedantically 'signed char' is not blessed with that property by the std.  But 
many compilers (llvm included) bestow it upon signed char.  Indeed this 
particular patch doesn't make a judgement on that, it just gets the aliasing 
info for 'signed char' and it happens to get the same ubiquitous char tbaa.

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


[clang] [clang] Strict aliasing warning ala GCC [PR50066] (PR #74155)

2023-12-15 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

> > > FWIW the GCC doc is 
> > > https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wstrict-aliasing_003dn
> > >  It says for Level 3 "If optimization is enabled, it also runs in the 
> > > back end, where it deals with multiple statement cases using 
> > > flow-sensitive points-to information."
> > > Do you know how it works? Any example?
> > 
> > 
> > I do not now how it works -- didn't go poking there. Neither do I have 
> > examples.
> 
> My understanding (which could be totally wrong) is that the logic for when to 
> emit the level 3 diagnostics rests mostly in the optimizer passes. This is 
> not something I think Clang should emulate as it creates a very poor user 
> experience in practice (not just with strict aliasing diagnostics -- I don't 
> think _any_ diagnostics other than remarks should be emitted based on LLVM 
> optimization decisions aside from the `error` and `warning` attributes which 
> are special circumstances).

I don't know if it's 'mostly', the level 3 can certainly be triggered in the FE 
-- it requires (a) an address-of-object idiom, (b) a suspicious cast and (c) a 
dereference.  Something like `*reinterpret_cast(&obj) = 5`, where `obj` 
is  not compatible with `int`. That's what this patch implements. (In GCC's 
case when it warns about this in the FE it marks the tree as warned, to inhibit 
the middle end also doing so.)



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


[clang] [clang][NFC] Adjust TBAA Base Info API (PR #73263)

2023-11-23 Thread Nathan Sidwell via cfe-commits

https://github.com/urnathan created 
https://github.com/llvm/llvm-project/pull/73263

I noticed a couple of minor issues with CodeGenTBAA::getBaseTypeInfo.

1) isValidBaseType explicitly checks for a reference type to return false, but 
then also returns false for all non-record types. Just remove that reference 
check.

2) All uses of CodeGenTBAA::getBaseTypeInfo from within that class are when 
we've already checked the type isValidBaseType. The only case where this isn't 
true is from outside the class. It seems better to have two entry points in 
this case.  Adding a new
'maybeGetBaseTypeInfo' entry point for external uses that returns nullptr for 
non valid base types.  (Open to other names?)

[This is part one of a pair of changes.]

>From 2a312ddadae91ea52b184edaa0d19495c6e0f4a3 Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Wed, 22 Nov 2023 20:45:38 -0500
Subject: [PATCH] [clang][NFC] Adjust TBAA Base Info API

I noticed a couple of minor issues with CodeGenTBAA::getBaseTypeInfo.

1) isValidBaseType explicitly checks for a reference type to return
false, but then also returns false for all non-record types. Just
remove that reference check.

2) All uses of CodeGenTBAA::getBaseTypeInfo from within that class are
when we've already checked the type isValidBaseType. The only case
where this isn't true is from outside the class. It seems better to
have two entry points in this case.  Adding a new
'maybeGetBaseTypeInfo' entry point for external uses that returns
nullptr for non valid base types.  (Open to other names?)

[This is part one of a pair of changes.]
---
 clang/lib/CodeGen/CodeGenModule.cpp |  2 +-
 clang/lib/CodeGen/CodeGenTBAA.cpp   |  9 +
 clang/lib/CodeGen/CodeGenTBAA.h | 11 ---
 3 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 7cdf50a281cd278..e01fdc3579d88b8 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1318,7 +1318,7 @@ llvm::MDNode *CodeGenModule::getTBAAStructInfo(QualType 
QTy) {
 llvm::MDNode *CodeGenModule::getTBAABaseTypeInfo(QualType QTy) {
   if (!TBAA)
 return nullptr;
-  return TBAA->getBaseTypeInfo(QTy);
+  return TBAA->maybeGetBaseTypeInfo(QTy);
 }
 
 llvm::MDNode *CodeGenModule::getTBAAAccessTagInfo(TBAAAccessInfo Info) {
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp 
b/clang/lib/CodeGen/CodeGenTBAA.cpp
index 8705d3d65f1a573..9b45a644937b8d9 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -95,8 +95,6 @@ static bool TypeHasMayAlias(QualType QTy) {
 
 /// Check if the given type is a valid base type to be used in access tags.
 static bool isValidBaseType(QualType QTy) {
-  if (QTy->isReferenceType())
-return false;
   if (const RecordType *TTy = QTy->getAs()) {
 const RecordDecl *RD = TTy->getDecl()->getDefinition();
 // Incomplete types are not valid base access types.
@@ -414,8 +412,7 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type 
*Ty) {
 }
 
 llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) {
-  if (!isValidBaseType(QTy))
-return nullptr;
+  assert(isValidBaseType(QTy) && "Must be a valid base type");
 
   const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
   if (llvm::MDNode *N = BaseTypeMetadataCache[Ty])
@@ -428,6 +425,10 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) {
   return BaseTypeMetadataCache[Ty] = TypeNode;
 }
 
+llvm::MDNode *CodeGenTBAA::maybeGetBaseTypeInfo(QualType QTy) {
+  return isValidBaseType(QTy) ? getBaseTypeInfo(QTy) : nullptr;
+}
+
 llvm::MDNode *CodeGenTBAA::getAccessTagInfo(TBAAAccessInfo Info) {
   assert(!Info.isIncomplete() && "Access to an object of an incomplete type!");
 
diff --git a/clang/lib/CodeGen/CodeGenTBAA.h b/clang/lib/CodeGen/CodeGenTBAA.h
index a65963596fe9def..53d77e1fefc4352 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.h
+++ b/clang/lib/CodeGen/CodeGenTBAA.h
@@ -166,6 +166,10 @@ class CodeGenTBAA {
   /// used to describe accesses to objects of the given base type.
   llvm::MDNode *getBaseTypeInfoHelper(const Type *Ty);
 
+  /// getBaseTypeInfo - Return metadata that describes the given base access
+  /// type. The type must be suitable.
+  llvm::MDNode *getBaseTypeInfo(QualType QTy);
+
 public:
   CodeGenTBAA(ASTContext &Ctx, llvm::Module &M, const CodeGenOptions &CGO,
   const LangOptions &Features, MangleContext &MContext);
@@ -187,9 +191,10 @@ class CodeGenTBAA {
   /// the given type.
   llvm::MDNode *getTBAAStructInfo(QualType QTy);
 
-  /// getBaseTypeInfo - Get metadata that describes the given base access type.
-  /// Return null if the type is not suitable for use in TBAA access tags.
-  llvm::MDNode *getBaseTypeInfo(QualType QTy);
+  /// maybeGetBaseTypeInfo - Get metadata that describes the given base access
+  /// type. Return null if the type is not suitable for use in TBAA access
+  /// tags.
+  llvm::MDNode *maybeGetBaseTyp

[clang] [clang] Avoid recalculating TBAA base type info (PR #73264)

2023-11-23 Thread Nathan Sidwell via cfe-commits

https://github.com/urnathan created 
https://github.com/llvm/llvm-project/pull/73264

I noticed that TBAA BaseTypeMetadataCache can legitimately store null values, 
but it also uses that to mean 'no entry'. Thus nullptr entries get continually 
recalculated. (AFAICT null entries can never become non-null.)  This changes 
the hash lookup/insertion to use find and try_emplace rather than the subscript 
operator.

While there, getBaseTypeInfoHelper will insert non-null values into the 
hashtable itself, but simply return nullptr values.  The only caller, 
getBaseTypeInfo unconditionally inserts the value anyway. It seems clearer to 
let getBaseTypeInfo do the insertion and getBaseTypeInfoHelper merely computes.

[This is the second of a pair of prs]

>From e4c92cd687782743ba939becf7ea8862eea6a108 Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Thu, 23 Nov 2023 11:30:12 -0500
Subject: [PATCH] [clang] Avoid recalculating TBAA base type info

I noticed that TBAA BaseTypeMetadataCache can legitimately store null
values, but it also uses that to mean 'no entry'. Thus nullptr entries
get continually recalculated. (AFAICT null entries can never become
non-null.)  This changes the hash lookup/insertion to use find and
try_emplace rather than the subscript operator.

While there, getBaseTypeInfoHelper will insert non-null values into
the hashtable itself, but simply return nullptr values.  The only
caller, getBaseTypeInfo unconditionally inserts the value anyway. It
seems clearer to let getBaseTypeInfo do the insertion and
getBaseTypeInfoHelper merely computes.
---
 clang/lib/CodeGen/CodeGenTBAA.cpp | 24 +++-
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp 
b/clang/lib/CodeGen/CodeGenTBAA.cpp
index 8705d3d65f1a573..94dc304bfc243b9 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -342,7 +342,7 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type 
*Ty) {
   // field. Virtual bases are more complex and omitted, but avoid an
   // incomplete view for NewStructPathTBAA.
   if (CodeGenOpts.NewStructPathTBAA && CXXRD->getNumVBases() != 0)
-return BaseTypeMetadataCache[Ty] = nullptr;
+return nullptr;
   for (const CXXBaseSpecifier &B : CXXRD->bases()) {
 if (B.isVirtual())
   continue;
@@ -354,7 +354,7 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type 
*Ty) {
  ? getBaseTypeInfo(BaseQTy)
  : getTypeInfo(BaseQTy);
 if (!TypeNode)
-  return BaseTypeMetadataCache[Ty] = nullptr;
+  return nullptr;
 uint64_t Offset = Layout.getBaseClassOffset(BaseRD).getQuantity();
 uint64_t Size =
 Context.getASTRecordLayout(BaseRD).getDataSize().getQuantity();
@@ -378,7 +378,7 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type 
*Ty) {
   llvm::MDNode *TypeNode = isValidBaseType(FieldQTy) ?
   getBaseTypeInfo(FieldQTy) : getTypeInfo(FieldQTy);
   if (!TypeNode)
-return BaseTypeMetadataCache[Ty] = nullptr;
+return nullptr;
 
   uint64_t BitOffset = Layout.getFieldOffset(Field->getFieldIndex());
   uint64_t Offset = Context.toCharUnitsFromBits(BitOffset).getQuantity();
@@ -418,14 +418,20 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) {
 return nullptr;
 
   const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
-  if (llvm::MDNode *N = BaseTypeMetadataCache[Ty])
-return N;
 
-  // Note that the following helper call is allowed to add new nodes to the
-  // cache, which invalidates all its previously obtained iterators. So we
-  // first generate the node for the type and then add that node to the cache.
+  // nullptr is a valid value in the cache, so use find rather than []
+  auto I = BaseTypeMetadataCache.find(Ty);
+  if (I != BaseTypeMetadataCache.end())
+return I->second;
+
+  // First calculate the metadata, before recomputing the insertion point, as
+  // the helper can recursively call us.
   llvm::MDNode *TypeNode = getBaseTypeInfoHelper(Ty);
-  return BaseTypeMetadataCache[Ty] = TypeNode;
+  LLVM_ATTRIBUTE_UNUSED auto inserted =
+  BaseTypeMetadataCache.try_emplace(Ty, TypeNode);
+  assert(inserted.second && "BaseType metadata was already inserted");
+
+  return TypeNode;
 }
 
 llvm::MDNode *CodeGenTBAA::getAccessTagInfo(TBAAAccessInfo Info) {

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


[clang] [clang] Refactor TBAA Base Info construction (PR #70499)

2023-11-23 Thread Nathan Sidwell via cfe-commits

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


[clang] [clang][NFC] Adjust TBAA Base Info API (PR #73263)

2023-11-24 Thread Nathan Sidwell via cfe-commits

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


[clang] [clang] Avoid recalculating TBAA base type info (PR #73264)

2023-11-24 Thread Nathan Sidwell via cfe-commits

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


[clang] [clang] Avoid recalculating TBAA base type info (PR #73264)

2023-12-01 Thread Nathan Sidwell via cfe-commits

https://github.com/urnathan updated 
https://github.com/llvm/llvm-project/pull/73264

>From e4c92cd687782743ba939becf7ea8862eea6a108 Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Thu, 23 Nov 2023 11:30:12 -0500
Subject: [PATCH 1/2] [clang] Avoid recalculating TBAA base type info

I noticed that TBAA BaseTypeMetadataCache can legitimately store null
values, but it also uses that to mean 'no entry'. Thus nullptr entries
get continually recalculated. (AFAICT null entries can never become
non-null.)  This changes the hash lookup/insertion to use find and
try_emplace rather than the subscript operator.

While there, getBaseTypeInfoHelper will insert non-null values into
the hashtable itself, but simply return nullptr values.  The only
caller, getBaseTypeInfo unconditionally inserts the value anyway. It
seems clearer to let getBaseTypeInfo do the insertion and
getBaseTypeInfoHelper merely computes.
---
 clang/lib/CodeGen/CodeGenTBAA.cpp | 24 +++-
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp 
b/clang/lib/CodeGen/CodeGenTBAA.cpp
index 8705d3d65f1a573..94dc304bfc243b9 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -342,7 +342,7 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type 
*Ty) {
   // field. Virtual bases are more complex and omitted, but avoid an
   // incomplete view for NewStructPathTBAA.
   if (CodeGenOpts.NewStructPathTBAA && CXXRD->getNumVBases() != 0)
-return BaseTypeMetadataCache[Ty] = nullptr;
+return nullptr;
   for (const CXXBaseSpecifier &B : CXXRD->bases()) {
 if (B.isVirtual())
   continue;
@@ -354,7 +354,7 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type 
*Ty) {
  ? getBaseTypeInfo(BaseQTy)
  : getTypeInfo(BaseQTy);
 if (!TypeNode)
-  return BaseTypeMetadataCache[Ty] = nullptr;
+  return nullptr;
 uint64_t Offset = Layout.getBaseClassOffset(BaseRD).getQuantity();
 uint64_t Size =
 Context.getASTRecordLayout(BaseRD).getDataSize().getQuantity();
@@ -378,7 +378,7 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type 
*Ty) {
   llvm::MDNode *TypeNode = isValidBaseType(FieldQTy) ?
   getBaseTypeInfo(FieldQTy) : getTypeInfo(FieldQTy);
   if (!TypeNode)
-return BaseTypeMetadataCache[Ty] = nullptr;
+return nullptr;
 
   uint64_t BitOffset = Layout.getFieldOffset(Field->getFieldIndex());
   uint64_t Offset = Context.toCharUnitsFromBits(BitOffset).getQuantity();
@@ -418,14 +418,20 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) {
 return nullptr;
 
   const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
-  if (llvm::MDNode *N = BaseTypeMetadataCache[Ty])
-return N;
 
-  // Note that the following helper call is allowed to add new nodes to the
-  // cache, which invalidates all its previously obtained iterators. So we
-  // first generate the node for the type and then add that node to the cache.
+  // nullptr is a valid value in the cache, so use find rather than []
+  auto I = BaseTypeMetadataCache.find(Ty);
+  if (I != BaseTypeMetadataCache.end())
+return I->second;
+
+  // First calculate the metadata, before recomputing the insertion point, as
+  // the helper can recursively call us.
   llvm::MDNode *TypeNode = getBaseTypeInfoHelper(Ty);
-  return BaseTypeMetadataCache[Ty] = TypeNode;
+  LLVM_ATTRIBUTE_UNUSED auto inserted =
+  BaseTypeMetadataCache.try_emplace(Ty, TypeNode);
+  assert(inserted.second && "BaseType metadata was already inserted");
+
+  return TypeNode;
 }
 
 llvm::MDNode *CodeGenTBAA::getAccessTagInfo(TBAAAccessInfo Info) {

>From fee3b7407ab6fe73476eed82e387cceb9b6ef88c Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Fri, 1 Dec 2023 15:58:51 -0500
Subject: [PATCH 2/2] Use insert not try_emplace

---
 clang/lib/CodeGen/CodeGenTBAA.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp 
b/clang/lib/CodeGen/CodeGenTBAA.cpp
index 94dc304bfc243b9..5906b14dd93cf08 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -428,7 +428,7 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) {
   // the helper can recursively call us.
   llvm::MDNode *TypeNode = getBaseTypeInfoHelper(Ty);
   LLVM_ATTRIBUTE_UNUSED auto inserted =
-  BaseTypeMetadataCache.try_emplace(Ty, TypeNode);
+  BaseTypeMetadataCache.insert({Ty, TypeNode});
   assert(inserted.second && "BaseType metadata was already inserted");
 
   return TypeNode;

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


[clang] [clang] Avoid recalculating TBAA base type info (PR #73264)

2023-12-01 Thread Nathan Sidwell via cfe-commits


@@ -418,14 +418,20 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) {
 return nullptr;
 
   const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
-  if (llvm::MDNode *N = BaseTypeMetadataCache[Ty])
-return N;
 
-  // Note that the following helper call is allowed to add new nodes to the
-  // cache, which invalidates all its previously obtained iterators. So we
-  // first generate the node for the type and then add that node to the cache.
+  // nullptr is a valid value in the cache, so use find rather than []
+  auto I = BaseTypeMetadataCache.find(Ty);
+  if (I != BaseTypeMetadataCache.end())
+return I->second;
+
+  // First calculate the metadata, before recomputing the insertion point, as
+  // the helper can recursively call us.
   llvm::MDNode *TypeNode = getBaseTypeInfoHelper(Ty);
-  return BaseTypeMetadataCache[Ty] = TypeNode;
+  LLVM_ATTRIBUTE_UNUSED auto inserted =
+  BaseTypeMetadataCache.try_emplace(Ty, TypeNode);

urnathan wrote:

done, will push when tests complete

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


[clang] [clang][NFC] Adjust TBAA Base Info API (PR #73263)

2023-12-01 Thread Nathan Sidwell via cfe-commits

https://github.com/urnathan updated 
https://github.com/llvm/llvm-project/pull/73263

>From 2a312ddadae91ea52b184edaa0d19495c6e0f4a3 Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Wed, 22 Nov 2023 20:45:38 -0500
Subject: [PATCH 1/2] [clang][NFC] Adjust TBAA Base Info API

I noticed a couple of minor issues with CodeGenTBAA::getBaseTypeInfo.

1) isValidBaseType explicitly checks for a reference type to return
false, but then also returns false for all non-record types. Just
remove that reference check.

2) All uses of CodeGenTBAA::getBaseTypeInfo from within that class are
when we've already checked the type isValidBaseType. The only case
where this isn't true is from outside the class. It seems better to
have two entry points in this case.  Adding a new
'maybeGetBaseTypeInfo' entry point for external uses that returns
nullptr for non valid base types.  (Open to other names?)

[This is part one of a pair of changes.]
---
 clang/lib/CodeGen/CodeGenModule.cpp |  2 +-
 clang/lib/CodeGen/CodeGenTBAA.cpp   |  9 +
 clang/lib/CodeGen/CodeGenTBAA.h | 11 ---
 3 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 7cdf50a281cd278..e01fdc3579d88b8 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1318,7 +1318,7 @@ llvm::MDNode *CodeGenModule::getTBAAStructInfo(QualType 
QTy) {
 llvm::MDNode *CodeGenModule::getTBAABaseTypeInfo(QualType QTy) {
   if (!TBAA)
 return nullptr;
-  return TBAA->getBaseTypeInfo(QTy);
+  return TBAA->maybeGetBaseTypeInfo(QTy);
 }
 
 llvm::MDNode *CodeGenModule::getTBAAAccessTagInfo(TBAAAccessInfo Info) {
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp 
b/clang/lib/CodeGen/CodeGenTBAA.cpp
index 8705d3d65f1a573..9b45a644937b8d9 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -95,8 +95,6 @@ static bool TypeHasMayAlias(QualType QTy) {
 
 /// Check if the given type is a valid base type to be used in access tags.
 static bool isValidBaseType(QualType QTy) {
-  if (QTy->isReferenceType())
-return false;
   if (const RecordType *TTy = QTy->getAs()) {
 const RecordDecl *RD = TTy->getDecl()->getDefinition();
 // Incomplete types are not valid base access types.
@@ -414,8 +412,7 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type 
*Ty) {
 }
 
 llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) {
-  if (!isValidBaseType(QTy))
-return nullptr;
+  assert(isValidBaseType(QTy) && "Must be a valid base type");
 
   const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
   if (llvm::MDNode *N = BaseTypeMetadataCache[Ty])
@@ -428,6 +425,10 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) {
   return BaseTypeMetadataCache[Ty] = TypeNode;
 }
 
+llvm::MDNode *CodeGenTBAA::maybeGetBaseTypeInfo(QualType QTy) {
+  return isValidBaseType(QTy) ? getBaseTypeInfo(QTy) : nullptr;
+}
+
 llvm::MDNode *CodeGenTBAA::getAccessTagInfo(TBAAAccessInfo Info) {
   assert(!Info.isIncomplete() && "Access to an object of an incomplete type!");
 
diff --git a/clang/lib/CodeGen/CodeGenTBAA.h b/clang/lib/CodeGen/CodeGenTBAA.h
index a65963596fe9def..53d77e1fefc4352 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.h
+++ b/clang/lib/CodeGen/CodeGenTBAA.h
@@ -166,6 +166,10 @@ class CodeGenTBAA {
   /// used to describe accesses to objects of the given base type.
   llvm::MDNode *getBaseTypeInfoHelper(const Type *Ty);
 
+  /// getBaseTypeInfo - Return metadata that describes the given base access
+  /// type. The type must be suitable.
+  llvm::MDNode *getBaseTypeInfo(QualType QTy);
+
 public:
   CodeGenTBAA(ASTContext &Ctx, llvm::Module &M, const CodeGenOptions &CGO,
   const LangOptions &Features, MangleContext &MContext);
@@ -187,9 +191,10 @@ class CodeGenTBAA {
   /// the given type.
   llvm::MDNode *getTBAAStructInfo(QualType QTy);
 
-  /// getBaseTypeInfo - Get metadata that describes the given base access type.
-  /// Return null if the type is not suitable for use in TBAA access tags.
-  llvm::MDNode *getBaseTypeInfo(QualType QTy);
+  /// maybeGetBaseTypeInfo - Get metadata that describes the given base access
+  /// type. Return null if the type is not suitable for use in TBAA access
+  /// tags.
+  llvm::MDNode *maybeGetBaseTypeInfo(QualType QTy);
 
   /// getAccessTagInfo - Get TBAA tag for a given memory access.
   llvm::MDNode *getAccessTagInfo(TBAAAccessInfo Info);

>From f4755f32880748100d0a3aa93836341033418f4d Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Fri, 1 Dec 2023 16:08:04 -0500
Subject: [PATCH 2/2] Rename internal getter to getValidBaseTypeInfo

---
 clang/lib/CodeGen/CodeGenModule.cpp |  2 +-
 clang/lib/CodeGen/CodeGenTBAA.cpp   | 18 ++
 clang/lib/CodeGen/CodeGenTBAA.h | 10 +-
 3 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index e01f

[clang] [clang][NFC] Adjust TBAA Base Info API (PR #73263)

2023-12-01 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

sure, like so?

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


[clang] [clang] Better bitfield access units (PR #65742)

2023-12-01 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

You knew this ping was coming, right?

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


[clang] [clang] Strict aliasing warning ala GCC [PR50066] (PR #74155)

2023-12-01 Thread Nathan Sidwell via cfe-commits

https://github.com/urnathan created 
https://github.com/llvm/llvm-project/pull/74155

This implements -Wstrict-aliasing(=[123])? along the same lines as GCC. It's 
not 100% the same for reasons expanded on below. The default is level 3, and I 
have verified that bootstrapping does not trigger any warnings (just like 
building with GCC).

As with GCC, higher levels result in fewer warnings, reducing the number of 
false positives at the cost of missing (some) potential cases. Unlike GCC, this 
is entirely in the FE, we do not propagate any checking into the IR (so there 
are cases GCC will detect we do not, I have not encountered any). GCC's 
documentation is not very specific about which cases are detected. I examined 
GCC's source code to reverse engineer the algorithm[*], and as can be seen from 
the testcases, noted GCC's behaviour.

The strict aliasing check relies on TBAA. LLVM's representation is semantically 
different to GCCs for structured types. I have tried to keep with the spirit of 
the warning.

The warning checks reinterpret_casts that are CK_BitCast or CK_LValueBitCast. 
It also checks C-style casts that are equivalent (to the extent available, as a 
C-style bitcast could be a well-formed static cast).

level=1 looks for reinterpret casts from T * to U * (or an lvalue of type T to 
U &), where T and U are not TBAA compatible.

level=2 requires the src expression be an lvalue something of known(ish) static 
type. I.e a variable, array dereference or member access.

level=3 requires level 2 and that the resultant pointer is actually referenced 
(lvalue->rvalue or lvalue written). Here we can do better than GCC, which 
doesn't represent this in the IR -- we merely get a dereference (and reference 
types are modeled as pointers with auto-dereference semantics). There is one 
exception to this, which is by-value aggregate arguments. These end up invoking 
a copy constructor (passing a reference of course), but are IMHO morally an 
rvalue -- so should trigger.

The warning hooks into clang's code-generator's TBAA machinery. For scalar 
types the TBAA is straight forwards, comparing LLVM's MDNode representaion. For 
record & union types we check if one of the types is (recursively) the same (or 
TBAA compatible) as the first direct base or a field(s) of the record at offset 
zero (i.e. the first member of a record, or any members of a union). This 
covers both C++ and C-Style inheritance. Also. the member maybe alias_any, or 
in ubiquitous-char's alias set, which is also permissible.

The warning is similar to the alignment check that 
CheckCompatibleReinterpretCast does, perhaps some merging could occur if this 
is accepted?

[*] I implemented what turned into GCC's level=1 way back when.

WIP: adjust tests

>From 89c05618bb75fd073343046f3b54bde5f2254719 Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Wed, 15 Nov 2023 15:27:16 -0500
Subject: [PATCH] [clang] Strict aliasing warning ala GCC [PR50066]

This implements -Wstrict-aliasing(=[123])? along the same lines as
GCC. It's not 100% the same for reasons expanded on below. The default
is level 3, and I have verified that bootstrapping does not trigger
any warnings (just like building with GCC).

As with GCC, higher levels result in fewer warnings, reducing the
number of false positives at the cost of missing (some) potential
cases. Unlike GCC, this is entirely in the FE, we do not propagate any
checking into the IR (so there are cases GCC will detect we do not, I
have not encountered any). GCC's documentation is not very specific
about which cases are detected. I examined GCC's source code to reverse
engineer the algorithm[*], and as can be seen from the testcases, noted
GCC's behaviour.

The strict aliasing check relies on TBAA. LLVM's representation is
semantically different to GCCs for structured types. I have tried to
keep with the spirit of the warning.

The warning checks reinterpret_casts that are CK_BitCast or
CK_LValueBitCast. It also checks C-style casts that are equivalent (to
the extent available, as a C-style bitcast could be a well-formed
static cast).

level=1 looks for reinterpret casts from T * to U * (or an lvalue of
type T to U &), where T and U are not TBAA compatible.

level=2 requires the src expression be an lvalue something of
known(ish) static type. I.e a variable, array dereference or member
access.

level=3 requires level 2 and that the resultant pointer is actually
referenced (lvalue->rvalue or lvalue written). Here we can do better
than GCC, which doesn't represent this in the IR -- we merely get a
dereference (and reference types are modeled as pointers with
auto-dereference semantics). There is one exception to this, which is
by-value aggregate arguments. These end up invoking a copy constructor
(passing a reference of course), but are IMHO morally an rvalue -- so
should trigger.

The warning hooks into clang's code-generator's TBAA machinery. For
scalar types the TBAA is straight forwards, comparing LLVM's MD

[clang] [clang] Avoid recalculating TBAA base type info (PR #73264)

2023-12-02 Thread Nathan Sidwell via cfe-commits

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


[clang] [clang] Strict aliasing warning ala GCC [PR50066] (PR #74155)

2023-12-02 Thread Nathan Sidwell via cfe-commits

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


[clang] [clang] Strict aliasing warning ala GCC [PR50066] (PR #74155)

2023-12-02 Thread Nathan Sidwell via cfe-commits

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


[clang] [clang][NFC] Adjust TBAA Base Info API (PR #73263)

2023-12-22 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

ping?

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


[clang] [clang] Better bitfield access units (PR #65742)

2023-12-22 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

ping?

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


[clang] [clang][NFC] Adjust TBAA Base Info API (PR #73263)

2024-01-05 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

@efriedma-quic this naming ok?

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


[clang] [clang] Better bitfield access units (PR #65742)

2024-01-05 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

Can someone please review this?

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


[clang] [clang][NFC] Adjust TBAA Base Info API (PR #73263)

2024-01-10 Thread Nathan Sidwell via cfe-commits


@@ -95,8 +95,6 @@ static bool TypeHasMayAlias(QualType QTy) {
 
 /// Check if the given type is a valid base type to be used in access tags.
 static bool isValidBaseType(QualType QTy) {
-  if (QTy->isReferenceType())
-return false;

urnathan wrote:

This is case  #1 in the intro. Namely this is immediately followed by 
```
 if (const RecordType *TTy = QTy->getAs()) {
   .. do stuff
   return true;
}
return false;
```
So AFAICT that inital check for a reference type is doing nothing.  Am I 
misunderstanding getAs and that it's possible for a type to be both 
RecordType and ReferenceType?

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


[clang] de867c6 - [clang] Reformat

2022-03-24 Thread Nathan Sidwell via cfe-commits

Author: Nathan Sidwell
Date: 2022-03-24T05:56:23-07:00
New Revision: de867c6d6ed86851dcd0f9de1154db3d42a0ad63

URL: 
https://github.com/llvm/llvm-project/commit/de867c6d6ed86851dcd0f9de1154db3d42a0ad63
DIFF: 
https://github.com/llvm/llvm-project/commit/de867c6d6ed86851dcd0f9de1154db3d42a0ad63.diff

LOG: [clang] Reformat

Reformat some misindentation that is coincidentally close to a piece
being worked on.

Reviewed By: dblaikie

Differential Revision: https://reviews.llvm.org/D122314

Added: 


Modified: 
clang/lib/Index/USRGeneration.cpp

Removed: 




diff  --git a/clang/lib/Index/USRGeneration.cpp 
b/clang/lib/Index/USRGeneration.cpp
index 41edd431dd5b8..129114ebfaedc 100644
--- a/clang/lib/Index/USRGeneration.cpp
+++ b/clang/lib/Index/USRGeneration.cpp
@@ -549,22 +549,22 @@ void USRGenerator::VisitTagDecl(const TagDecl *D) {
 if (const TypedefNameDecl *TD = D->getTypedefNameForAnonDecl()) {
   Buf[off] = 'A';
   Out << '@' << *TD;
-}
-  else {
-if (D->isEmbeddedInDeclarator() && !D->isFreeStanding()) {
-  printLoc(Out, D->getLocation(), Context->getSourceManager(), true);
 } else {
-  Buf[off] = 'a';
-  if (auto *ED = dyn_cast(D)) {
-// Distinguish USRs of anonymous enums by using their first enumerator.
-auto enum_range = ED->enumerators();
-if (enum_range.begin() != enum_range.end()) {
-  Out << '@' << **enum_range.begin();
+  if (D->isEmbeddedInDeclarator() && !D->isFreeStanding()) {
+printLoc(Out, D->getLocation(), Context->getSourceManager(), true);
+  } else {
+Buf[off] = 'a';
+if (auto *ED = dyn_cast(D)) {
+  // Distinguish USRs of anonymous enums by using their first
+  // enumerator.
+  auto enum_range = ED->enumerators();
+  if (enum_range.begin() != enum_range.end()) {
+Out << '@' << **enum_range.begin();
+  }
 }
   }
 }
   }
-  }
 
   // For a class template specialization, mangle the template arguments.
   if (const ClassTemplateSpecializationDecl *Spec



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


[clang] ae4dce8 - [clang][ABI] New C++20 module mangling scheme

2022-03-30 Thread Nathan Sidwell via cfe-commits

Author: Nathan Sidwell
Date: 2022-03-30T08:51:27-07:00
New Revision: ae4dce8659f313ca2034782583d31993212fa8bd

URL: 
https://github.com/llvm/llvm-project/commit/ae4dce8659f313ca2034782583d31993212fa8bd
DIFF: 
https://github.com/llvm/llvm-project/commit/ae4dce8659f313ca2034782583d31993212fa8bd.diff

LOG: [clang][ABI] New C++20 module mangling scheme

Implement a demangleable strong ownership symbol mangling.

 * The original module symbol mangling scheme turned out to be
undemangleable.

 * The hoped-for C++17 compatibility of weak ownership turns out to be
fragile

* C++20 now has better ways of controlling C++17 compatibility

The issue is captured on the ABI list at:
  https://github.com/itanium-cxx-abi/cxx-abi/issues/134

GCC implements this new mangling.

The old mangling is unceremoniously dropped.  No backwards
compatibility, no deprectated old-mangling flag.  It was always
labelled experimental.  (Old and new manglings cannot be confused.)

Reviewed By: dblaikie

Differential Revision: https://reviews.llvm.org/D122256

Added: 
clang/test/CodeGenCXX/Inputs/cxx20-module-impl-1a.cpp
clang/test/CodeGenCXX/Inputs/cxx20-module-std-subst-2a.cpp
clang/test/CodeGenCXX/cxx20-module-decomp-1.cpp
clang/test/CodeGenCXX/cxx20-module-extern-1.cppm
clang/test/CodeGenCXX/cxx20-module-impl-1a.cpp
clang/test/CodeGenCXX/cxx20-module-nested-1.cppm
clang/test/CodeGenCXX/cxx20-module-nested-2.cppm
clang/test/CodeGenCXX/cxx20-module-part-1a.cpp
clang/test/CodeGenCXX/cxx20-module-part-1b.cpp
clang/test/CodeGenCXX/cxx20-module-part-1c.cpp
clang/test/CodeGenCXX/cxx20-module-std-subst-1.cppm
clang/test/CodeGenCXX/cxx20-module-std-subst-2b.cpp
clang/test/CodeGenCXX/cxx20-module-std-subst-2c.cpp
clang/test/CodeGenCXX/cxx20-module-sub-1a.cppm
clang/test/CodeGenCXX/cxx20-module-sub-1b.cppm
clang/test/CodeGenCXX/cxx20-module-tmpl-1.cppm

Modified: 
clang/lib/AST/Decl.cpp
clang/lib/AST/ItaniumMangle.cpp
clang/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp
clang/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm
clang/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp
clang/test/CXX/modules-ts/basic/basic.link/p3.cppm
clang/test/CXX/modules-ts/codegen-basics.cppm

Removed: 




diff  --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 9b8585bbe3128..46c888430bb07 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -1547,6 +1547,11 @@ LinkageInfo 
LinkageComputer::getDeclLinkageAndVisibility(const NamedDecl *D) {
 }
 
 Module *Decl::getOwningModuleForLinkage(bool IgnoreLinkage) const {
+  if (isa(this))
+// Namespaces never have module linkage.  It is the entities within them
+// that [may] do.
+return nullptr;
+
   Module *M = getOwningModule();
   if (!M)
 return nullptr;

diff  --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 96716f6ce0e31..fb76fa7b896fc 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -438,6 +438,7 @@ class CXXNameMangler {
   void mangleType(QualType T);
   void mangleNameOrStandardSubstitution(const NamedDecl *ND);
   void mangleLambdaSig(const CXXRecordDecl *Lambda);
+  void mangleModuleNamePrefix(StringRef Name);
 
 private:
 
@@ -473,22 +474,21 @@ class CXXNameMangler {
 
   void mangleNameWithAbiTags(GlobalDecl GD,
  const AbiTagList *AdditionalAbiTags);
-  void mangleModuleName(const Module *M);
-  void mangleModuleNamePrefix(StringRef Name);
+  void mangleModuleName(const NamedDecl *ND);
   void mangleTemplateName(const TemplateDecl *TD,
   const TemplateArgument *TemplateArgs,
   unsigned NumTemplateArgs);
-  void mangleUnqualifiedName(GlobalDecl GD,
+  void mangleUnqualifiedName(GlobalDecl GD, const DeclContext *DC,
  const AbiTagList *AdditionalAbiTags) {
-mangleUnqualifiedName(GD, cast(GD.getDecl())->getDeclName(), 
UnknownArity,
-  AdditionalAbiTags);
+mangleUnqualifiedName(GD, cast(GD.getDecl())->getDeclName(), DC,
+  UnknownArity, AdditionalAbiTags);
   }
   void mangleUnqualifiedName(GlobalDecl GD, DeclarationName Name,
- unsigned KnownArity,
+ const DeclContext *DC, unsigned KnownArity,
  const AbiTagList *AdditionalAbiTags);
-  void mangleUnscopedName(GlobalDecl GD,
+  void mangleUnscopedName(GlobalDecl GD, const DeclContext *DC,
   const AbiTagList *AdditionalAbiTags);
-  void mangleUnscopedTemplateName(GlobalDecl GD,
+  void mangleUnscopedTemplateName(GlobalDecl GD, const DeclContext *DC,
   const AbiTagList *AdditionalAbiTags);
   void mangleSourceName(const IdentifierInfo *II);
   void mangleRegCallName(c

[clang] 54c5033 - [clang] Document p1703 not needed

2022-04-05 Thread Nathan Sidwell via cfe-commits

Author: Nathan Sidwell
Date: 2022-04-05T06:54:31-07:00
New Revision: 54c50336e4c11e9c9255d96ae0b55a56cc193ecb

URL: 
https://github.com/llvm/llvm-project/commit/54c50336e4c11e9c9255d96ae0b55a56cc193ecb
DIFF: 
https://github.com/llvm/llvm-project/commit/54c50336e4c11e9c9255d96ae0b55a56cc193ecb.diff

LOG: [clang] Document p1703 not needed

We list p1703 as unimplemented, but it is subsumed by p1857.

Reviewed By: tbaeder

Differential Revision: https://reviews.llvm.org/D123120

Added: 


Modified: 
clang/www/cxx_status.html

Removed: 




diff  --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html
index 3fcf7a3a27cae..47a6fdb1e4466 100755
--- a/clang/www/cxx_status.html
+++ b/clang/www/cxx_status.html
@@ -1176,10 +1176,11 @@ C++20 implementation status
   
   
 https://wg21.link/p1811r0";>P1811R0
-No
+No
   
   
 https://wg21.link/p1703r1";>P1703R1
+Subsumed by P1857
   

 https://wg21.link/p1874r1";>P1874R1



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


[clang] ba4482f - [clang][NFC] Add specificity to compatibility hack

2022-04-06 Thread Nathan Sidwell via cfe-commits

Author: Nathan Sidwell
Date: 2022-04-06T03:57:36-07:00
New Revision: ba4482f481991799a922d5cf124a56bea5866254

URL: 
https://github.com/llvm/llvm-project/commit/ba4482f481991799a922d5cf124a56bea5866254
DIFF: 
https://github.com/llvm/llvm-project/commit/ba4482f481991799a922d5cf124a56bea5866254.diff

LOG: [clang][NFC] Add specificity to compatibility hack

Add specific dates and versions to note about source_location handling.

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D123119

Added: 


Modified: 
clang/lib/AST/ExprConstant.cpp

Removed: 




diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 6c2447dc4420f..93950ac5341ba 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -8838,10 +8838,11 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr 
*E) {
   E->getType()->getPointeeType());
   // 1. We'll allow it in std::allocator::allocate, and anything which that
   //calls.
-  // 2. We'll allow it in the body of std::source_location:current.  This 
is
-  //necessary for libstdc++'s , which gave its
-  //parameter the type void*, and cast from that back to `const 
__impl*`
-  //in the body. (Fixed for new versions in gcc.gnu.org/PR104602).
+  // 2. HACK 2022-03-28: Work around an issue with libstdc++'s
+  // header. Fixed in GCC 12 and later (2022-04-??).
+  //We'll allow it in the body of std::source_location::current.  GCC's
+  //implementation had a parameter of type `void*`, and casts from
+  //that back to `const __impl*` in its body.
   if (VoidPtrCastMaybeOK &&
   (Info.getStdAllocatorCaller("allocate") ||
IsDeclSourceLocationCurrent(Info.CurrentCall->Callee))) {



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


[clang] 482fad4 - [clang][DOC] Document module mangler changes

2022-04-06 Thread Nathan Sidwell via cfe-commits

Author: Nathan Sidwell
Date: 2022-04-06T11:13:32-07:00
New Revision: 482fad4a3fcb013aa19e97661e3d66583d026bb8

URL: 
https://github.com/llvm/llvm-project/commit/482fad4a3fcb013aa19e97661e3d66583d026bb8
DIFF: 
https://github.com/llvm/llvm-project/commit/482fad4a3fcb013aa19e97661e3d66583d026bb8.diff

LOG: [clang][DOC] Document module mangler changes

Note that the mangling has changed and the demangler's learnt a new
trick.  Obviously dependent upon the mangler and demangler patches.

Reviewed By: bruno

Differential Revision: https://reviews.llvm.org/D123141

Added: 


Modified: 
clang/docs/ReleaseNotes.rst

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index bf592329ac02a..df6a7d7539ee6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -201,6 +201,13 @@ C++20 Feature Support
 
 - Implemented `__builtin_source_location()` which enables library support for 
std::source_location.
 
+- The mangling scheme for C++20 modules has incompatibly changed. The
+  initial mangling was discovered not to be reversible, and the weak
+  ownership design decision did not give the backwards compatibility
+  that was hoped for. C++20 since added ``extern "C++"`` semantics
+  that can be used for such compatibility. The demangler now demangles
+  symbols with named module attachment.
+
 C++2b Feature Support
 ^
 



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


[clang] 9eda5fc - [clang] Verify internal entity module mangling

2022-04-07 Thread Nathan Sidwell via cfe-commits

Author: Nathan Sidwell
Date: 2022-04-07T05:40:57-07:00
New Revision: 9eda5fc0c6eafd772d0e6ff015352136c5e505a4

URL: 
https://github.com/llvm/llvm-project/commit/9eda5fc0c6eafd772d0e6ff015352136c5e505a4
DIFF: 
https://github.com/llvm/llvm-project/commit/9eda5fc0c6eafd772d0e6ff015352136c5e505a4.diff

LOG: [clang] Verify internal entity module mangling

Internal symbol mangling is implementation-defined.  We do not mangle
any module attachment, and this adds a test to verify that.

Reviewed By: dblaikie

Differential Revision: https://reviews.llvm.org/D123220

Added: 
clang/test/CodeGenCXX/cxx20-module-internal.cppm

Modified: 


Removed: 




diff  --git a/clang/test/CodeGenCXX/cxx20-module-internal.cppm 
b/clang/test/CodeGenCXX/cxx20-module-internal.cppm
new file mode 100644
index 0..b45358325c423
--- /dev/null
+++ b/clang/test/CodeGenCXX/cxx20-module-internal.cppm
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -std=c++20 %s -triple %itanium_abi_triple -emit-llvm -o - | 
FileCheck %s
+
+// internal-linkage symbol mangling is implementation defined.  Let's
+// not mangle in the module attachment -- that unnecessarily bloats
+// the symbols.
+
+export module A;
+
+// CHECK-DAG: void @_ZL6addonev(
+static void addone() {}
+// CHECK-DAG: @_ZL1x =
+static int x = 5;
+
+namespace {
+// CHECK-DAG: void @_ZN12_GLOBAL__N_14frobEv(
+void frob() {}
+// CHECK-DAG: @_ZN12_GLOBAL__N_11yE =
+int y = 2;
+struct Bill {
+  void F();
+};
+// CHECK-DAG: void @_ZN12_GLOBAL__N_14Bill1FEv(
+void Bill::F() {}
+} // namespace
+
+// CHECK-DAG: void @_ZL4FrobPN12_GLOBAL__N_14BillE(
+static void Frob(Bill *b) {
+  if (b)
+b->F();
+}
+
+namespace N {
+// CHECK-DAG: void @_ZN1NL5innerEv(
+static void inner() {}
+// CHECK-DAG: @_ZN1NL1zE
+static int z = 3;
+} // namespace N
+
+// CHECK-DAG: void @_ZW1A6addsixv(
+void addsix() {
+  Frob(nullptr);
+  frob();
+  addone();
+  void(x + y + N::z);
+  N::inner();
+}



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


[clang] 815446c - [clang][NFC] Standard substitution checking cleanup

2022-02-10 Thread Nathan Sidwell via cfe-commits

Author: Nathan Sidwell
Date: 2022-02-10T04:44:48-08:00
New Revision: 815446cd3e164b8be010864648d4104ad178b129

URL: 
https://github.com/llvm/llvm-project/commit/815446cd3e164b8be010864648d4104ad178b129
DIFF: 
https://github.com/llvm/llvm-project/commit/815446cd3e164b8be010864648d4104ad178b129.diff

LOG: [clang][NFC] Standard substitution checking cleanup

In preparing for module mangling changes I noticed some issues with
the way we check for std::basic_string instantiations and friends.

*) there's a single routine for std::basic_{i,o,io}stream but it is
 templatized on the length of the name.  Really?  just use a
 StringRef, rather than clone the entire routine just for
 'basic_iostream'.

*) We have a helper routine to check for char type, and call it from
 several places.  But given all the instantiations are of the form
 TPL ...> we could just check the first arg is char
 and the later templated args are instantiating that same type.  A
 simpler type comparison.

*) Because basic_string has a third allocator parameter, it is open
 coded, which I found a little confusing.  But otherwise it's exactly
 the same pattern as the iostream ones.  Just tell that checker about
 whether there's an expected allocator argument.[*]

*) We may as well return in each block of mangleStandardSubstitution
 once we determine it is not one of the entities of interest -- it
 certainly cannot be one of the other kinds of entities.

FWIW this shaves about 500 bytes off the executable.

[*] I suppose we could also have this routine a tri-value, with one to
indicat 'it is this name, but it's not the one you're looking for', to
avoid later calls trying different names?

Reviewd By: ChuanqiXu

Differential Revision: https://reviews.llvm.org/D119333

Added: 


Modified: 
clang/lib/AST/ItaniumMangle.cpp

Removed: 




diff  --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 2e734e2b28cdb..b15669d426bd6 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -5969,27 +5969,19 @@ bool CXXNameMangler::mangleSubstitution(uintptr_t Ptr) {
   return true;
 }
 
-static bool isCharType(QualType T) {
-  if (T.isNull())
+/// Returns whether S is a template specialization of std::Name with a single
+/// argument of type A.
+static bool isSpecializedAs(QualType S, llvm::StringRef Name, QualType A) {
+  if (S.isNull())
 return false;
 
-  return T->isSpecificBuiltinType(BuiltinType::Char_S) ||
-T->isSpecificBuiltinType(BuiltinType::Char_U);
-}
-
-/// Returns whether a given type is a template specialization of a given name
-/// with a single argument of type char.
-static bool isCharSpecialization(QualType T, const char *Name) {
-  if (T.isNull())
-return false;
-
-  const RecordType *RT = T->getAs();
+  const RecordType *RT = S->getAs();
   if (!RT)
 return false;
 
   const ClassTemplateSpecializationDecl *SD =
 dyn_cast(RT->getDecl());
-  if (!SD)
+  if (!SD || !SD->getIdentifier()->isStr(Name))
 return false;
 
   if (!isStdNamespace(getEffectiveDeclContext(SD)))
@@ -5999,26 +5991,37 @@ static bool isCharSpecialization(QualType T, const char 
*Name) {
   if (TemplateArgs.size() != 1)
 return false;
 
-  if (!isCharType(TemplateArgs[0].getAsType()))
+  if (TemplateArgs[0].getAsType() != A)
 return false;
 
-  return SD->getIdentifier()->getName() == Name;
+  return true;
 }
 
-template 
-static bool isStreamCharSpecialization(const 
ClassTemplateSpecializationDecl*SD,
-   const char (&Str)[StrLen]) {
-  if (!SD->getIdentifier()->isStr(Str))
+/// Returns whether SD is a template specialization std::Name [, std::allocator]>
+/// HasAllocator controls whether the 3rd template argument is needed.
+static bool isStdCharSpecialization(const ClassTemplateSpecializationDecl *SD,
+llvm::StringRef Name, bool HasAllocator) {
+  if (!SD->getIdentifier()->isStr(Name))
 return false;
 
   const TemplateArgumentList &TemplateArgs = SD->getTemplateArgs();
-  if (TemplateArgs.size() != 2)
+  if (TemplateArgs.size() != (HasAllocator ? 3 : 2))
 return false;
 
-  if (!isCharType(TemplateArgs[0].getAsType()))
+  QualType A = TemplateArgs[0].getAsType();
+  if (A.isNull())
+return false;
+  // Plain 'char' is named Char_S or Char_U depending on the target ABI.
+  if (!A->isSpecificBuiltinType(BuiltinType::Char_S) &&
+  !A->isSpecificBuiltinType(BuiltinType::Char_U))
 return false;
 
-  if (!isCharSpecialization(TemplateArgs[1].getAsType(), "char_traits"))
+  if (!isSpecializedAs(TemplateArgs[1].getAsType(), "char_traits", A))
+return false;
+
+  if (HasAllocator &&
+  !isSpecializedAs(TemplateArgs[2].getAsType(), "allocator", A))
 return false;
 
   return true;
@@ -6031,6 +6034,7 @@ bool CXXNameMangler::mangleStandardSubstitution(const 
NamedDecl *ND) {
   Out << "St";

[clang] 0209390 - [clang][NFC] Remove IgnoreLinkageSpecDecls

2022-02-15 Thread Nathan Sidwell via cfe-commits

Author: Nathan Sidwell
Date: 2022-02-15T04:28:45-08:00
New Revision: 02093906fa0fd5bacc61b2189ea643c78cd02509

URL: 
https://github.com/llvm/llvm-project/commit/02093906fa0fd5bacc61b2189ea643c78cd02509
DIFF: 
https://github.com/llvm/llvm-project/commit/02093906fa0fd5bacc61b2189ea643c78cd02509.diff

LOG: [clang][NFC] Remove IgnoreLinkageSpecDecls

The Itanium mangler uses IgnoreLinkageSpecDecls to strip linkage spec
contexts.  It doesn't do this consistently, but there is no need for
it to do it at all.  getEffectiveDeclContext never returns a linkage
spec, as it either recurses, uses getRedeclContext (which itself
removes the specs), or gets the decl context of non-namespace entities.

This patch removes the function and all calls to it.  For safety I add
a couple of asserts to make sure we never get them.

Reviewed By: ChuanqiXu

Differential Revision: https://reviews.llvm.org/D119748

Added: 


Modified: 
clang/lib/AST/ItaniumMangle.cpp

Removed: 




diff  --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index b15669d426bd6..b92a6a07ff1f7 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -862,18 +862,9 @@ void CXXNameMangler::mangleFunctionEncodingBareType(const 
FunctionDecl *FD) {
  MangleReturnType, FD);
 }
 
-static const DeclContext *IgnoreLinkageSpecDecls(const DeclContext *DC) {
-  while (isa(DC)) {
-DC = getEffectiveParentContext(DC);
-  }
-
-  return DC;
-}
-
 /// Return whether a given namespace is the 'std' namespace.
 static bool isStd(const NamespaceDecl *NS) {
-  if (!IgnoreLinkageSpecDecls(getEffectiveParentContext(NS))
-->isTranslationUnit())
+  if (!getEffectiveParentContext(NS)->isTranslationUnit())
 return false;
 
   const IdentifierInfo *II = NS->getOriginalNamespace()->getIdentifier();
@@ -978,7 +969,7 @@ void CXXNameMangler::mangleNameWithAbiTags(GlobalDecl GD,
 return;
   }
 
-  DC = IgnoreLinkageSpecDecls(DC);
+  assert(!isa(DC) && "context cannot be LinkageSpecDecl");
 
   if (isLocalContainerContext(DC)) {
 mangleLocalName(GD, AdditionalAbiTags);
@@ -1054,7 +1045,7 @@ void CXXNameMangler::mangleModuleNamePrefix(StringRef 
Name) {
 void CXXNameMangler::mangleTemplateName(const TemplateDecl *TD,
 const TemplateArgument *TemplateArgs,
 unsigned NumTemplateArgs) {
-  const DeclContext *DC = IgnoreLinkageSpecDecls(getEffectiveDeclContext(TD));
+  const DeclContext *DC = getEffectiveDeclContext(TD);
 
   if (DC->isTranslationUnit() || isStdNamespace(DC)) {
 mangleUnscopedTemplateName(TD, nullptr);
@@ -1070,7 +1061,7 @@ void CXXNameMangler::mangleUnscopedName(GlobalDecl GD,
   //   ::= 
   //  ::= St# ::std::
 
-  if (isStdNamespace(IgnoreLinkageSpecDecls(getEffectiveDeclContext(ND
+  if (isStdNamespace(getEffectiveDeclContext(ND)))
 Out << "St";
 
   mangleUnqualifiedName(GD, AdditionalAbiTags);
@@ -2030,7 +2021,7 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC, 
bool NoFunction) {
   //   ::= # empty
   //   ::= 
 
-  DC = IgnoreLinkageSpecDecls(DC);
+  assert(!isa(DC) && "prefix cannot be LinkageSpecDecl");
 
   if (DC->isTranslationUnit())
 return;



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


[clang] 082f328 - [clang] Itanium mangler constructors

2022-02-16 Thread Nathan Sidwell via cfe-commits

Author: Nathan Sidwell
Date: 2022-02-16T04:30:47-08:00
New Revision: 082f328899be9ed8a38b04a4e52be936f4875495

URL: 
https://github.com/llvm/llvm-project/commit/082f328899be9ed8a38b04a4e52be936f4875495
DIFF: 
https://github.com/llvm/llvm-project/commit/082f328899be9ed8a38b04a4e52be936f4875495.diff

LOG: [clang] Itanium mangler constructors

The Itanium mangler constructors use both NSDMI and explicit member
construction for default values.  This is confusing.

*) Use NSDMIs wherever possible

*) Use forwarding ctor for the nesting case with an
 llvm::raw_null_ostream (and explicitly set NullOut flag in that ctor).

*) Copy the ModuleSubstitutions.  This is a bug with no effect in the
 current mangling, but not in the newer mangling.

Reviewed By: ChuanqiXu

Differential Revision: https://reviews.llvm.org/D119550

Added: 


Modified: 
clang/lib/AST/ItaniumMangle.cpp

Removed: 




diff  --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index b92a6a07ff1f7..63e40a0f30721 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -267,10 +267,10 @@ class CXXNameMangler {
   /// that's not a template specialization; otherwise it's the pattern
   /// for that specialization.
   const NamedDecl *Structor;
-  unsigned StructorType;
+  unsigned StructorType = 0;
 
   /// The next substitution sequence number.
-  unsigned SeqID;
+  unsigned SeqID = 0;
 
   class FunctionTypeDepthState {
 unsigned Bits;
@@ -430,32 +430,32 @@ class CXXNameMangler {
 public:
   CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_,
  const NamedDecl *D = nullptr, bool NullOut_ = false)
-: Context(C), Out(Out_), NullOut(NullOut_),  Structor(getStructor(D)),
-  StructorType(0), SeqID(0), AbiTagsRoot(AbiTags) {
+  : Context(C), Out(Out_), NullOut(NullOut_), Structor(getStructor(D)),
+AbiTagsRoot(AbiTags) {
 // These can't be mangled without a ctor type or dtor type.
 assert(!D || (!isa(D) &&
   !isa(D)));
   }
   CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_,
  const CXXConstructorDecl *D, CXXCtorType Type)
-: Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
-  SeqID(0), AbiTagsRoot(AbiTags) { }
+  : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
+AbiTagsRoot(AbiTags) {}
   CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_,
  const CXXDestructorDecl *D, CXXDtorType Type)
-: Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
-  SeqID(0), AbiTagsRoot(AbiTags) { }
+  : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
+AbiTagsRoot(AbiTags) {}
 
   CXXNameMangler(CXXNameMangler &Outer, raw_ostream &Out_)
-  : Context(Outer.Context), Out(Out_), NullOut(false),
-Structor(Outer.Structor), StructorType(Outer.StructorType),
-SeqID(Outer.SeqID), FunctionTypeDepth(Outer.FunctionTypeDepth),
-AbiTagsRoot(AbiTags), Substitutions(Outer.Substitutions) {}
+  : Context(Outer.Context), Out(Out_), Structor(Outer.Structor),
+StructorType(Outer.StructorType), SeqID(Outer.SeqID),
+FunctionTypeDepth(Outer.FunctionTypeDepth), AbiTagsRoot(AbiTags),
+Substitutions(Outer.Substitutions),
+ModuleSubstitutions(Outer.ModuleSubstitutions) {}
 
   CXXNameMangler(CXXNameMangler &Outer, llvm::raw_null_ostream &Out_)
-  : Context(Outer.Context), Out(Out_), NullOut(true),
-Structor(Outer.Structor), StructorType(Outer.StructorType),
-SeqID(Outer.SeqID), FunctionTypeDepth(Outer.FunctionTypeDepth),
-AbiTagsRoot(AbiTags), Substitutions(Outer.Substitutions) {}
+  : CXXNameMangler(Outer, (raw_ostream &)Out_) {
+NullOut = true;
+  }
 
   raw_ostream &getStream() { return Out; }
 



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


[clang] 80bebbc - [clang][NFC] Cleanup some coroutine tests

2022-05-16 Thread Nathan Sidwell via cfe-commits

Author: Nathan Sidwell
Date: 2022-05-16T05:15:12-07:00
New Revision: 80bebbc7cb77979ef9d229450b7ea84e3e9c6a5a

URL: 
https://github.com/llvm/llvm-project/commit/80bebbc7cb77979ef9d229450b7ea84e3e9c6a5a
DIFF: 
https://github.com/llvm/llvm-project/commit/80bebbc7cb77979ef9d229450b7ea84e3e9c6a5a.diff

LOG: [clang][NFC] Cleanup some coroutine tests

I noticed these two tests emit a warning about a missing
unhandled_exception.  That's irrelevant to what is being tested, but
is unnecessary noise.

Reviewed By: dblaikie

Differential Revision: https://reviews.llvm.org/D125535

Added: 


Modified: 
clang/test/CodeGenCoroutines/coro-ret-void.cpp
clang/test/CoverageMapping/coroutine.cpp

Removed: 




diff  --git a/clang/test/CodeGenCoroutines/coro-ret-void.cpp 
b/clang/test/CodeGenCoroutines/coro-ret-void.cpp
index 7bc1bcd958b7a..ae139afabc4d4 100644
--- a/clang/test/CodeGenCoroutines/coro-ret-void.cpp
+++ b/clang/test/CodeGenCoroutines/coro-ret-void.cpp
@@ -8,6 +8,7 @@ struct coro1 {
 std::suspend_never initial_suspend();
 std::suspend_never final_suspend() noexcept;
 void return_void();
+void unhandled_exception() noexcept;
   };
 };
 
@@ -39,6 +40,7 @@ struct coro2 {
 std::suspend_never initial_suspend();
 std::suspend_never final_suspend() noexcept;
 void return_value(int);
+void unhandled_exception() noexcept;
   };
 };
 

diff  --git a/clang/test/CoverageMapping/coroutine.cpp 
b/clang/test/CoverageMapping/coroutine.cpp
index c9de301f81757..da38acc442be2 100644
--- a/clang/test/CoverageMapping/coroutine.cpp
+++ b/clang/test/CoverageMapping/coroutine.cpp
@@ -30,6 +30,7 @@ struct std::coroutine_traits {
 int get_return_object();
 suspend_always initial_suspend();
 suspend_always final_suspend() noexcept;
+void unhandled_exception() noexcept;
 void return_value(int);
   };
 };



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


[clang] a1dcfb7 - [clang] Module global init mangling

2022-05-23 Thread Nathan Sidwell via cfe-commits

Author: Nathan Sidwell
Date: 2022-05-23T09:03:10-07:00
New Revision: a1dcfb75ea8c31dd39edb6bdab6f54cde81cad85

URL: 
https://github.com/llvm/llvm-project/commit/a1dcfb75ea8c31dd39edb6bdab6f54cde81cad85
DIFF: 
https://github.com/llvm/llvm-project/commit/a1dcfb75ea8c31dd39edb6bdab6f54cde81cad85.diff

LOG: [clang] Module global init mangling

C++20 modules require emission of an initializer function, which is
called by importers of the module.  This implements the mangling for
that function.  It is the one place the ABI exposes partition names in
symbols -- but fortunately only needed by other TUs of that same module.

Reviewed By: bruno

Differential Revision: https://reviews.llvm.org/D122741

Added: 


Modified: 
clang/include/clang/AST/Mangle.h
clang/lib/AST/ItaniumMangle.cpp

Removed: 




diff  --git a/clang/include/clang/AST/Mangle.h 
b/clang/include/clang/AST/Mangle.h
index 9bca97a611d08..96cc8c90a8e83 100644
--- a/clang/include/clang/AST/Mangle.h
+++ b/clang/include/clang/AST/Mangle.h
@@ -199,6 +199,8 @@ class ItaniumMangleContext : public MangleContext {
 
   virtual void mangleDynamicStermFinalizer(const VarDecl *D, raw_ostream &) = 
0;
 
+  virtual void mangleModuleInitializer(const Module *Module, raw_ostream &) = 
0;
+
   // This has to live here, otherwise the CXXNameMangler won't have access to
   // it.
   virtual DiscriminatorOverrideTy getDiscriminatorOverride() const = 0;

diff  --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index b380e02fc8f7d..a9416397c90d6 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -130,6 +130,8 @@ class ItaniumMangleContextImpl : public 
ItaniumMangleContext {
 
   void mangleLambdaSig(const CXXRecordDecl *Lambda, raw_ostream &) override;
 
+  void mangleModuleInitializer(const Module *Module, raw_ostream &) override;
+
   bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
 // Lambda closure types are already numbered.
 if (isLambda(ND))
@@ -438,7 +440,7 @@ class CXXNameMangler {
   void mangleType(QualType T);
   void mangleNameOrStandardSubstitution(const NamedDecl *ND);
   void mangleLambdaSig(const CXXRecordDecl *Lambda);
-  void mangleModuleNamePrefix(StringRef Name);
+  void mangleModuleNamePrefix(StringRef Name, bool IsPartition = false);
 
 private:
 
@@ -1057,8 +1059,8 @@ void CXXNameMangler::mangleModuleName(const NamedDecl 
*ND) {
 //  ::=  
 //  ::= 
 //  ::= W 
-// ::= W P  # not (yet) needed
-void CXXNameMangler::mangleModuleNamePrefix(StringRef Name) {
+// ::= W P 
+void CXXNameMangler::mangleModuleNamePrefix(StringRef Name, bool IsPartition) {
   //   ::= S  _
   auto It = ModuleSubstitutions.find(Name);
   if (It != ModuleSubstitutions.end()) {
@@ -1072,10 +1074,14 @@ void CXXNameMangler::mangleModuleNamePrefix(StringRef 
Name) {
   auto Parts = Name.rsplit('.');
   if (Parts.second.empty())
 Parts.second = Parts.first;
-  else
-mangleModuleNamePrefix(Parts.first);
+  else {
+mangleModuleNamePrefix(Parts.first, IsPartition);
+IsPartition = false;
+  }
 
   Out << 'W';
+  if (IsPartition)
+Out << 'P';
   Out << Parts.second.size() << Parts.second;
   ModuleSubstitutions.insert({Name, SeqID++});
 }
@@ -6533,6 +6539,21 @@ void ItaniumMangleContextImpl::mangleLambdaSig(const 
CXXRecordDecl *Lambda,
   Mangler.mangleLambdaSig(Lambda);
 }
 
+void ItaniumMangleContextImpl::mangleModuleInitializer(const Module *M,
+   raw_ostream &Out) {
+  //  ::= GI   # module initializer function
+  CXXNameMangler Mangler(*this, Out);
+  Mangler.getStream() << "_ZGI";
+  Mangler.mangleModuleNamePrefix(M->getPrimaryModuleInterfaceName());
+  if (M->isModulePartition()) {
+// The partition needs including, as partitions can have them too.
+auto Partition = M->Name.find(':');
+Mangler.mangleModuleNamePrefix(
+StringRef(&M->Name[Partition + 1], M->Name.size() - Partition - 1),
+/*IsPartition*/ true);
+  }
+}
+
 ItaniumMangleContext *ItaniumMangleContext::create(ASTContext &Context,
DiagnosticsEngine &Diags,
bool IsAux) {



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


[clang] [clang] Better bitfield access units (PR #65742)

2024-03-15 Thread Nathan Sidwell via cfe-commits


@@ -439,82 +444,194 @@ 
CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
   Members.push_back(MemberInfo(bitsToCharUnits(StartBitOffset),
MemberInfo::Field, nullptr, *Field));
 }
-return;
+return Field;
   }
 
-  // Check if OffsetInRecord (the size in bits of the current run) is better
-  // as a single field run. When OffsetInRecord has legal integer width, and
-  // its bitfield offset is naturally aligned, it is better to make the
-  // bitfield a separate storage component so as it can be accessed directly
-  // with lower cost.
-  auto IsBetterAsSingleFieldRun = [&](uint64_t OffsetInRecord,
-  uint64_t StartBitOffset) {
-if (!Types.getCodeGenOpts().FineGrainedBitfieldAccesses)
-  return false;
-if (OffsetInRecord < 8 || !llvm::isPowerOf2_64(OffsetInRecord) ||
-!DataLayout.fitsInLegalInteger(OffsetInRecord))
-  return false;
-// Make sure StartBitOffset is naturally aligned if it is treated as an
-// IType integer.
-if (StartBitOffset %
-Context.toBits(getAlignment(getIntNType(OffsetInRecord))) !=
-0)
-  return false;
-return true;
-  };
+  // The SysV ABI can overlap bitfield storage units with both other bitfield
+  // storage units /and/ other non-bitfield data members. Accessing a sequence
+  // of bitfields mustn't interfere with adjacent non-bitfields -- they're
+  // permitted to be accessed in separate threads for instance.
+
+  // We split runs of bit-fields into a sequence of "access units". When we 
emit
+  // a load or store of a bit-field, we'll load/store the entire containing
+  // access unit. As mentioned, the standard requires that these loads and
+  // stores must not interfere with accesses to other memory locations, and it
+  // defines the bit-field's memory location as the current run of
+  // non-zero-width bit-fields. So an access unit must never overlap with
+  // non-bit-field storage or cross a zero-width bit-field. Otherwise, we're
+  // free to draw the lines as we see fit.
+
+  // Drawing these lines well can be complicated. LLVM generally can't modify a
+  // program to access memory that it didn't before, so using very narrow 
access
+  // units can prevent the compiler from using optimal access patterns. For
+  // example, suppose a run of bit-fields occupies four bytes in a struct. If 
we
+  // split that into four 1-byte access units, then a sequence of assignments
+  // that doesn't touch all four bytes may have to be emitted with multiple
+  // 8-bit stores instead of a single 32-bit store. On the other hand, if we 
use
+  // very wide access units, we may find ourselves emitting accesses to
+  // bit-fields we didn't really need to touch, just because LLVM was unable to
+  // clean up after us.
+
+  // It is desirable to have access units be aligned powers of 2 no larger than
+  // a register. (On non-strict alignment ISAs, the alignment requirement can 
be
+  // dropped.) A three byte access unit will be accessed using 2-byte and 
1-byte
+  // accesses and bit manipulation. If no bitfield straddles across the two
+  // separate accesses, it is better to have separate 2-byte and 1-byte access
+  // units, as then LLVM will not generate unnecessary memory accesses, or bit
+  // manipulation. Similarly, on a strict-alignment architecture, it is better
+  // to keep access-units naturally aligned, to avoid similar bit
+  // manipulation synthesizing larger unaligned accesses.
+
+  // We do this in two phases, processing a sequential run of bitfield
+  // declarations.
+
+  // a) Bitfields that share parts of a single byte are, of necessity, placed 
in
+  // the same access unit. That unit will encompass a consecutive
+  // run where adjacent bitfields share parts of a byte. (The first bitfield of
+  // such an access unit will start at the beginning of a byte.)
+
+  // b) Accumulate adjacent access units when the combined unit is naturally
+  // sized, no larger than a register, and on a strict alignment ISA,
+  // aligned. Note that this requires lookahead to one or more subsequent 
access
+  // units. For instance, consider a 2-byte access-unit followed by 2 1-byte
+  // units. We can merge that into a 4-byte access-unit, but we would not want
+  // to merge a 2-byte followed by a single 1-byte (and no available tail
+  // padding).
+
+  // This accumulation is prevented when:
+  // *) it would cross a zero-width bitfield (ABI-dependent), or
+  // *) one of the candidate access units contains a volatile bitfield, or
+  // *) fine-grained bitfield access option is in effect.
+
+  CharUnits RegSize =
+  bitsToCharUnits(Context.getTargetInfo().getRegisterWidth());
+  unsigned CharBits = Context.getCharWidth();
+
+  RecordDecl::field_iterator Begin = FieldEnd;
+  CharUnits StartOffset;
+  uint64_t BitSize;
+  CharUnits BestEndOffset;
+  RecordDecl::field_iterator BestEnd = B

[clang] [clang] Better bitfield access units (PR #65742)

2024-03-15 Thread Nathan Sidwell via cfe-commits


@@ -439,82 +444,194 @@ 
CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
   Members.push_back(MemberInfo(bitsToCharUnits(StartBitOffset),
MemberInfo::Field, nullptr, *Field));
 }
-return;
+return Field;
   }
 
-  // Check if OffsetInRecord (the size in bits of the current run) is better
-  // as a single field run. When OffsetInRecord has legal integer width, and
-  // its bitfield offset is naturally aligned, it is better to make the
-  // bitfield a separate storage component so as it can be accessed directly
-  // with lower cost.
-  auto IsBetterAsSingleFieldRun = [&](uint64_t OffsetInRecord,
-  uint64_t StartBitOffset) {
-if (!Types.getCodeGenOpts().FineGrainedBitfieldAccesses)
-  return false;
-if (OffsetInRecord < 8 || !llvm::isPowerOf2_64(OffsetInRecord) ||
-!DataLayout.fitsInLegalInteger(OffsetInRecord))
-  return false;
-// Make sure StartBitOffset is naturally aligned if it is treated as an
-// IType integer.
-if (StartBitOffset %
-Context.toBits(getAlignment(getIntNType(OffsetInRecord))) !=
-0)
-  return false;
-return true;
-  };
+  // The SysV ABI can overlap bitfield storage units with both other bitfield
+  // storage units /and/ other non-bitfield data members. Accessing a sequence
+  // of bitfields mustn't interfere with adjacent non-bitfields -- they're
+  // permitted to be accessed in separate threads for instance.
+
+  // We split runs of bit-fields into a sequence of "access units". When we 
emit
+  // a load or store of a bit-field, we'll load/store the entire containing
+  // access unit. As mentioned, the standard requires that these loads and
+  // stores must not interfere with accesses to other memory locations, and it
+  // defines the bit-field's memory location as the current run of
+  // non-zero-width bit-fields. So an access unit must never overlap with
+  // non-bit-field storage or cross a zero-width bit-field. Otherwise, we're
+  // free to draw the lines as we see fit.
+
+  // Drawing these lines well can be complicated. LLVM generally can't modify a
+  // program to access memory that it didn't before, so using very narrow 
access
+  // units can prevent the compiler from using optimal access patterns. For
+  // example, suppose a run of bit-fields occupies four bytes in a struct. If 
we
+  // split that into four 1-byte access units, then a sequence of assignments
+  // that doesn't touch all four bytes may have to be emitted with multiple
+  // 8-bit stores instead of a single 32-bit store. On the other hand, if we 
use
+  // very wide access units, we may find ourselves emitting accesses to
+  // bit-fields we didn't really need to touch, just because LLVM was unable to
+  // clean up after us.
+
+  // It is desirable to have access units be aligned powers of 2 no larger than
+  // a register. (On non-strict alignment ISAs, the alignment requirement can 
be
+  // dropped.) A three byte access unit will be accessed using 2-byte and 
1-byte
+  // accesses and bit manipulation. If no bitfield straddles across the two
+  // separate accesses, it is better to have separate 2-byte and 1-byte access
+  // units, as then LLVM will not generate unnecessary memory accesses, or bit
+  // manipulation. Similarly, on a strict-alignment architecture, it is better
+  // to keep access-units naturally aligned, to avoid similar bit
+  // manipulation synthesizing larger unaligned accesses.
+
+  // We do this in two phases, processing a sequential run of bitfield
+  // declarations.
+
+  // a) Bitfields that share parts of a single byte are, of necessity, placed 
in
+  // the same access unit. That unit will encompass a consecutive
+  // run where adjacent bitfields share parts of a byte. (The first bitfield of
+  // such an access unit will start at the beginning of a byte.)
+
+  // b) Accumulate adjacent access units when the combined unit is naturally
+  // sized, no larger than a register, and on a strict alignment ISA,
+  // aligned. Note that this requires lookahead to one or more subsequent 
access
+  // units. For instance, consider a 2-byte access-unit followed by 2 1-byte
+  // units. We can merge that into a 4-byte access-unit, but we would not want
+  // to merge a 2-byte followed by a single 1-byte (and no available tail
+  // padding).
+
+  // This accumulation is prevented when:
+  // *) it would cross a zero-width bitfield (ABI-dependent), or
+  // *) one of the candidate access units contains a volatile bitfield, or
+  // *) fine-grained bitfield access option is in effect.
+
+  CharUnits RegSize =
+  bitsToCharUnits(Context.getTargetInfo().getRegisterWidth());
+  unsigned CharBits = Context.getCharWidth();
+
+  RecordDecl::field_iterator Begin = FieldEnd;
+  CharUnits StartOffset;
+  uint64_t BitSize;
+  CharUnits BestEndOffset;
+  RecordDecl::field_iterator BestEnd = B

[clang] [clang] Better bitfield access units (PR #65742)

2024-03-18 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

@rjmccall here is a rebase an update, which I think addresses all your 
comments.  I did make some material changes though:

1) I removed the Volatile handling. I was always a little uncomfortable with it 
because it didn't affect the access units of a non-volatile bitfield that ends 
up being volatile qualified via the structure's volatile quals itself. Users of 
volatile fields are probably confused, but if not they have a std-blessed 
mechanism for isolating access units -- a zero-length bitfield. The heuristic 
broke the idea that this patch /just/ implemented a better access algorithm so 
I was being inconsistent. AFAICT the ARM ABI, which seems to be one that 
describes volatile bitfields carefully, does not specify that volatile 
bitfields should  be as isolated as possible.  This change causes one change, 
in `CodeGen/aapcs-bitfield.c` with:
```
struct st5 {
  int a : 12;
  volatile char c : 5;
} st5;
```
The two bitfields are placed into a single 32-bit access unit, rather than 
separate 16bit ones. Either behaviour is ok with the aapcs. (The previous 
algorithm would have placed them into a single 24bit field if they abutted at a 
byte boundary, no change in that behaviour now.)

2) Implementing the barrier behaviour you wanted. I tried to find a psABI that 
had the right attributes to place barriers at arbitrary bit positions, to see 
if it had any comment, but failed to find one.  as you say, this simplifies 
things, but ...

3) The barrier bitfield behaviour that we already had showed an interesting 
behaviour, which I suspect is from a later scissoring processing.  Namely with:
```
struct  A {
  unsigned a : 16;
  unsigned b : 8;
  char : 0;
  unsigned d;
} a;
```
we'd generate an llvm struct of `{ i24, i32}`, but then adjust the access unit 
for the bitfields to be a 32-bit unit itself. That seems conformant, because 
nothing else uses that 4th byte, and the std merely says that the bitfield 
starts at an allocation unit boundary. This patch was originally treating that 
barrier as a limit to the current span, whereas we can use the next member with 
storage as that limit.  This is actually the behaviour we had when we reached 
the end of a run of bitfields, so I have made that change as you can see from 
the changed handling setting Barrier.

4) I adjusted the new testcases to reduce their complexity -- we don't care 
about endianness, which only affects the placement of the bitfields within 
their access unit, not the access units themselves.

It may be that the later pass that was adjusting bitfield accesses to natural 
sizes can be simplified or deleted. I've not investigated.

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


[clang] [clang] Better bitfield access units (PR #65742)

2024-03-18 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

Sorry to push another update, but I realized the LimitOffset computation could 
be sunk to the point of use, and therefore not computed in all cases.

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


[clang] [clang] Better bitfield access units (PR #65742)

2024-03-22 Thread Nathan Sidwell via cfe-commits


@@ -439,82 +444,247 @@ 
CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
   Members.push_back(MemberInfo(bitsToCharUnits(StartBitOffset),
MemberInfo::Field, nullptr, *Field));
 }
-return;
+return Field;
   }
 
-  // Check if OffsetInRecord (the size in bits of the current run) is better
-  // as a single field run. When OffsetInRecord has legal integer width, and
-  // its bitfield offset is naturally aligned, it is better to make the
-  // bitfield a separate storage component so as it can be accessed directly
-  // with lower cost.
-  auto IsBetterAsSingleFieldRun = [&](uint64_t OffsetInRecord,
-  uint64_t StartBitOffset) {
-if (!Types.getCodeGenOpts().FineGrainedBitfieldAccesses)
-  return false;
-if (OffsetInRecord < 8 || !llvm::isPowerOf2_64(OffsetInRecord) ||
-!DataLayout.fitsInLegalInteger(OffsetInRecord))
-  return false;
-// Make sure StartBitOffset is naturally aligned if it is treated as an
-// IType integer.
-if (StartBitOffset %
-Context.toBits(getAlignment(getIntNType(OffsetInRecord))) !=
-0)
-  return false;
-return true;
-  };
+  // The SysV ABI can overlap bitfield storage units with both other bitfield
+  // storage units /and/ other non-bitfield data members. Accessing a sequence
+  // of bitfields mustn't interfere with adjacent non-bitfields -- they're
+  // permitted to be accessed in separate threads for instance.
+
+  // We split runs of bit-fields into a sequence of "access units". When we 
emit
+  // a load or store of a bit-field, we'll load/store the entire containing
+  // access unit. As mentioned, the standard requires that these loads and
+  // stores must not interfere with accesses to other memory locations, and it
+  // defines the bit-field's memory location as the current run of
+  // non-zero-width bit-fields. So an access unit must never overlap with
+  // non-bit-field storage or cross a zero-width bit-field. Otherwise, we're
+  // free to draw the lines as we see fit.
+
+  // Drawing these lines well can be complicated. LLVM generally can't modify a
+  // program to access memory that it didn't before, so using very narrow 
access
+  // units can prevent the compiler from using optimal access patterns. For
+  // example, suppose a run of bit-fields occupies four bytes in a struct. If 
we
+  // split that into four 1-byte access units, then a sequence of assignments
+  // that doesn't touch all four bytes may have to be emitted with multiple
+  // 8-bit stores instead of a single 32-bit store. On the other hand, if we 
use
+  // very wide access units, we may find ourselves emitting accesses to
+  // bit-fields we didn't really need to touch, just because LLVM was unable to
+  // clean up after us.
+
+  // It is desirable to have access units be aligned powers of 2 no larger than
+  // a register. (On non-strict alignment ISAs, the alignment requirement can 
be
+  // dropped.) A three byte access unit will be accessed using 2-byte and 
1-byte
+  // accesses and bit manipulation. If no bitfield straddles across the two
+  // separate accesses, it is better to have separate 2-byte and 1-byte access
+  // units, as then LLVM will not generate unnecessary memory accesses, or bit
+  // manipulation. Similarly, on a strict-alignment architecture, it is better
+  // to keep access-units naturally aligned, to avoid similar bit
+  // manipulation synthesizing larger unaligned accesses.
+
+  // Bitfields that share parts of a single byte are, of necessity, placed in
+  // the same access unit. That unit will encompass a consecutive run where
+  // adjacent bitfields share parts of a byte. (The first bitfield of such an
+  // access unit will start at the beginning of a byte.)
+
+  // We then try and accumulate adjacent access units when the combined unit is
+  // naturally sized, no larger than a register, and (on a strict alignment
+  // ISA), naturally aligned. Note that this requires lookahead to one or more
+  // subsequent access units. For instance, consider a 2-byte access-unit
+  // followed by 2 1-byte units. We can merge that into a 4-byte access-unit,
+  // but we would not want to merge a 2-byte followed by a single 1-byte (and 
no
+  // available tail padding). We keep track of the best access unit seen so 
far,
+  // and use that when we determine we cannot accumulate any more. Then we 
start
+  // again at the bitfield following that best one.
+
+  // The accumulation is also prevented when:
+  // *) it would cross a character-aigned zero-width bitfield, or
+  // *) fine-grained bitfield access option is in effect.
+
+  CharUnits RegSize =
+  bitsToCharUnits(Context.getTargetInfo().getRegisterWidth());
+  unsigned CharBits = Context.getCharWidth();
+
+  // Data about the start of the span we're accumulating to create an access
+  // unit from. Begin is the first bitfie

[clang] [clang] Better bitfield access units (PR #65742)

2024-03-22 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

@rjmccall thanks, here is an update with those changes.  I've collapsed it to 
the 3 commits mentioned earlier

1) Tests marked up for the current behaviour
2) TargetInfo strict/flexible alignment load predicate
3) The new algorithm

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


[clang] a8ca4ab - [clang][NFC] Bitfield access unit tests (#65742)

2024-03-29 Thread Nathan Sidwell via cfe-commits

Author: Nathan Sidwell
Date: 2024-03-29T09:35:31-04:00
New Revision: a8ca4abfcfa98d28ec46ee497e1fc5e91f8e1ad6

URL: 
https://github.com/llvm/llvm-project/commit/a8ca4abfcfa98d28ec46ee497e1fc5e91f8e1ad6
DIFF: 
https://github.com/llvm/llvm-project/commit/a8ca4abfcfa98d28ec46ee497e1fc5e91f8e1ad6.diff

LOG: [clang][NFC] Bitfield access unit tests (#65742)

Verify bitfield access units.

Added: 
clang/test/CodeGen/aapcs-bitfield-access-unit.c
clang/test/CodeGen/bitfield-access-pad.c
clang/test/CodeGen/bitfield-access-unit.c
clang/test/CodeGenCXX/bitfield-access-empty.cpp
clang/test/CodeGenCXX/bitfield-access-tail.cpp
clang/test/CodeGenCXX/bitfield-ir.cpp

Modified: 
clang/test/CodeGen/arm-bitfield-alignment.c
clang/test/CodeGen/arm64-be-bitfield.c
clang/test/CodeGen/no-bitfield-type-align.c
clang/test/CodeGen/struct-x86-darwin.c
clang/test/CodeGenCXX/bitfield.cpp

Removed: 




diff  --git a/clang/test/CodeGen/aapcs-bitfield-access-unit.c 
b/clang/test/CodeGen/aapcs-bitfield-access-unit.c
new file mode 100644
index 00..ff28397c529007
--- /dev/null
+++ b/clang/test/CodeGen/aapcs-bitfield-access-unit.c
@@ -0,0 +1,231 @@
+// RUN: %clang_cc1 -triple armv8-none-linux-eabi   -fno-aapcs-bitfield-width 
-fdump-record-layouts-simple -emit-llvm -o /dev/null %s | FileCheck %s 
-check-prefixes=LAYOUT
+// RUN: %clang_cc1 -triple armebv8-none-linux-eabi   -fno-aapcs-bitfield-width 
-fdump-record-layouts-simple -emit-llvm -o /dev/null %s | FileCheck %s 
-check-prefixes=LAYOUT
+
+// RUN: %clang_cc1 -triple armv8-none-linux-eabi   -faapcs-bitfield-width 
-fdump-record-layouts-simple -emit-llvm -o /dev/null %s | FileCheck %s 
-check-prefixes=LAYOUT
+// RUN: %clang_cc1 -triple armebv8-none-linux-eabi   -faapcs-bitfield-width 
-fdump-record-layouts-simple -emit-llvm -o /dev/null %s | FileCheck %s 
-check-prefixes=LAYOUT
+
+struct st0 {
+  short c : 7;
+} st0;
+// LAYOUT-LABEL: LLVMType:%struct.st0 =
+// LAYOUT-SAME: type { i8, i8 }
+// LAYOUT: BitFields:[
+// LAYOUT-NEXT: 
+
+struct st1 {
+  int a : 10;
+  short c : 6;
+} st1;
+// LAYOUT-LABEL: LLVMType:%struct.st1 =
+// LAYOUT-SAME: type { i16, [2 x i8] }
+// LAYOUT: BitFields:[
+// LAYOUT-NEXT: 
+
+struct st2 {
+  int a : 10;
+  short c : 7;
+} st2;
+// LAYOUT-LABEL: LLVMType:%struct.st2 =
+// LAYOUT-SAME: type { i16, i8 }
+// LAYOUT: BitFields:[
+// LAYOUT-NEXT: 
+
+struct st3 {
+  volatile short c : 7;
+} st3;
+// LAYOUT-LABEL: LLVMType:%struct.st3 =
+// LAYOUT-SAME: type { i8, i8 }
+// LAYOUT: BitFields:[
+// LAYOUT-NEXT: 
+
+struct st4 {
+  int b : 9;
+  volatile char c : 5;
+} st4;
+// LAYOUT-LABEL: LLVMType:%struct.st4 =
+// LAYOUT-SAME: type { i16, [2 x i8] }
+// LAYOUT: BitFields:[
+// LAYOUT-NEXT: 
+
+struct st5 {
+  int a : 12;
+  volatile char c : 5;
+} st5;
+// LAYOUT-LABEL: LLVMType:%struct.st5 =
+// LAYOUT-SAME: type { i16, i8 }
+// LAYOUT: BitFields:[
+// LAYOUT-NEXT: 
+
+struct st6 {
+  int a : 12;
+  char b;
+  int c : 5;
+} st6;
+// LAYOUT-LABEL: LLVMType:%struct.st6 =
+// LAYOUT-SAME: type { i16, i8, i8 }
+// LAYOUT: BitFields:[
+// LAYOUT-NEXT: 
+
+struct st7a {
+  char a;
+  int b : 5;
+} st7a;
+// LAYOUT-LABEL: LLVMType:%struct.st7a =
+// LAYOUT-SAME: type { i8, i8, [2 x i8] }
+// LAYOUT: BitFields:[
+// LAYOUT-NEXT: 
+
+struct st7b {
+  char x;
+  volatile struct st7a y;
+} st7b;
+// LAYOUT-LABEL: LLVMType:%struct.st7b =
+// LAYOUT-SAME: type { i8, [3 x i8], %struct.st7a }
+// LAYOUT: BitFields:[
+// LAYOUT-NEXT: ]>
+
+struct st8 {
+  unsigned f : 16;
+} st8;
+// LAYOUT-LABEL: LLVMType:%struct.st8 =
+// LAYOUT-SAME: type { i16, [2 x i8] }
+// LAYOUT: BitFields:[
+// LAYOUT-NEXT: 
+
+struct st9{
+  int f : 8;
+} st9;
+// LAYOUT-LABEL: LLVMType:%struct.st9 =
+// LAYOUT-SAME: type { i8, [3 x i8] }
+// LAYOUT: BitFields:[
+// LAYOUT-NEXT: 
+
+struct st10{
+  int e : 1;
+  int f : 8;
+} st10;
+// LAYOUT-LABEL: LLVMType:%struct.st10 =
+// LAYOUT-SAME: type { i16, [2 x i8] }
+// LAYOUT: BitFields:[
+// LAYOUT-NEXT: 
+
+struct st11{
+  char e;
+  int f : 16;
+} st11;
+// LAYOUT-LABEL: LLVMType:%struct.st11 =
+// LAYOUT-SAME: type <{ i8, i16, i8 }>
+// LAYOUT: BitFields:[
+// LAYOUT-NEXT: 
+
+struct st12{
+  int e : 8;
+  int f : 16;
+} st12;
+// LAYOUT-LABEL: LLVMType:%struct.st12 =
+// LAYOUT-SAME: type { i24 }
+// LAYOUT: BitFields:[
+// LAYOUT-NEXT: 
+
+struct st13 {
+  char a : 8;
+  int b : 32;
+} __attribute__((packed)) st13;
+// LAYOUT-LABEL: LLVMType:%struct.st13 =
+// LAYOUT-SAME: type { [5 x i8] }
+// LAYOUT: BitFields:[
+// LAYOUT-NEXT: 
+
+struct st14 {
+  char a : 8;
+} __attribute__((packed)) st14;
+// LAYOUT-LABEL: LLVMType:%struct.st14 =
+// LAYOUT-SAME: type { i8 }
+// LAYOUT: BitFields:[
+// LAYOUT-NEXT: 
+
+struct st15 {
+  short a : 8;
+} __attribute__((packed)) st15;
+// LAYOUT-LABEL: LLVMType:%struct.st15 =
+// LAYOUT-SAME: type { i8 }
+// LAYOUT: BitFields:[
+// LAYOUT-NEXT: 
+
+struct st16 {
+  int a :

[clang] 7df79ab - [clang] TargetInfo hook for unaligned bitfields (#65742)

2024-03-29 Thread Nathan Sidwell via cfe-commits

Author: Nathan Sidwell
Date: 2024-03-29T09:35:31-04:00
New Revision: 7df79ababee8d03b27bbaba1aabc2ec4ea14143e

URL: 
https://github.com/llvm/llvm-project/commit/7df79ababee8d03b27bbaba1aabc2ec4ea14143e
DIFF: 
https://github.com/llvm/llvm-project/commit/7df79ababee8d03b27bbaba1aabc2ec4ea14143e.diff

LOG: [clang] TargetInfo hook for unaligned bitfields (#65742)

Promote ARM & AArch64's HasUnaligned to TargetInfo and set for all
targets.

Added: 


Modified: 
clang/include/clang/Basic/TargetInfo.h
clang/lib/Basic/TargetInfo.cpp
clang/lib/Basic/Targets/AArch64.cpp
clang/lib/Basic/Targets/AArch64.h
clang/lib/Basic/Targets/ARM.cpp
clang/lib/Basic/Targets/ARM.h
clang/lib/Basic/Targets/LoongArch.cpp
clang/lib/Basic/Targets/LoongArch.h
clang/lib/Basic/Targets/Mips.h
clang/lib/Basic/Targets/PPC.h
clang/lib/Basic/Targets/SystemZ.h
clang/lib/Basic/Targets/VE.h
clang/lib/Basic/Targets/WebAssembly.h
clang/lib/Basic/Targets/X86.h

Removed: 




diff  --git a/clang/include/clang/Basic/TargetInfo.h 
b/clang/include/clang/Basic/TargetInfo.h
index 374595edd2ce4a..e1ef7454f01669 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -267,6 +267,9 @@ class TargetInfo : public TransferrableTargetInfo,
   LLVM_PREFERRED_TYPE(bool)
   unsigned AllowAMDGPUUnsafeFPAtomics : 1;
 
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned HasUnalignedAccess : 1;
+
   unsigned ARMCDECoprocMask : 8;
 
   unsigned MaxOpenCLWorkGroupSize;
@@ -859,6 +862,18 @@ class TargetInfo : public TransferrableTargetInfo,
 return PointerWidth;
   }
 
+  /// Return true iff unaligned accesses are a single instruction (rather than
+  /// a synthesized sequence).
+  bool hasUnalignedAccess() const { return HasUnalignedAccess; }
+
+  /// Return true iff unaligned accesses are cheap. This affects placement and
+  /// size of bitfield loads/stores. (Not the ABI-mandated placement of
+  /// the bitfields themselves.)
+  bool hasCheapUnalignedBitFieldAccess() const {
+// Simply forward to the unaligned access getter.
+return hasUnalignedAccess();
+  }
+
   /// \brief Returns the default value of the __USER_LABEL_PREFIX__ macro,
   /// which is the prefix given to user symbols by default.
   ///

diff  --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp
index 5d9055174c089a..f96956f31d50dc 100644
--- a/clang/lib/Basic/TargetInfo.cpp
+++ b/clang/lib/Basic/TargetInfo.cpp
@@ -157,6 +157,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) {
   HasAArch64SVETypes = false;
   HasRISCVVTypes = false;
   AllowAMDGPUUnsafeFPAtomics = false;
+  HasUnalignedAccess = false;
   ARMCDECoprocMask = 0;
 
   // Default to no types using fpret.

diff  --git a/clang/lib/Basic/Targets/AArch64.cpp 
b/clang/lib/Basic/Targets/AArch64.cpp
index 1c3199bd76eed6..1569b5e04b770a 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -188,6 +188,8 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple 
&Triple,
   assert(UseBitFieldTypeAlignment && "bitfields affect type alignment");
   UseZeroLengthBitfieldAlignment = true;
 
+  HasUnalignedAccess = true;
+
   // AArch64 targets default to using the ARM C++ ABI.
   TheCXXABI.set(TargetCXXABI::GenericAArch64);
 
@@ -496,7 +498,7 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions 
&Opts,
   if (HasPAuthLR)
 Builder.defineMacro("__ARM_FEATURE_PAUTH_LR", "1");
 
-  if (HasUnaligned)
+  if (HasUnalignedAccess)
 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
 
   if ((FPU & NeonMode) && HasFullFP16)
@@ -921,7 +923,8 @@ bool 
AArch64TargetInfo::handleTargetFeatures(std::vector &Features,
   HasSM4 = true;
 }
 if (Feature == "+strict-align")
-  HasUnaligned = false;
+  HasUnalignedAccess = false;
+
 // All predecessor archs are added but select the latest one for ArchKind.
 if (Feature == "+v8a" && ArchInfo->Version < llvm::AArch64::ARMV8A.Version)
   ArchInfo = &llvm::AArch64::ARMV8A;

diff  --git a/clang/lib/Basic/Targets/AArch64.h 
b/clang/lib/Basic/Targets/AArch64.h
index 542894c66412dc..12fb50286f7511 100644
--- a/clang/lib/Basic/Targets/AArch64.h
+++ b/clang/lib/Basic/Targets/AArch64.h
@@ -38,7 +38,6 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public 
TargetInfo {
   bool HasSHA2 = false;
   bool HasSHA3 = false;
   bool HasSM4 = false;
-  bool HasUnaligned = true;
   bool HasFullFP16 = false;
   bool HasDotProd = false;
   bool HasFP16FML = false;

diff  --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp
index 55b71557452fa0..877799c66ec4f2 100644
--- a/clang/lib/Basic/Targets/ARM.cpp
+++ b/clang/lib/Basic/Targets/ARM.cpp
@@ -509,7 +509,7 @@ bool 
ARMTargetInfo::handleTargetFeatures(std::vector &Features,
   SHA2 = 0;
   AES = 0;
   DSP = 0;
-  Unaligned = 1;
+  HasUnalignedAccess = true;
   SoftF

[clang] [clang] Better bitfield access units (PR #65742)

2024-03-29 Thread Nathan Sidwell via cfe-commits

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


[clang] [clang] Better bitfield access units (PR #65742)

2024-03-29 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

Committed, expect tailclipping cleanup PR soon

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


[clang] [clang] Move tailclipping to bitfield allocation (PR #87090)

2024-03-29 Thread Nathan Sidwell via cfe-commits

https://github.com/urnathan created 
https://github.com/llvm/llvm-project/pull/87090

This follows on from PR65742. As I suspected clipTailPadding's functionality 
can be moved into accumulateBitfields; it has sufficient information now.  It 
turns out that clipTailPadding was undoing some of the work just added to 
accumulateBitfields.  Specifically, on a strict-alignment LP64 machine, 
accumulateBitfields could determine that a 24-bit access unit was the best unit 
to use (loading 3 separate bytes being better than 4). But if those 3 bytes 
were followed by a padding byte, clipTailPadding would not make the storage a 
3-byte array, and the access unit would be an (unaligned) i32.  Boo!  The new 
testcase shows this -- it's written to work on ILP32 and LP64, but the common 
case I think would be on LP64 where a pointer follows the bitfields, and 
there's 4 bytes of alignment padding between.

The fine-grained-bitfield accesses needed adjusting, to preserve the existing 
behaviour of extending them into useable tail padding. You'll see we now check 
this later -- allowing it to grow, but preventing accumulation of a subsequent 
span. I think that's in keeping with the desired behaviour of that option.


>From 4d9861a9ca23d8de7b33c4b830b5c6f78e8a3768 Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Sun, 24 Mar 2024 09:37:46 -0400
Subject: [PATCH 1/2] Move bitfield clipping into bitfield accumulation

---
 clang/lib/CodeGen/CGRecordLayoutBuilder.cpp | 63 -
 clang/test/CodeGen/bitfield-access-unit.c   | 18 ++
 2 files changed, 55 insertions(+), 26 deletions(-)

diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp 
b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
index e32023aeac1e6f..5b9045f661e048 100644
--- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -41,10 +41,11 @@ namespace {
 ///   contains enough information to determine where the runs break.  Microsoft
 ///   and Itanium follow different rules and use different codepaths.
 /// * It is desired that, when possible, bitfields use the appropriate iN type
-///   when lowered to llvm types.  For example unsigned x : 24 gets lowered to
+///   when lowered to llvm types. For example unsigned x : 24 gets lowered to
 ///   i24.  This isn't always possible because i24 has storage size of 32 bit
-///   and if it is possible to use that extra byte of padding we must use
-///   [i8 x 3] instead of i24.  The function clipTailPadding does this.
+///   and if it is possible to use that extra byte of padding we must use [i8 x
+///   3] instead of i24. This is computed when accumulating bitfields in
+///   accumulateBitfields.
 ///   C++ examples that require clipping:
 ///   struct { int a : 24; char b; }; // a must be clipped, b goes at offset 3
 ///   struct A { int a : 24; ~A(); }; // a must be clipped because:
@@ -197,9 +198,7 @@ struct CGRecordLowering {
   /// not the primary vbase of some base class.
   bool hasOwnStorage(const CXXRecordDecl *Decl, const CXXRecordDecl *Query);
   void calculateZeroInit();
-  /// Lowers bitfield storage types to I8 arrays for bitfields with tail
-  /// padding that is or can potentially be used.
-  void clipTailPadding();
+  void checkTailPadding();
   /// Determines if we need a packed llvm struct.
   void determinePacked(bool NVBaseType);
   /// Inserts padding everywhere it's needed.
@@ -302,7 +301,7 @@ void CGRecordLowering::lower(bool NVBaseType) {
   }
   llvm::stable_sort(Members);
   Members.push_back(StorageInfo(Size, getIntNType(8)));
-  clipTailPadding();
+  checkTailPadding();
   determinePacked(NVBaseType);
   insertPadding();
   Members.pop_back();
@@ -521,6 +520,7 @@ 
CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
   // available padding characters.
   RecordDecl::field_iterator BestEnd = Begin;
   CharUnits BestEndOffset;
+  bool BestClipped; // Whether the representation must be in a byte array.
 
   for (;;) {
 // AtAlignedBoundary is true iff Field is the (potential) start of a new
@@ -583,10 +583,9 @@ 
CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
 // this is the best seen so far.
 BestEnd = Field;
 BestEndOffset = BeginOffset + AccessSize;
-if (Types.getCodeGenOpts().FineGrainedBitfieldAccesses)
-  // Fine-grained access, so no merging of spans.
-  InstallBest = true;
-else if (!BitSizeSinceBegin)
+// Assume clipped until proven not below.
+BestClipped = true;
+if (!BitSizeSinceBegin)
   // A zero-sized initial span -- this will install nothing and reset
   // for another.
   InstallBest = true;
@@ -614,6 +613,12 @@ 
CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
 // The access unit is not at a naturally aligned offset within the
 // structure.
 InstallBest = true;
+
+  if (InstallBest && BestEnd == Fi

[clang] [clang] Move tailclipping to bitfield allocation (PR #87090)

2024-03-29 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

Sigh, clipTailPadding is still needed, because of no_unique_address and empty 
base placement.  Will update.

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


[clang] [llvm] MIPS: Support -m(no-)unaligned-access for r6 (PR #85174)

2024-04-01 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

#65742 is committed, so MIPS' TargetInfo will need adjusting to propagate the 
unaligned capability. See 7df79ababee8

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


[clang] [clang] Fix bitfield access unit for vbase corner case (PR #87238)

2024-04-01 Thread Nathan Sidwell via cfe-commits

https://github.com/urnathan created 
https://github.com/llvm/llvm-project/pull/87238

This fixes #87227 My change to bitfield access unit allocation (#65742) causes 
an ICE for a corner case of vbase allocation: a class where an unshared (i.e. 
not the nearly-empty base optimization) vbase is placed below nvsize. 
Unfortunately, although there was a testcase for such a class layout, it didn't 
have the immediately preceding bitfield -- the reason the scissor needs to be 
correct.

The fix is to break out the scissor calculation from `accumulateVbases`, and 
have `allocateBitfields` be aware it is creating either the base subobject, or 
the complete object. Then it can call the scissor calculator to get the 
appropriate upper bound. The scissor calculation can cause a base walk, I 
thought it best to cache the result in `allocateBitfields`, as we can reach 
that point multiple times with unfortunately-sized bitfield spans.

In breaking out the scissor calculation, I discovered a couple more member fns 
that could be const qualified -- as before do you want that as a separate PR?

>From 3b0bfce77d6d70bc35316484b39bb83123b8a583 Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Sun, 31 Mar 2024 11:11:13 -0400
Subject: [PATCH] [clang] Fix bitfield access unit for vbase corner case

We must account for unshared vbases that are allocated below nvsize.
---
 clang/lib/CodeGen/CGRecordLayoutBuilder.cpp   |  57 +++---
 .../test/CodeGenCXX/bitfield-access-tail.cpp  | 104 --
 2 files changed, 113 insertions(+), 48 deletions(-)

diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp 
b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
index e32023aeac1e6f..634a55fec5182e 100644
--- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -185,9 +185,10 @@ struct CGRecordLowering {
   /// Lowers an ASTRecordLayout to a llvm type.
   void lower(bool NonVirtualBaseType);
   void lowerUnion(bool isNoUniqueAddress);
-  void accumulateFields();
+  void accumulateFields(bool isNonVirtualBaseType);
   RecordDecl::field_iterator
-  accumulateBitFields(RecordDecl::field_iterator Field,
+  accumulateBitFields(bool isNonVirtualBaseType,
+  RecordDecl::field_iterator Field,
   RecordDecl::field_iterator FieldEnd);
   void computeVolatileBitfields();
   void accumulateBases();
@@ -195,8 +196,10 @@ struct CGRecordLowering {
   void accumulateVBases();
   /// Recursively searches all of the bases to find out if a vbase is
   /// not the primary vbase of some base class.
-  bool hasOwnStorage(const CXXRecordDecl *Decl, const CXXRecordDecl *Query);
+  bool hasOwnStorage(const CXXRecordDecl *Decl,
+ const CXXRecordDecl *Query) const;
   void calculateZeroInit();
+  CharUnits calculateTailClippingOffset(bool isNonVirtualBaseType) const;
   /// Lowers bitfield storage types to I8 arrays for bitfields with tail
   /// padding that is or can potentially be used.
   void clipTailPadding();
@@ -287,7 +290,7 @@ void CGRecordLowering::lower(bool NVBaseType) {
 computeVolatileBitfields();
 return;
   }
-  accumulateFields();
+  accumulateFields(NVBaseType);
   // RD implies C++.
   if (RD) {
 accumulateVPtrs();
@@ -378,12 +381,12 @@ void CGRecordLowering::lowerUnion(bool isNoUniqueAddress) 
{
 Packed = true;
 }
 
-void CGRecordLowering::accumulateFields() {
+void CGRecordLowering::accumulateFields(bool isNonVirtualBaseType) {
   for (RecordDecl::field_iterator Field = D->field_begin(),
   FieldEnd = D->field_end();
Field != FieldEnd;) {
 if (Field->isBitField()) {
-  Field = accumulateBitFields(Field, FieldEnd);
+  Field = accumulateBitFields(isNonVirtualBaseType, Field, FieldEnd);
   assert((Field == FieldEnd || !Field->isBitField()) &&
  "Failed to accumulate all the bitfields");
 } else if (Field->isZeroSize(Context)) {
@@ -404,9 +407,12 @@ void CGRecordLowering::accumulateFields() {
 }
 
 // Create members for bitfields. Field is a bitfield, and FieldEnd is the end
-// iterator of the record. Return the first non-bitfield encountered.
+// iterator of the record. Return the first non-bitfield encountered.  We need
+// to know whether this is the base or complete layout, as virtual bases could
+// affect the upper bound of bitfield access unit allocation.
 RecordDecl::field_iterator
-CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
+CGRecordLowering::accumulateBitFields(bool isNonVirtualBaseType,
+  RecordDecl::field_iterator Field,
   RecordDecl::field_iterator FieldEnd) {
   if (isDiscreteBitFieldABI()) {
 // Run stores the first element of the current run of bitfields. FieldEnd 
is
@@ -505,6 +511,10 @@ 
CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
   bitsToCharUnits(Context.getTargetInfo().getRegisterWidth())

[clang] [clang] Move tailclipping to bitfield allocation (PR #87090)

2024-04-01 Thread Nathan Sidwell via cfe-commits

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


[clang] [clang] Better bitfield access units (PR #65742)

2024-04-01 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

Be aware of bug #87227 and PR #87238 to address that

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


[clang] MIPS/Clang: Set HasUnalignedAccess false if +strict-align (PR #87257)

2024-04-01 Thread Nathan Sidwell via cfe-commits


@@ -330,6 +331,8 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public 
TargetInfo {
 IsMicromips = true;
   else if (Feature == "+mips32r6" || Feature == "+mips64r6")
 HasUnalignedAccess = true;
+  else if (Feature == "+strict-align")
+StrictAlign = true;

urnathan wrote:

Why not clear HasUnalignedAccess directly here? That's what AArch64 and ARM do.

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


[clang] [clang] Fix bitfield access unit for vbase corner case (PR #87238)

2024-04-01 Thread Nathan Sidwell via cfe-commits

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


[clang] [clang] Fix bitfield access unit for vbase corner case (PR #87238)

2024-04-01 Thread Nathan Sidwell via cfe-commits

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


[clang] [clang] Strict aliasing warning ala GCC [PR50066] (PR #74155)

2024-02-13 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

> On the LLVM side, there's very little interesting logic; it's basically just 
> walking the tree of metadata nodes generated by clang. See 
> https://llvm.org/docs/LangRef.html#tbaa-node-semantics . The hard part of the 
> refactoring would just be adding an abstraction for the underlying 
> information.

IIUC you're suggesting movint the TBAA data origination from CodeGen into 
(probably) Sema and/or TargetInfo and then deriving the LLVM info in CodeGen 
from that.  I.e. keep once source of truth, but move where it is?

I don't think it'd be that hard -- mostly mechanical. And I suspect only the 
scalar TBAA needs so moving, the structure-related stuff is sufficiently 
different to that strict-aliasing wants.

Although you don't explicitly say it, the implication is you'd be ameanable to 
such an approach?

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


[clang] [clang] Better bitfield access units (PR #65742)

2024-03-08 Thread Nathan Sidwell via cfe-commits


@@ -394,33 +412,155 @@ void CGRecordLowering::accumulateFields() {
   : getStorageType(*Field),
   *Field));
   ++Field;
-} else {
-  ++Field;
 }
   }
 }
 
-void
-CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
-  RecordDecl::field_iterator FieldEnd) {
-  // Run stores the first element of the current run of bitfields.  FieldEnd is
-  // used as a special value to note that we don't have a current run.  A
-  // bitfield run is a contiguous collection of bitfields that can be stored in
-  // the same storage block.  Zero-sized bitfields and bitfields that would
-  // cross an alignment boundary break a run and start a new one.
-  RecordDecl::field_iterator Run = FieldEnd;
-  // Tail is the offset of the first bit off the end of the current run.  It's
-  // used to determine if the ASTRecordLayout is treating these two bitfields 
as
-  // contiguous.  StartBitOffset is offset of the beginning of the Run.
-  uint64_t StartBitOffset, Tail = 0;
+namespace {
+
+// A run of bitfields assigned to the same access unit -- the size of memory
+// loads & stores.
+class BitFieldAccessUnit {
+  RecordDecl::field_iterator Begin; // Field at start of this access unit.
+  RecordDecl::field_iterator End;   // Field just after this access unit.
+
+  CharUnits StartOffset; // Starting offset in the containing record.
+  CharUnits EndOffset;   // Finish offset (exclusive) in the containing record.
+
+  bool ContainsVolatile; // This access unit contains a volatile bitfield.
+
+public:
+  // End barrier constructor.
+  BitFieldAccessUnit(RecordDecl::field_iterator F, CharUnits Offset,
+ bool Volatile = false)
+  : Begin(F), End(F), StartOffset(Offset), EndOffset(Offset),
+ContainsVolatile(Volatile) {}
+
+  // Collect contiguous bitfields into an access unit.
+  BitFieldAccessUnit(RecordDecl::field_iterator FieldBegin,
+ RecordDecl::field_iterator FieldEnd,
+ const CGRecordLowering &CGRL);

urnathan wrote:

Updated to add gatherBitFieldAccessUnit and installBitFieldAccessUnit members 
of CGRecordLowering.  You're right that it makes the structure clearer.

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


[clang] [clang] Better bitfield access units (PR #65742)

2024-03-08 Thread Nathan Sidwell via cfe-commits


@@ -394,33 +412,155 @@ void CGRecordLowering::accumulateFields() {
   : getStorageType(*Field),
   *Field));
   ++Field;
-} else {
-  ++Field;
 }
   }
 }
 
-void
-CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
-  RecordDecl::field_iterator FieldEnd) {
-  // Run stores the first element of the current run of bitfields.  FieldEnd is
-  // used as a special value to note that we don't have a current run.  A
-  // bitfield run is a contiguous collection of bitfields that can be stored in
-  // the same storage block.  Zero-sized bitfields and bitfields that would
-  // cross an alignment boundary break a run and start a new one.
-  RecordDecl::field_iterator Run = FieldEnd;
-  // Tail is the offset of the first bit off the end of the current run.  It's
-  // used to determine if the ASTRecordLayout is treating these two bitfields 
as
-  // contiguous.  StartBitOffset is offset of the beginning of the Run.
-  uint64_t StartBitOffset, Tail = 0;
+namespace {
+
+// A run of bitfields assigned to the same access unit -- the size of memory
+// loads & stores.
+class BitFieldAccessUnit {
+  RecordDecl::field_iterator Begin; // Field at start of this access unit.
+  RecordDecl::field_iterator End;   // Field just after this access unit.
+
+  CharUnits StartOffset; // Starting offset in the containing record.
+  CharUnits EndOffset;   // Finish offset (exclusive) in the containing record.
+
+  bool ContainsVolatile; // This access unit contains a volatile bitfield.
+
+public:
+  // End barrier constructor.
+  BitFieldAccessUnit(RecordDecl::field_iterator F, CharUnits Offset,
+ bool Volatile = false)
+  : Begin(F), End(F), StartOffset(Offset), EndOffset(Offset),
+ContainsVolatile(Volatile) {}
+
+  // Collect contiguous bitfields into an access unit.
+  BitFieldAccessUnit(RecordDecl::field_iterator FieldBegin,
+ RecordDecl::field_iterator FieldEnd,
+ const CGRecordLowering &CGRL);
+
+  // Compute the access unit following this one -- which might be a barrier at
+  // Limit.
+  BitFieldAccessUnit accumulateNextUnit(RecordDecl::field_iterator FieldEnd,
+CharUnits Limit,
+const CGRecordLowering &CGRL) const {
+return end() != FieldEnd ? BitFieldAccessUnit(end(), FieldEnd, CGRL)
+ : BitFieldAccessUnit(FieldEnd, Limit);
+  }
+  // Re-set the end of this unit if there is space before Probe starts.
+  void enlargeIfSpace(const BitFieldAccessUnit &Probe, CharUnits Offset) {
+if (Probe.getStartOffset() >= Offset) {
+  End = Probe.begin();
+  EndOffset = Offset;
+}
+  }
+
+public:
+  RecordDecl::field_iterator begin() const { return Begin; }
+  RecordDecl::field_iterator end() const { return End; }
+
+public:
+  // Accessors
+  CharUnits getSize() const { return EndOffset - StartOffset; }
+  CharUnits getStartOffset() const { return StartOffset; }
+  CharUnits getEndOffset() const { return EndOffset; }
+
+  // Predicates
+  bool isBarrier() const { return getSize().isZero(); }
+  bool hasVolatile() const { return ContainsVolatile; }
+
+  // Create the containing access unit and install the bitfields.
+  void installUnit(CGRecordLowering &CGRL) const {
+if (!isBarrier()) {
+  // Add the storage member for the access unit to the record. The
+  // bitfields get the offset of their storage but come afterward and 
remain
+  // there after a stable sort.
+  llvm::Type *Type = CGRL.getIntNType(CGRL.Context.toBits(getSize()));
+  CGRL.Members.push_back(CGRL.StorageInfo(getStartOffset(), Type));
+  for (auto F : *this)
+if (!F->isZeroLengthBitField(CGRL.Context))
+  CGRL.Members.push_back(CGRecordLowering::MemberInfo(
+  getStartOffset(), CGRecordLowering::MemberInfo::Field, nullptr,
+  F));
+}
+  }
+};
+
+// Create an access unit of contiguous bitfields.
+BitFieldAccessUnit::BitFieldAccessUnit(RecordDecl::field_iterator FieldBegin,
+   RecordDecl::field_iterator FieldEnd,
+   const CGRecordLowering &CGRL)
+: BitFieldAccessUnit(FieldBegin, CharUnits::Zero(),
+ FieldBegin->getType().isVolatileQualified()) {
+  assert(End != FieldEnd);
+
+  uint64_t StartBit = CGRL.getFieldBitOffset(*FieldBegin);
+  uint64_t BitSize = End->getBitWidthValue(CGRL.Context);
+  unsigned CharBits = CGRL.Context.getCharWidth();
+
+  assert(!(StartBit % CharBits) && "Not at start of char");
+
+  ++End;
+  if (BitSize ||
+  !(CGRL.Context.getTargetInfo().useZeroLengthBitfieldAlignment() ||
+CGRL.Context.getTargetInfo().useBitFieldTypeAlignment()))
+// The first field is not a (zero-width) barrier. Collect contiguous 
fields.
+for (; End != FieldEnd; ++End) {
+  uin

[clang] [clang] Better bitfield access units (PR #65742)

2024-03-08 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

This update 
* moves the creation and installation of the BitFieldAccessUnit objects into 
CGRecordLowering.
* adds aarch64 and arm darwin target tests, as those have different layout 
rules (let me know if I've missed something here).
* Simplifies the checking of barriers -- an explicit flag, rather than 
inferring from a zero-sized unit.  The latter can represent a non-barrier that 
happens to fall at a byte boundary, and results in a simplification of the 
gathering operation.
* changes the API of accumulateBitFields to return the following non-bitfield.  
This means that the caller does not itself have to scan across the bitfields to 
find their range. Given the bitfield processor has scan the bitfields anyway, 
this seems like a win.
* because of that, the determination of the limiting boundary, only needed for 
non-ms abis, is moved to where it is needed.

FWIW, I experimented with the representation in BitFieldAccessUnit:
* Although adjacent units are contiguous and it would seem one of Begin and End 
is unneeded, it turned out easiest to have both -- omitting Begin simply makes 
the calling code to the bookwork
* Whether to represent access unit boundaries as bit or char offsets.  
Whichever is chosen leads to conversions to the other representation at various 
points. Using chars was the least painful, and makes it clear these are char 
boundaries.

It might be possible to go further and perform the accumulation you outlined 
above, but there's enough churn in this update that I thought it best to push 
it.

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


[clang] [clang] Better bitfield access units (PR #65742)

2024-03-12 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

@rjmccall here's a refactoring along the lines you suggested. Once one stops 
worrying about rescanning when the next access unit fails to accumulate into 
the current one, things get simpler. The compiler should be able to turn the 
boolean conditional flow within the loop body into direct control flow. 

Would you like the API change I introduced in the previous patch (having 
`accumulateBitFields` return the following non-bitfield) broken out into a 
separate PR?

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


[clang] [clang][NFC] constify or staticify some fns (PR #82874)

2024-02-24 Thread Nathan Sidwell via cfe-commits

https://github.com/urnathan created 
https://github.com/llvm/llvm-project/pull/82874

As mentioned in PR https://github.com/llvm/llvm-project/pull/65742, these 
functions do not alter the object -- and on one case don't even need it. Thus 
marking them static or const as appropriate. I constified a few more than I'd 
originally fallen over.

>From ccc917e8a826bbefcd68df4e013edbd97bb19914 Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Fri, 2 Feb 2024 08:01:21 -0500
Subject: [PATCH] [clang][NFC] constify or staticify some fns

These functions do not alter the object -- and on one case don't even
need it. Thus marking them static or const as appropriate.
---
 clang/lib/CodeGen/CGRecordLayoutBuilder.cpp | 28 ++---
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp 
b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
index 868ef810f3c4e8..7822903b89ce47 100644
--- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -95,7 +95,7 @@ struct CGRecordLowering {
   CGRecordLowering(CodeGenTypes &Types, const RecordDecl *D, bool Packed);
   // Short helper routines.
   /// Constructs a MemberInfo instance from an offset and llvm::Type *.
-  MemberInfo StorageInfo(CharUnits Offset, llvm::Type *Data) {
+  static MemberInfo StorageInfo(CharUnits Offset, llvm::Type *Data) {
 return MemberInfo(Offset, MemberInfo::Field, Data);
   }
 
@@ -104,7 +104,7 @@ struct CGRecordLowering {
   /// fields of the same formal type.  We want to emit a layout with
   /// these discrete storage units instead of combining them into a
   /// continuous run.
-  bool isDiscreteBitFieldABI() {
+  bool isDiscreteBitFieldABI() const {
 return Context.getTargetInfo().getCXXABI().isMicrosoft() ||
D->isMsStruct(Context);
   }
@@ -121,22 +121,22 @@ struct CGRecordLowering {
   /// other bases, which complicates layout in specific ways.
   ///
   /// Note specifically that the ms_struct attribute doesn't change this.
-  bool isOverlappingVBaseABI() {
+  bool isOverlappingVBaseABI() const {
 return !Context.getTargetInfo().getCXXABI().isMicrosoft();
   }
 
   /// Wraps llvm::Type::getIntNTy with some implicit arguments.
-  llvm::Type *getIntNType(uint64_t NumBits) {
+  llvm::Type *getIntNType(uint64_t NumBits) const {
 unsigned AlignedBits = llvm::alignTo(NumBits, Context.getCharWidth());
 return llvm::Type::getIntNTy(Types.getLLVMContext(), AlignedBits);
   }
   /// Get the LLVM type sized as one character unit.
-  llvm::Type *getCharType() {
+  llvm::Type *getCharType() const {
 return llvm::Type::getIntNTy(Types.getLLVMContext(),
  Context.getCharWidth());
   }
   /// Gets an llvm type of size NumChars and alignment 1.
-  llvm::Type *getByteArrayType(CharUnits NumChars) {
+  llvm::Type *getByteArrayType(CharUnits NumChars) const {
 assert(!NumChars.isZero() && "Empty byte arrays aren't allowed.");
 llvm::Type *Type = getCharType();
 return NumChars == CharUnits::One() ? Type :
@@ -144,7 +144,7 @@ struct CGRecordLowering {
   }
   /// Gets the storage type for a field decl and handles storage
   /// for itanium bitfields that are smaller than their declared type.
-  llvm::Type *getStorageType(const FieldDecl *FD) {
+  llvm::Type *getStorageType(const FieldDecl *FD) const {
 llvm::Type *Type = Types.ConvertTypeForMem(FD->getType());
 if (!FD->isBitField()) return Type;
 if (isDiscreteBitFieldABI()) return Type;
@@ -152,29 +152,29 @@ struct CGRecordLowering {
  (unsigned)Context.toBits(getSize(Type;
   }
   /// Gets the llvm Basesubobject type from a CXXRecordDecl.
-  llvm::Type *getStorageType(const CXXRecordDecl *RD) {
+  llvm::Type *getStorageType(const CXXRecordDecl *RD) const {
 return Types.getCGRecordLayout(RD).getBaseSubobjectLLVMType();
   }
-  CharUnits bitsToCharUnits(uint64_t BitOffset) {
+  CharUnits bitsToCharUnits(uint64_t BitOffset) const {
 return Context.toCharUnitsFromBits(BitOffset);
   }
-  CharUnits getSize(llvm::Type *Type) {
+  CharUnits getSize(llvm::Type *Type) const {
 return CharUnits::fromQuantity(DataLayout.getTypeAllocSize(Type));
   }
-  CharUnits getAlignment(llvm::Type *Type) {
+  CharUnits getAlignment(llvm::Type *Type) const {
 return CharUnits::fromQuantity(DataLayout.getABITypeAlign(Type));
   }
-  bool isZeroInitializable(const FieldDecl *FD) {
+  bool isZeroInitializable(const FieldDecl *FD) const {
 return Types.isZeroInitializable(FD->getType());
   }
-  bool isZeroInitializable(const RecordDecl *RD) {
+  bool isZeroInitializable(const RecordDecl *RD) const {
 return Types.isZeroInitializable(RD);
   }
   void appendPaddingBytes(CharUnits Size) {
 if (!Size.isZero())
   FieldTypes.push_back(getByteArrayType(Size));
   }
-  uint64_t getFieldBitOffset(const FieldDecl *FD) {
+  uint64_t getFieldBitOffset(const FieldDecl *FD) const {
 retur

[clang] [clang][NFC] constify or staticify some CGRecordLowering fns (PR #82874)

2024-02-24 Thread Nathan Sidwell via cfe-commits

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


[clang] 8e22fff - [clang] Remove trailing whitespace

2024-02-24 Thread Nathan Sidwell via cfe-commits

Author: Nathan Sidwell
Date: 2024-02-24T12:25:08-05:00
New Revision: 8e22fffc85b36784146041499b716cec74285660

URL: 
https://github.com/llvm/llvm-project/commit/8e22fffc85b36784146041499b716cec74285660
DIFF: 
https://github.com/llvm/llvm-project/commit/8e22fffc85b36784146041499b716cec74285660.diff

LOG: [clang] Remove trailing whitespace

Fix commit 66f6929fec3ae

Added: 


Modified: 
clang/docs/HLSL/ExpectedDifferences.rst

Removed: 




diff  --git a/clang/docs/HLSL/ExpectedDifferences.rst 
b/clang/docs/HLSL/ExpectedDifferences.rst
index 60001b22dc7920..d1b6010f10f43a 100644
--- a/clang/docs/HLSL/ExpectedDifferences.rst
+++ b/clang/docs/HLSL/ExpectedDifferences.rst
@@ -93,7 +93,7 @@ behavior between Clang and DXC. Some examples include:
 fma(X, Y, Z); // DXC: Fails to resolve no known conversion from float to 
double.
   // Clang: Resolves to fma(double,double,double).
   #endif
-
+
 double D = dot(A, B); // DXC: Resolves to dot(double3, double3), fails 
DXIL Validation.
   // FXC: Expands to compute double dot product with 
fmul/fadd
   // Clang: Resolves to dot(float3, float3), emits 
conversion warnings.
@@ -102,7 +102,7 @@ behavior between Clang and DXC. Some examples include:
 
 .. note::
 
-  In Clang, a conscious decision was made to exclude the 
``dot(vector, vector)`` 
+  In Clang, a conscious decision was made to exclude the 
``dot(vector, vector)``
   overload and allow overload resolution to resolve the
   ``vector`` overload. This approach provides ``-Wconversion``
   diagnostic notifying the user of the conversion rather than silently altering



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


[clang] [clang][NFC] constify or staticify some CGRecordLowering fns (PR #82874)

2024-02-24 Thread Nathan Sidwell via cfe-commits

https://github.com/urnathan updated 
https://github.com/llvm/llvm-project/pull/82874

>From 792c608cc55d89552cf86d058796825a1f428f5d Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Fri, 2 Feb 2024 08:01:21 -0500
Subject: [PATCH] [clang][NFC] constify or staticify some fns

These functions do not alter the object -- and on one case don't even
need it. Thus marking them static or const as appropriate.
---
 clang/lib/CodeGen/CGRecordLayoutBuilder.cpp | 28 ++---
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp 
b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
index 868ef810f3c4e8..7822903b89ce47 100644
--- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -95,7 +95,7 @@ struct CGRecordLowering {
   CGRecordLowering(CodeGenTypes &Types, const RecordDecl *D, bool Packed);
   // Short helper routines.
   /// Constructs a MemberInfo instance from an offset and llvm::Type *.
-  MemberInfo StorageInfo(CharUnits Offset, llvm::Type *Data) {
+  static MemberInfo StorageInfo(CharUnits Offset, llvm::Type *Data) {
 return MemberInfo(Offset, MemberInfo::Field, Data);
   }
 
@@ -104,7 +104,7 @@ struct CGRecordLowering {
   /// fields of the same formal type.  We want to emit a layout with
   /// these discrete storage units instead of combining them into a
   /// continuous run.
-  bool isDiscreteBitFieldABI() {
+  bool isDiscreteBitFieldABI() const {
 return Context.getTargetInfo().getCXXABI().isMicrosoft() ||
D->isMsStruct(Context);
   }
@@ -121,22 +121,22 @@ struct CGRecordLowering {
   /// other bases, which complicates layout in specific ways.
   ///
   /// Note specifically that the ms_struct attribute doesn't change this.
-  bool isOverlappingVBaseABI() {
+  bool isOverlappingVBaseABI() const {
 return !Context.getTargetInfo().getCXXABI().isMicrosoft();
   }
 
   /// Wraps llvm::Type::getIntNTy with some implicit arguments.
-  llvm::Type *getIntNType(uint64_t NumBits) {
+  llvm::Type *getIntNType(uint64_t NumBits) const {
 unsigned AlignedBits = llvm::alignTo(NumBits, Context.getCharWidth());
 return llvm::Type::getIntNTy(Types.getLLVMContext(), AlignedBits);
   }
   /// Get the LLVM type sized as one character unit.
-  llvm::Type *getCharType() {
+  llvm::Type *getCharType() const {
 return llvm::Type::getIntNTy(Types.getLLVMContext(),
  Context.getCharWidth());
   }
   /// Gets an llvm type of size NumChars and alignment 1.
-  llvm::Type *getByteArrayType(CharUnits NumChars) {
+  llvm::Type *getByteArrayType(CharUnits NumChars) const {
 assert(!NumChars.isZero() && "Empty byte arrays aren't allowed.");
 llvm::Type *Type = getCharType();
 return NumChars == CharUnits::One() ? Type :
@@ -144,7 +144,7 @@ struct CGRecordLowering {
   }
   /// Gets the storage type for a field decl and handles storage
   /// for itanium bitfields that are smaller than their declared type.
-  llvm::Type *getStorageType(const FieldDecl *FD) {
+  llvm::Type *getStorageType(const FieldDecl *FD) const {
 llvm::Type *Type = Types.ConvertTypeForMem(FD->getType());
 if (!FD->isBitField()) return Type;
 if (isDiscreteBitFieldABI()) return Type;
@@ -152,29 +152,29 @@ struct CGRecordLowering {
  (unsigned)Context.toBits(getSize(Type;
   }
   /// Gets the llvm Basesubobject type from a CXXRecordDecl.
-  llvm::Type *getStorageType(const CXXRecordDecl *RD) {
+  llvm::Type *getStorageType(const CXXRecordDecl *RD) const {
 return Types.getCGRecordLayout(RD).getBaseSubobjectLLVMType();
   }
-  CharUnits bitsToCharUnits(uint64_t BitOffset) {
+  CharUnits bitsToCharUnits(uint64_t BitOffset) const {
 return Context.toCharUnitsFromBits(BitOffset);
   }
-  CharUnits getSize(llvm::Type *Type) {
+  CharUnits getSize(llvm::Type *Type) const {
 return CharUnits::fromQuantity(DataLayout.getTypeAllocSize(Type));
   }
-  CharUnits getAlignment(llvm::Type *Type) {
+  CharUnits getAlignment(llvm::Type *Type) const {
 return CharUnits::fromQuantity(DataLayout.getABITypeAlign(Type));
   }
-  bool isZeroInitializable(const FieldDecl *FD) {
+  bool isZeroInitializable(const FieldDecl *FD) const {
 return Types.isZeroInitializable(FD->getType());
   }
-  bool isZeroInitializable(const RecordDecl *RD) {
+  bool isZeroInitializable(const RecordDecl *RD) const {
 return Types.isZeroInitializable(RD);
   }
   void appendPaddingBytes(CharUnits Size) {
 if (!Size.isZero())
   FieldTypes.push_back(getByteArrayType(Size));
   }
-  uint64_t getFieldBitOffset(const FieldDecl *FD) {
+  uint64_t getFieldBitOffset(const FieldDecl *FD) const {
 return Layout.getFieldOffset(FD->getFieldIndex());
   }
   // Layout routines.

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


[clang] [clang][NFC] constify or staticify some CGRecordLowering fns (PR #82874)

2024-02-26 Thread Nathan Sidwell via cfe-commits

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


[clang] [clang] Better bitfield access units (PR #65742)

2024-02-26 Thread Nathan Sidwell via cfe-commits


@@ -132,6 +132,7 @@ class LLVM_LIBRARY_VISIBILITY LoongArch64TargetInfo
   : LoongArchTargetInfo(Triple, Opts) {
 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
 IntMaxType = Int64Type = SignedLong;
+HasCheapUnalignedBitfieldAccess = true;

urnathan wrote:

fixed

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


[clang] [clang] Better bitfield access units (PR #65742)

2024-02-26 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

> Yeah, LLVM supports changing subtarget options on a per-function basis. We 
> would presumably make the query based on the global setting.
> 
> Anyway, getting this information from LLVM doesn't seem tractable in the 
> short-to-medium term; it's just unfortunate.

Thinking further, several (AArch64, ARM & Loongson) targets have a 
'HasUnaligned' bool in their TargetInfo objects.  Perhaps the way forwards is 
to promote that to the base TargetInfo and just use that, rather than the 
bitfield-specific field I added (which just duplicates that functionality on 
those targets)?


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


[clang] [clang] Better bitfield access units (PR #65742)

2024-02-28 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

> > 
> 
> Thinking further, several (AArch64, ARM & Loongson) targets have a 
> 'HasUnaligned' bool in their TargetInfo objects. Perhaps the way forwards is 
> to promote that to the base TargetInfo and just use that, rather than the 
> bitfield-specific field I added (which just duplicates that functionality on 
> those targets)?

I've added such a change.  The AArch64 & ARM targets record this information to 
determine whether a `__ARM_FEATURE_UNALIGNED` macro should be defined.  The 
Loongson target just needs to check the `-ual` target feature.


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


[clang] [clang] Better bitfield access units (PR #65742)

2024-02-02 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

@rjmccall thanks for your comments.  Here's a reimplementation using a single 
loop -- the downside is that we may end up repeating the initial grouping scan, 
if we search more than 1 Access Unit ahead and fail to find a 'good' access 
unit.  This update changes the algorithm slightly, as I realized that `struct A 
{ short a: 16; char b:8; int c;};` and `struct B { char b: 8; short a:16; int 
c;};` should have the same (32-bit) access unit.  Originally only `A` got that.

1) I noticed that several `CGRecordLowering` member fns could either be `const` 
or `static` -- would you like that as a separate NFC PR?
2) I have corrected the error about merging across zero-sized members.
3) It may not be obvious from GH, but this PR breaks down to 3 (or 4) separate 
commits:
   a) A set of test cases, marked up for the current scheme
   b) A new Target hook indicating whether unaligned accesses are cheap
   c) [optional] the CGRecordLowering change just mentioned
   d) the algorithm change, which updates those tests and makes it easier to 
see how the behaviour changes.
   Do you want that commit structure maintained?

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


[clang] [clang] Better bitfield access units (PR #65742)

2024-01-19 Thread Nathan Sidwell via cfe-commits


@@ -376,33 +377,41 @@ void CGRecordLowering::lowerUnion(bool isNoUniqueAddress) 
{
 }
 
 void CGRecordLowering::accumulateFields() {
-  for (RecordDecl::field_iterator Field = D->field_begin(),
-  FieldEnd = D->field_end();
-Field != FieldEnd;) {
+  RecordDecl::field_iterator FieldEnd = D->field_end();
+  RecordDecl::field_iterator BitField = FieldEnd;
+  for (RecordDecl::field_iterator Field = D->field_begin(); Field != FieldEnd;
+   ++Field) {
 if (Field->isBitField()) {
-  RecordDecl::field_iterator Start = Field;
-  // Iterate to gather the list of bitfields.
-  for (++Field; Field != FieldEnd && Field->isBitField(); ++Field);
-  accumulateBitFields(Start, Field);
+  if (BitField == FieldEnd)
+// Start gathering bitfields
+BitField = Field;
 } else if (!Field->isZeroSize(Context)) {
   // Use base subobject layout for the potentially-overlapping field,
   // as it is done in RecordLayoutBuilder
+  CharUnits Offset = bitsToCharUnits(getFieldBitOffset(*Field));

urnathan wrote:

ah, thanks -- I should have checked harder.  Simple enough to undo that bit.

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


[clang] [clang] Robustify open mp test (PR #69739)

2023-10-20 Thread Nathan Sidwell via cfe-commits

https://github.com/urnathan created 
https://github.com/llvm/llvm-project/pull/69739

If the source path contains 'alias' this would spuriously fail.  Be more 
specific about not wanting [no]alias annotations.

>From bb391aa466577f4187af6b284ee5107090778a03 Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Fri, 20 Oct 2023 11:43:08 -0400
Subject: [PATCH] [clang] Robustify open mp test

If the source path contains 'alias' this would spuriously fail.  Be
more specific about not wanting [no]alias annotations.
---
 clang/test/OpenMP/declare_variant_device_kind_codegen.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/OpenMP/declare_variant_device_kind_codegen.cpp 
b/clang/test/OpenMP/declare_variant_device_kind_codegen.cpp
index daa14f1e3a93129..aec71bd5b5da20e 100644
--- a/clang/test/OpenMP/declare_variant_device_kind_codegen.cpp
+++ b/clang/test/OpenMP/declare_variant_device_kind_codegen.cpp
@@ -80,7 +80,7 @@
 
 // expected-no-diagnostics
 
-// CHECK-NOT: alias
+// CHECK-NOT: {{ (no)?alias }}
 
 // CHECK-NOT: ret i32 {{1|4|81|84}}
 // CHECK-DAG: declare {{.*}}i32 @_Z5bazzzv()

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


[clang] [clang] Robustify openmp test (PR #69739)

2023-10-20 Thread Nathan Sidwell via cfe-commits

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


  1   2   >