[clang] [analyzer] New optin.taint.TaintedAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-06-05 Thread Balazs Benics via cfe-commits


@@ -938,6 +938,53 @@ optin.portability.UnixAPI
 "
 Finds implementation-defined behavior in UNIX/Posix functions.
 
+.. _optin-taint-TaintedAlloc:
+
+optin.taint.TaintedAlloc (C, C++)
+"""

steakhal wrote:

```suggestion
"
```

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


[clang] [analyzer] Factor out NoOwnershipChangeVisitor (PR #94357)

2024-06-05 Thread Balazs Benics via cfe-commits

steakhal wrote:

Is this NFC?

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


[clang] [flang] [llvm] [mlir] [Flang]Fix for changed code at the end of AllocaIP. (PR #92430)

2024-06-05 Thread Mats Petersson via cfe-commits


@@ -0,0 +1,23 @@
+!! The main point of this test is to check that the code compiles at all, so 
the

Leporacanthicus wrote:

I have created an internal ticket to improve the code generation. It's just a 
much bigger task than this one started out as. I then found more problems, so 
this took much longer than I expected.

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


[clang] [llvm] [AArch64] Fix feature flags dependecies (PR #90612)

2024-06-05 Thread Paul Walker via cfe-commits

paulwalker-arm wrote:

@momchil-velikov's commentary applies globally and is not specific to FPMR. 
Which is to say, Arm switched a while back from "all system register need to be 
protected by their feature flag" to "only protect system registers where there 
is a need".  The rational is that we see it as being unnecessarily burdensome 
to asm writers to force them to use a feature flag in order to use the pretty 
printed version of an instruction they can already emit (this is especially 
true when dynamic feature detection is used, rather than wanting to explicitly 
say the feature must be present) .  We've no direct plans to revisit all 
previously implemented system registers unless there's a specific need.

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


[clang] 1ea5688 - [clang][Interp][NFC] Mark failed globals as uninitialized

2024-06-05 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-06-05T13:10:18+02:00
New Revision: 1ea568895aa106a61e84607edfd52c3ebf4b59bc

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

LOG: [clang][Interp][NFC] Mark failed globals as uninitialized

This happens automatically if anything _before_ the Ret op fails,
but in this case we have to un-initialize it again.

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 3eb7e7544df71..3671c41ae7039 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -3080,12 +3080,22 @@ bool ByteCodeExprGen::visitDecl(const VarDecl 
*VD) {
 }
   }
 
-  // Return the value
-  if (VarT)
-return this->emitRet(*VarT, VD);
-
-  // Return non-primitive values as pointers here.
-  return this->emitRet(PT_Ptr, VD);
+  // Return the value.
+  if (!this->emitRet(VarT.value_or(PT_Ptr), VD)) {
+// If the Ret above failed and this is a global variable, mark it as
+// uninitialized, even everything else succeeded.
+if (Context::shouldBeGloballyIndexed(VD)) {
+  auto GlobalIndex = P.getGlobal(VD);
+  assert(GlobalIndex);
+  Block *GlobalBlock = P.getGlobal(*GlobalIndex);
+  InlineDescriptor &ID =
+  *reinterpret_cast(GlobalBlock->rawData());
+  ID.IsInitialized = false;
+  GlobalBlock->invokeDtor();
+}
+return false;
+  }
+  return true;
 }
 
 template 



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


[clang] [llvm] [mlir] [OMPIRBuilder] - Handle dependencies in `createTarget` (PR #93977)

2024-06-05 Thread Sergio Afonso via cfe-commits

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


[clang] [llvm] [mlir] [OMPIRBuilder] - Handle dependencies in `createTarget` (PR #93977)

2024-06-05 Thread Sergio Afonso via cfe-commits

https://github.com/skatrak commented:

Thank you Pranav, I think this looks good. I just have a few minor comments.

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


[clang] [llvm] [mlir] [OMPIRBuilder] - Handle dependencies in `createTarget` (PR #93977)

2024-06-05 Thread Sergio Afonso via cfe-commits


@@ -5252,6 +5660,8 @@ static void emitTargetCall(OpenMPIRBuilder &OMPBuilder, 
IRBuilderBase &Builder,
   //  emitKernelLaunch
   auto &&EmitTargetCallFallbackCB =
   [&](OpenMPIRBuilder::InsertPointTy IP) -> OpenMPIRBuilder::InsertPointTy 
{
+LLVM_DEBUG(dbgs() << "EmitTargetCallFallbackCB::Builder = " << &Builder
+  << "\n");

skatrak wrote:

Nit: Is this addition intentional?

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


[clang] [llvm] [mlir] [OMPIRBuilder] - Handle dependencies in `createTarget` (PR #93977)

2024-06-05 Thread Sergio Afonso via cfe-commits


@@ -5572,6 +5999,8 @@ void OpenMPIRBuilder::emitOffloadingArrays(
 return;
 
   Builder.restoreIP(AllocaIP);
+  LLVM_DEBUG(dbgs() << "Basicblock before emitOffloadingArrays\n"
+<< *(Builder.GetInsertBlock()) << "\n");

skatrak wrote:

Nit: Is this addition intentional?

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


[clang] [llvm] [mlir] [OMPIRBuilder] - Handle dependencies in `createTarget` (PR #93977)

2024-06-05 Thread Sergio Afonso via cfe-commits


@@ -5212,6 +5273,78 @@ static Function *createOutlinedFunction(
   return Func;
 }
 
+// Create an entry point for a target task with the following.
+// It'll have the following signature
+// void @.omp_target_task_proxy_func(i32 %thread.id, ptr %task)
+// This function is called from emitTargetTask once the
+// code to launch the target kernel has been outlined already.
+static Function *emitProxyTaskFunction(OpenMPIRBuilder &OMPBuilder,

skatrak wrote:

I agree with the comment by @ergawy, though I'd rather suggest 
`emitTargetTaskProxyFunction`, since that's what the emitted function is named. 
Feel free to ignore if you disagree.

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


[clang] [llvm] [mlir] [OMPIRBuilder] - Handle dependencies in `createTarget` (PR #93977)

2024-06-05 Thread Sergio Afonso via cfe-commits


@@ -0,0 +1,37 @@
+! Offloading test checking the use of the depend clause on
+! the target construct
+! REQUIRES: flang, amdgcn-amd-amdhsa
+! UNSUPPORTED: nvptx64-nvidia-cuda
+! UNSUPPORTED: nvptx64-nvidia-cuda-LTO
+! UNSUPPORTED: aarch64-unknown-linux-gnu
+! UNSUPPORTED: aarch64-unknown-linux-gnu-LTO
+! UNSUPPORTED: x86_64-pc-linux-gnu
+! UNSUPPORTED: x86_64-pc-linux-gnu-LTO
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+program main
+  integer :: a = 0
+  call foo(5, a)
+  print*, "=== FORTRAN Test passed! ==="
+  print*, "foo(5) returned ", a, ", expected 6\n"
+  !   stop 0
+end program main
+subroutine foo(N, r)
+  integer, intent(in) :: N
+  integer, intent(out) :: r
+  integer :: z
+
+  z = 1
+  !$omp task depend(out: z) shared(z)
+  z = N

skatrak wrote:

Would it make sense to perhaps add a relatively long-running loop before 
setting the value of `z` here? Just to make sure that the target task below has 
had to wait for the first to finish (rather than being able to assume it did 
because it possibly runs so fast that it always finishes before the next task 
starts running).

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


[clang] [llvm] [mlir] [OMPIRBuilder] - Handle dependencies in `createTarget` (PR #93977)

2024-06-05 Thread Sergio Afonso via cfe-commits


@@ -5272,36 +5682,53 @@ static void emitTargetCall(OpenMPIRBuilder &OMPBuilder, 
IRBuilderBase &Builder,
   Value *DynCGGroupMem = Builder.getInt32(0);
 
   bool HasNoWait = false;
+  bool HasDependencies = Dependencies.size() > 0;
+  bool RequiresOuterTargetTask = HasNoWait || HasDependencies;
 
   OpenMPIRBuilder::TargetKernelArgs KArgs(NumTargetItems, RTArgs, 
NumIterations,
   NumTeamsVal, NumThreadsVal,
   DynCGGroupMem, HasNoWait);
 
-  Builder.restoreIP(OMPBuilder.emitKernelLaunch(
-  Builder, OutlinedFn, OutlinedFnID, EmitTargetCallFallbackCB, KArgs,
-  DeviceID, RTLoc, AllocaIP));
+  // The presence of certain clauses on the target directive require the
+  // explicit generation of the target task.
+  if (RequiresOuterTargetTask) {
+OMPBuilder.emitTargetTask(OutlinedFn, OutlinedFnID,

skatrak wrote:

Is a call to `Builder.restoreIP()` missing?

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


[clang] [llvm] [mlir] [OMPIRBuilder] - Handle dependencies in `createTarget` (PR #93977)

2024-06-05 Thread Sergio Afonso via cfe-commits


@@ -792,6 +792,9 @@ void OpenMPIRBuilder::finalize(Function *Fn) {
 
   if (!OffloadInfoManager.empty())
 createOffloadEntriesAndInfoMetadata(ErrorReportFn);
+
+  LLVM_DEBUG(dbgs() << "Module after OMPIRBuilder::finalize\n");
+  LLVM_DEBUG(dbgs() << M << "\n");

skatrak wrote:

Nit: Is this addition intentional?

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


[clang] [llvm] [mlir] [OMPIRBuilder] - Handle dependencies in `createTarget` (PR #93977)

2024-06-05 Thread Sergio Afonso via cfe-commits


@@ -1698,6 +1701,64 @@ void OpenMPIRBuilder::createTaskyield(const 
LocationDescription &Loc) {
   emitTaskyieldImpl(Loc);
 }
 
+// Processes the dependencies in Dependencies and does the following
+// - Allocates space on the stack of an array of DependInfo objects
+// - Populates each DependInfo object with relevant information of
+//   the corresponding dependence.
+// - All code is inserted in the entry block of the current function.
+static Value *
+emitDepArray(OpenMPIRBuilder &OMPBuilder,

skatrak wrote:

```suggestion
emitTargetTaskDependenciesArray(OpenMPIRBuilder &OMPBuilder,
```
Nit: I think it's best to try avoiding arbitrary abbreviations in function 
names for readability. Perhaps the name I'm suggesting can be shortened if it's 
also intended for general tasks (`emitTaskDependenciesArray`), but it looks 
like it's only used for target tasks at the moment.

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


[clang] [llvm] [mlir] [OMPIRBuilder] - Handle dependencies in `createTarget` (PR #93977)

2024-06-05 Thread Sergio Afonso via cfe-commits


@@ -705,28 +728,9 @@ convertOmpTaskOp(omp::TaskOp taskOp, llvm::IRBuilderBase 
&builder,
   };
 
   SmallVector dds;
-  if (!taskOp.getDependVars().empty() && taskOp.getDepends()) {
-for (auto dep :
- llvm::zip(taskOp.getDependVars(), taskOp.getDepends()->getValue())) {
-  llvm::omp::RTLDependenceKindTy type;
-  switch (
-  cast(std::get<1>(dep)).getValue()) {
-  case mlir::omp::ClauseTaskDepend::taskdependin:
-type = llvm::omp::RTLDependenceKindTy::DepIn;
-break;
-  // The OpenMP runtime requires that the codegen for 'depend' clause for
-  // 'out' dependency kind must be the same as codegen for 'depend' clause
-  // with 'inout' dependency.
-  case mlir::omp::ClauseTaskDepend::taskdependout:
-  case mlir::omp::ClauseTaskDepend::taskdependinout:
-type = llvm::omp::RTLDependenceKindTy::DepInOut;
-break;
-  };
-  llvm::Value *depVal = moduleTranslation.lookupValue(std::get<0>(dep));
-  llvm::OpenMPIRBuilder::DependData dd(type, depVal->getType(), depVal);
-  dds.emplace_back(dd);
-}
-  }
+  if (!taskOp.getDependVars().empty() && taskOp.getDepends())

skatrak wrote:

Nit: I'd suggest moving this check into `buildDependData`, since it always 
needs to be done. It would just return without adding anything to `dds` if the 
condition is not met.

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


[clang] [llvm] [AArch64] Decouple feature dependency expansion. (PR #94279)

2024-06-05 Thread Alexandros Lamprineas via cfe-commits

https://github.com/labrinea updated 
https://github.com/llvm/llvm-project/pull/94279

>From a413428bb0fdcd45b4a251e385b6cc00ff6a0a2c Mon Sep 17 00:00:00 2001
From: Alexandros Lamprineas 
Date: Mon, 3 Jun 2024 19:57:49 +0100
Subject: [PATCH 1/2] [AArch64] Decouple feature dependency expansion.

The dependency expansion step which was introduced by FMV has been
erroneously used for non-FMV features, for example when parsing the
target attribute. The PR #93695 has rectified most of the tests which
were relying on dependency expansion of target features specified on
the -cc1 command line. In this patch I am decoupling the dependency
expansion of features specified on the target attribute from FMV.

To do that first I am expanding FMV dependencies before passing the
list of target features to initFeatureMap(). Similarly when parsing
the target attribute I am reconstructing an ExtensionSet from the
list of target features which was created during the command line
option parsing. The attribute parsing may toggle bits of that
ExtensionSet and at the end it is converted to a list of target
features. Those are passed to initFeatureMap(), which no longer
requires an override.

A side effect of this refactoring is that features specified on the
target_version attribute now supersede the command line options,
which is what should be happening in the first place.
---
 clang/include/clang/AST/ASTContext.h  |   3 -
 clang/lib/AST/ASTContext.cpp  |  53 -
 clang/lib/Basic/Targets/AArch64.cpp   |  99 +
 clang/lib/Basic/Targets/AArch64.h |   4 -
 .../CodeGen/aarch64-cpu-supports-target.c |   2 +-
 .../aarch64-sme-attrs.cpp |   2 +-
 clang/test/CodeGen/aarch64-targetattr.c   |  41 ---
 clang/test/CodeGen/attr-target-version.c  |  46 
 clang/test/Sema/aarch64-neon-target.c |   4 +-
 clang/test/Sema/builtin-cpu-supports.c|   2 +-
 .../llvm/TargetParser/AArch64TargetParser.h   | 104 +++---
 llvm/lib/Target/AArch64/AArch64Features.td|   2 +-
 llvm/lib/TargetParser/AArch64TargetParser.cpp |  53 ++---
 13 files changed, 201 insertions(+), 214 deletions(-)

diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index a1d1d1c51cd41..8bce4812f0d48 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -3203,9 +3203,6 @@ class ASTContext : public RefCountedBase {
   /// valid feature names.
   ParsedTargetAttr filterFunctionTargetAttrs(const TargetAttr *TD) const;
 
-  std::vector
-  filterFunctionTargetVersionAttrs(const TargetVersionAttr *TV) const;
-
   void getFunctionFeatureMap(llvm::StringMap &FeatureMap,
  const FunctionDecl *) const;
   void getFunctionFeatureMap(llvm::StringMap &FeatureMap,
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 73d3b152c49f1..6b7cfbe48796a 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -87,6 +87,7 @@
 #include "llvm/Support/MD5.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/TargetParser/AArch64TargetParser.h"
 #include "llvm/TargetParser/Triple.h"
 #include 
 #include 
@@ -13663,17 +13664,18 @@ QualType 
ASTContext::getCorrespondingSignedFixedPointType(QualType Ty) const {
   }
 }
 
-std::vector ASTContext::filterFunctionTargetVersionAttrs(
-const TargetVersionAttr *TV) const {
-  assert(TV != nullptr);
-  llvm::SmallVector Feats;
-  std::vector ResFeats;
-  TV->getFeatures(Feats);
-  for (auto &Feature : Feats)
-if (Target->validateCpuSupports(Feature.str()))
-  // Use '?' to mark features that came from TargetVersion.
-  ResFeats.push_back("?" + Feature.str());
-  return ResFeats;
+// Given a list of FMV features, add each of their backend features to the 
list.
+static void
+getFMVBackendFeaturesFor(const llvm::SmallVectorImpl 
&FMVFeatStrings,
+ std::vector &BackendFeats) {
+  for (StringRef F : FMVFeatStrings) {
+if (auto FMVExt = llvm::AArch64::parseArchExtension(F)) {
+  SmallVector Feats;
+  FMVExt->DependentFeatures.split(Feats, ',', -1, false);
+  for (StringRef F : Feats)
+BackendFeats.push_back(F.str());
+}
+  }
 }
 
 ParsedTargetAttr
@@ -13708,10 +13710,12 @@ void 
ASTContext::getFunctionFeatureMap(llvm::StringMap &FeatureMap,
 
 // Make a copy of the features as passed on the command line into the
 // beginning of the additional features from the function to override.
-ParsedAttr.Features.insert(
-ParsedAttr.Features.begin(),
-Target->getTargetOpts().FeaturesAsWritten.begin(),
-Target->getTargetOpts().FeaturesAsWritten.end());
+// AArch64 handles command line option features in parseTargetAttr().
+if (!Target->getTriple().isAArch64())
+  ParsedAttr.Features.insert(
+  ParsedAttr.Features.begin(),
+ 

[clang] [llvm] [AArch64] set AppleA14 architecture version to v8.4-a (PR #92600)

2024-06-05 Thread Tomas Matheson via cfe-commits


@@ -718,12 +718,16 @@ def ProcessorFeatures {
   list AppleA13 = [HasV8_4aOps, FeatureCrypto, 
FeatureFPARMv8,
  FeatureNEON, FeaturePerfMon, 
FeatureFullFP16,
  FeatureFP16FML, FeatureSHA3];
+  // Apple A14 and M1 chips are based on Armv8.5-a but without BTI. Since there

tmatheson-arm wrote:

As you point out, the only publicly available documentation is the optimization 
guide, and lists these cores as "8.5 without BTI". Here in the tablegen file it 
is written as 8.4 plus all of the features from 8.5 which are supported. A 
comment explaining the discrepancy seems reasonable to me. It also alerts 
people that if any new backend feature is introduced that models something in 
8.5, they need to manually add it to the list for these cores.

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


[clang] [llvm] [AArch64] set AppleA14 architecture version to v8.4-a (PR #92600)

2024-06-05 Thread Tomas Matheson via cfe-commits


@@ -286,7 +286,6 @@ void AArch64TargetInfo::getTargetDefinesARMV84A(const 
LangOptions &Opts,
 void AArch64TargetInfo::getTargetDefinesARMV85A(const LangOptions &Opts,
 MacroBuilder &Builder) const {
   Builder.defineMacro("__ARM_FEATURE_FRINT", "1");
-  Builder.defineMacro("__ARM_FEATURE_BTI", "1");

tmatheson-arm wrote:

Maybe in a separate PR.

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


[clang] [analyzer] New optin.taint.TaintedAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-06-05 Thread Daniel Krupp via cfe-commits

https://github.com/dkrupp updated 
https://github.com/llvm/llvm-project/pull/92420

>From f6fdd544a90b865e5e0e530930db87cad405216e Mon Sep 17 00:00:00 2001
From: Daniel Krupp 
Date: Tue, 30 Apr 2024 15:20:52 +0200
Subject: [PATCH 1/8] [analyzer] Adding taint analysis capability to
 unix.Malloc checker

unix.Malloc checker will warn if a memory allocation function
(malloc, calloc, realloc, alloca) is called with a tainted
(attacker controlled) size parameter.
A large, maliciously set size value can trigger memory exhaustion.
To get this warning, the alpha.security.taint.TaintPropagation checker
also needs to be switched on.

The warning will only be emitted, if the analyzer cannot prove
that the size is below reasonable bounds (https://wiki.sei.cmu.edu/confluence/display/c/INT04-C.+Enforce+limits+on+integer+values+originating+from+tainted+sources>`_.
+
+You can silence this warning either by bound checking the ``size`` parameter, 
or
+by explicitly marking the ``size`` parameter as sanitized. See the
+:ref:`alpha-security-taint-TaintPropagation` checker for more details.
+
+.. code-block:: c
+
+  void t1(void) {
+size_t size;
+scanf("%zu", &size);
+int *p = malloc(size); // warn: malloc is called with a tainted 
(potentially attacker controlled) value
+free(p);
+  }
+
+  void t3(void) {
+size_t size;
+scanf("%zu", &size);
+if (1024 BT_MismatchedDealloc;
   mutable std::unique_ptr BT_OffsetFree[CK_NumCheckKinds];
   mutable std::unique_ptr BT_UseZerroAllocated[CK_NumCheckKinds];
+  mutable std::unique_ptr BT_TaintedAlloc[CK_NumCheckKinds];
 
 #define CHECK_FN(NAME) 
\
   void NAME(const CallEvent &Call, CheckerContext &C) const;
@@ -462,6 +464,13 @@ class MallocChecker
   };
 
   bool isMemCall(const CallEvent &Call) const;
+  void reportTaintBug(StringRef Msg, ProgramStateRef State, CheckerContext &C,
+  llvm::ArrayRef TaintedSyms,
+  AllocationFamily Family, const Expr *SizeEx) const;
+
+  void CheckTaintedness(CheckerContext &C, const CallEvent &Call,
+const SVal SizeSVal, ProgramStateRef State,
+AllocationFamily Family) const;
 
   // TODO: Remove mutable by moving the initializtaion to the registry 
function.
   mutable std::optional KernelZeroFlagVal;
@@ -521,9 +530,9 @@ class MallocChecker
   /// malloc leaves it undefined.
   /// \param [in] State The \c ProgramState right before allocation.
   /// \returns The ProgramState right after allocation.
-  [[nodiscard]] static ProgramStateRef
+  [[nodiscard]] ProgramStateRef
   MallocMemAux(CheckerContext &C, const CallEvent &Call, const Expr *SizeEx,
-   SVal Init, ProgramStateRef State, AllocationFamily Family);
+   SVal Init, ProgramStateRef State, AllocationFamily Family) 
const;
 
   /// Models memory allocation.
   ///
@@ -534,9 +543,10 @@ class MallocChecker
   /// malloc leaves it undefined.
   /// \param [in] State The \c ProgramState right before allocation.
   /// \returns The ProgramState right after allocation.
-  [[nodiscard]] static ProgramStateRef
-  MallocMemAux(CheckerContext &C, const CallEvent &Call, SVal Size, SVal Init,
-   ProgramStateRef State, AllocationFamily Family);
+  [[nodiscard]] ProgramStateRef MallocMemAux(CheckerContext &C,
+ const CallEvent &Call, SVal Size,
+ SVal Init, ProgramStateRef State,
+ AllocationFamily Family) const;
 
   // Check if this malloc() for special flags. At present that means M_ZERO or
   // __GFP_ZERO (in which case, treat it like calloc).
@@ -649,8 +659,9 @@ class MallocChecker
   /// \param [in] Call The expression that reallocated memory
   /// \param [in] State The \c ProgramState right before reallocation.
   /// \returns The ProgramState right after allocation.
-  [[nodiscard]] static ProgramStateRef
-  CallocMem(CheckerContext &C, const CallEvent &Call, ProgramStateRef State);
+  [[nodiscard]] ProgramStateRef CallocMem(CheckerContext &C,
+  const CallEvent &Call,
+  ProgramStateRef State) const;
 
   /// See if deallocation happens in a suspicious context. If so, escape the
   /// pointers that otherwise would have been deallocated and return true.
@@ -1779,7 +1790,7 @@ ProgramStateRef 
MallocChecker::MallocMemAux(CheckerContext &C,
 const CallEvent &Call,
 const Expr *SizeEx, SVal Init,
 ProgramStateRef State,
-AllocationFamily Family) {
+AllocationFamily Family) const {
   if (!State)
 return nullptr;
 
@@ -1787,10 +1798,71 @@ ProgramStateRef 
MallocChecker:

[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

2024-06-05 Thread Haojian Wu via cfe-commits

https://github.com/hokein updated 
https://github.com/llvm/llvm-project/pull/86512

>From 0eec9639530a137da6c4c4b2cc4249a3f9dd9939 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Mon, 25 Mar 2024 15:10:51 +0100
Subject: [PATCH] [clang] Implement a bitwise_copyable builtin type trait.

This patch implements a `__is_bitwise_copyable` builtin in clang.

The bitwise copyable types act as the trivially copyable types, but
they support a wider range of types (e.g. classes with virtual methods) --
their underlying types can be safely copied by `memcopy` or `memmove`,
the clang compiler guarantees that both source and destination objects
have the same *object* representations after the copy operation, and the
lifetime of the destination object implicitly starts.

A particular use case of this builtin is to clone an object via memcopy
(without running the constructor):

```
Message* clone(const Message* src, char* buffer, int size) {
  if constexpr __is_bitwise_copyable(Message) {
// bitwise copy to buffer
__builtin_memcpy(buffer, src, size);
// using __builtin_launder to prevent miscompile for 
-fstrict-vtable-pointers.
return __builtin_launder(reinterpret_cast(buffer));
  }
  // Fallback the operator new, which calls the constructor to start the 
lifetime.
  return new(buffer) Message(src);
}
```

Note that the definition of bitwise copyable is not tied to the Rule Of
Five, so users of this builtin must guarantee that program semantic constraints
are satisfied, e.g. no double resource deallocations.

Context: https://discourse.llvm.org/t/extension-for-creating-objects-via-memcpy
---
 clang/docs/LanguageExtensions.rst | 24 
 clang/docs/ReleaseNotes.rst   |  3 ++
 clang/include/clang/AST/Type.h| 14 +++
 clang/include/clang/Basic/TokenKinds.def  |  2 +
 clang/lib/AST/Type.cpp| 37 +++
 clang/lib/Sema/SemaExprCXX.cpp|  3 ++
 ...builtin-is-bitwise-cloneable-fsanitize.cpp | 34 +
 .../SemaCXX/builtin-is-bitwise-cloneable.cpp  |  8 
 clang/test/SemaObjCXX/arc-type-traits.mm  |  9 +
 9 files changed, 134 insertions(+)
 create mode 100644 
clang/test/SemaCXX/builtin-is-bitwise-cloneable-fsanitize.cpp
 create mode 100644 clang/test/SemaCXX/builtin-is-bitwise-cloneable.cpp

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index 46f99d0bbdd06..a49e4122ffc10 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -4016,6 +4016,30 @@ Note that the `size` argument must be a compile time 
constant.
 
 Note that this intrinsic cannot yet be called in a ``constexpr`` context.
 
+``__is_bitwise_cloneable``
+--
+
+A type trait is used to check whether a type can be safely copied by memcpy.
+
+**Syntax**:
+
+.. code-block:: c++
+
+  bool __is_bitwise_cloneable(Type)
+
+**Description**:
+
+Objects of bitwise cloneable types can be bitwise copied by memcpy/memmove. The
+Clang compiler warrants that this behavior is well defined, and won't be
+broken by compiler optimizations and sanitizers.
+
+For implicit-lifetime types, the lifetime of the new object is implicitly
+started after the copy. For other types (e.g., classes with virtual methods),
+the lifetime isn't started, and using the object results in undefined behavior
+according to the C++ Standard.
+
+This builtin can be used in constant expressions.
+
 Atomic Min/Max builtins with memory ordering
 
 
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 39a9013c75a41..cc2ff9920b5c1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -337,6 +337,9 @@ Non-comprehensive list of changes in this release
   ``-Winvalid-constexpr`` is not enabled for the function definition, which
   should result in mild compile-time performance improvements.
 
+- Added ``__buitlin_bitwise_clonable`` which is used to check whether a type
+  can be safely copied by memcpy/memmove.
+
 New Compiler Flags
 --
 - ``-fsanitize=implicit-bitfield-conversion`` checks implicit truncation and
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 263b632df23ce..4bb3a18102ebb 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -1120,6 +1120,20 @@ class QualType {
   /// Return true if this is a trivially copyable type (C++0x [basic.types]p9)
   bool isTriviallyCopyableType(const ASTContext &Context) const;
 
+  /// Return true if the type is safe to bitwise copy using memcpy/memmove.
+  ///
+  /// This is an extension in clang: bitwise clonable types act as trivially
+  /// copyable types, meaning their underlying bytes can be safely copied by
+  /// memcpy or memmove. After the copy, the destination object has the same
+  /// object representation.
+  ///
+  /// However, there are cases where it

[clang] 5f2aa91 - [clang][Interp][NFC] Don't try to dump uninitialized global variables

2024-06-05 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-06-05T13:24:22+02:00
New Revision: 5f2aa912766e4d48a5b46afa7ad9e99a41a51ee8

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

LOG: [clang][Interp][NFC] Don't try to dump uninitialized global variables

They don't contain anything useful.

Added: 


Modified: 
clang/lib/AST/Interp/Disasm.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/Disasm.cpp b/clang/lib/AST/Interp/Disasm.cpp
index ccdc96a79436d..e442c6c709f14 100644
--- a/clang/lib/AST/Interp/Disasm.cpp
+++ b/clang/lib/AST/Interp/Disasm.cpp
@@ -150,7 +150,7 @@ LLVM_DUMP_METHOD void Program::dump(llvm::raw_ostream &OS) 
const {
 }
 Desc->dump(OS);
 OS << "\n";
-if (Desc->isPrimitive() && !Desc->isDummy()) {
+if (GP.isInitialized() && Desc->isPrimitive() && !Desc->isDummy()) {
   OS << "   ";
   {
 ColorScope SC(OS, true, {llvm::raw_ostream::BRIGHT_CYAN, false});



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


[clang] 145815c - [clang][Interp][NFC] Move EvaluationResult::dump() to Disasm.cpp

2024-06-05 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-06-05T13:24:22+02:00
New Revision: 145815c180fc82c5a55bf568d01d98d250490a55

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

LOG: [clang][Interp][NFC] Move EvaluationResult::dump() to Disasm.cpp

Where all the other dump() functions live.

Added: 


Modified: 
clang/lib/AST/Interp/Disasm.cpp
clang/lib/AST/Interp/EvaluationResult.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/Disasm.cpp b/clang/lib/AST/Interp/Disasm.cpp
index e442c6c709f14..3f8a92ed2f0bd 100644
--- a/clang/lib/AST/Interp/Disasm.cpp
+++ b/clang/lib/AST/Interp/Disasm.cpp
@@ -11,6 +11,8 @@
 
//===--===//
 
 #include "Boolean.h"
+#include "Context.h"
+#include "EvaluationResult.h"
 #include "Floating.h"
 #include "Function.h"
 #include "FunctionPointer.h"
@@ -305,3 +307,43 @@ LLVM_DUMP_METHOD void Block::dump(llvm::raw_ostream &OS) 
const {
   OS << "  Extern: " << IsExtern << "\n";
   OS << "  Initialized: " << IsInitialized << "\n";
 }
+
+LLVM_DUMP_METHOD void EvaluationResult::dump() const {
+  assert(Ctx);
+  auto &OS = llvm::errs();
+  const ASTContext &ASTCtx = Ctx->getASTContext();
+
+  switch (Kind) {
+  case Empty:
+OS << "Empty\n";
+break;
+  case RValue:
+OS << "RValue: ";
+std::get(Value).dump(OS, ASTCtx);
+break;
+  case LValue: {
+assert(Source);
+QualType SourceType;
+if (const auto *D = Source.dyn_cast()) {
+  if (const auto *VD = dyn_cast(D))
+SourceType = VD->getType();
+} else if (const auto *E = Source.dyn_cast()) {
+  SourceType = E->getType();
+}
+
+OS << "LValue: ";
+if (const auto *P = std::get_if(&Value))
+  P->toAPValue().printPretty(OS, ASTCtx, SourceType);
+else if (const auto *FP = std::get_if(&Value)) // Nope
+  FP->toAPValue().printPretty(OS, ASTCtx, SourceType);
+OS << "\n";
+break;
+  }
+  case Invalid:
+OS << "Invalid\n";
+break;
+  case Valid:
+OS << "Valid\n";
+break;
+  }
+}

diff  --git a/clang/lib/AST/Interp/EvaluationResult.cpp 
b/clang/lib/AST/Interp/EvaluationResult.cpp
index 150a793da881d..c04b0fc0a1121 100644
--- a/clang/lib/AST/Interp/EvaluationResult.cpp
+++ b/clang/lib/AST/Interp/EvaluationResult.cpp
@@ -7,7 +7,6 @@
 
//===--===//
 
 #include "EvaluationResult.h"
-#include "Context.h"
 #include "InterpState.h"
 #include "Record.h"
 #include "clang/AST/ExprCXX.h"
@@ -159,45 +158,5 @@ bool EvaluationResult::checkFullyInitialized(InterpState 
&S,
   return CheckArrayInitialized(S, InitLoc, Ptr, CAT);
 }
 
-void EvaluationResult::dump() const {
-  assert(Ctx);
-  auto &OS = llvm::errs();
-  const ASTContext &ASTCtx = Ctx->getASTContext();
-
-  switch (Kind) {
-  case Empty:
-OS << "Empty\n";
-break;
-  case RValue:
-OS << "RValue: ";
-std::get(Value).dump(OS, ASTCtx);
-break;
-  case LValue: {
-assert(Source);
-QualType SourceType;
-if (const auto *D = Source.dyn_cast()) {
-  if (const auto *VD = dyn_cast(D))
-SourceType = VD->getType();
-} else if (const auto *E = Source.dyn_cast()) {
-  SourceType = E->getType();
-}
-
-OS << "LValue: ";
-if (const auto *P = std::get_if(&Value))
-  P->toAPValue().printPretty(OS, ASTCtx, SourceType);
-else if (const auto *FP = std::get_if(&Value)) // Nope
-  FP->toAPValue().printPretty(OS, ASTCtx, SourceType);
-OS << "\n";
-break;
-  }
-  case Invalid:
-OS << "Invalid\n";
-  break;
-  case Valid:
-OS << "Valid\n";
-  break;
-  }
-}
-
 } // namespace interp
 } // namespace clang



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


[clang] [llvm] [AArch64] set AppleA14 architecture version to v8.4-a (PR #92600)

2024-06-05 Thread Tomas Matheson via cfe-commits

https://github.com/tmatheson-arm updated 
https://github.com/llvm/llvm-project/pull/92600

>From 518b83ab69c4852f7e7ea71c17df3f58e8ff50ef Mon Sep 17 00:00:00 2001
From: Tomas Matheson 
Date: Fri, 17 May 2024 21:39:17 +0100
Subject: [PATCH 1/4] [AArch64] set AppleA14 architecture version to 8.5

---
 llvm/lib/Target/AArch64/AArch64Processors.td | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/AArch64/AArch64Processors.td 
b/llvm/lib/Target/AArch64/AArch64Processors.td
index f2286ae17dba5..96422758bc618 100644
--- a/llvm/lib/Target/AArch64/AArch64Processors.td
+++ b/llvm/lib/Target/AArch64/AArch64Processors.td
@@ -718,7 +718,7 @@ def ProcessorFeatures {
   list AppleA13 = [HasV8_4aOps, FeatureCrypto, 
FeatureFPARMv8,
  FeatureNEON, FeaturePerfMon, 
FeatureFullFP16,
  FeatureFP16FML, FeatureSHA3];
-  list AppleA14 = [HasV8_4aOps, FeatureCrypto, 
FeatureFPARMv8,
+  list AppleA14 = [HasV8_5aOps, FeatureCrypto, 
FeatureFPARMv8,
  FeatureNEON, FeaturePerfMon, 
FeatureFRInt3264,
  FeatureSpecRestrict, FeatureSSBS, 
FeatureSB,
  FeaturePredRes, FeatureCacheDeepPersist,

>From 74f6d426fa67b1f794a8ba2ac7c864830ee9c2b2 Mon Sep 17 00:00:00 2001
From: Tomas Matheson 
Date: Mon, 20 May 2024 12:38:52 +0100
Subject: [PATCH 2/4] make m1+a14 v8.4 instead

---
 clang/lib/Basic/Targets/AArch64.cpp|  4 +++-
 clang/test/Driver/aarch64-mac-cpus.c   |  2 +-
 clang/test/Preprocessor/aarch64-target-features.c  |  8 +++-
 .../llvm/TargetParser/AArch64TargetParser.h|  4 ++--
 llvm/lib/Target/AArch64/AArch64Processors.td   | 14 +-
 llvm/test/DebugInfo/debug_frame_symbol.ll  |  2 +-
 .../AddressSanitizer/calls-only-smallfn.ll |  2 +-
 .../Instrumentation/AddressSanitizer/calls-only.ll |  2 +-
 llvm/unittests/TargetParser/TargetParserTest.cpp   |  8 
 9 files changed, 29 insertions(+), 17 deletions(-)

diff --git a/clang/lib/Basic/Targets/AArch64.cpp 
b/clang/lib/Basic/Targets/AArch64.cpp
index 5db1ce78c657f..692ec58235efe 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -286,7 +286,6 @@ void AArch64TargetInfo::getTargetDefinesARMV84A(const 
LangOptions &Opts,
 void AArch64TargetInfo::getTargetDefinesARMV85A(const LangOptions &Opts,
 MacroBuilder &Builder) const {
   Builder.defineMacro("__ARM_FEATURE_FRINT", "1");
-  Builder.defineMacro("__ARM_FEATURE_BTI", "1");
   // Also include the Armv8.4 defines
   getTargetDefinesARMV84A(Opts, Builder);
 }
@@ -499,6 +498,9 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions 
&Opts,
   if (HasPAuthLR)
 Builder.defineMacro("__ARM_FEATURE_PAUTH_LR", "1");
 
+  if (HasBTI)
+Builder.defineMacro("__ARM_FEATURE_BTI", "1");
+
   if (HasUnalignedAccess)
 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
 
diff --git a/clang/test/Driver/aarch64-mac-cpus.c 
b/clang/test/Driver/aarch64-mac-cpus.c
index 5179731268950..488298cfd2d24 100644
--- a/clang/test/Driver/aarch64-mac-cpus.c
+++ b/clang/test/Driver/aarch64-mac-cpus.c
@@ -16,7 +16,7 @@
 // RUN: %clang --target=arm64-apple-macos -mcpu=apple-m1 -### -c %s 2>&1 | 
FileCheck --check-prefix=EXPLICIT-M1 %s
 
 // CHECK: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "apple-m1"
-// CHECK-SAME: "-target-feature" "+v8.5a"
+// CHECK-SAME: "-target-feature" "+v8.4a"
 
 // EXPLICIT-A11: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "apple-a11"
 // EXPLICIT-A7: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "apple-a7"
diff --git a/clang/test/Preprocessor/aarch64-target-features.c 
b/clang/test/Preprocessor/aarch64-target-features.c
index 82304a15a04a3..3f2c2929c7129 100644
--- a/clang/test/Preprocessor/aarch64-target-features.c
+++ b/clang/test/Preprocessor/aarch64-target-features.c
@@ -335,7 +335,7 @@
 // CHECK-MCPU-CARMEL: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" 
"+v8.2a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" 
"+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+lse" 
"-target-feature" "+ras" "-target-feature" "+rdm" "-target-feature" "+sha2" 
"-target-feature" "+neon"
 
 // RUN: %clang -target x86_64-apple-macosx -arch arm64 -### -c %s 2>&1 | 
FileCheck --check-prefix=CHECK-ARCH-ARM64 %s
-// CHECK-ARCH-ARM64: "-target-cpu" "apple-m1" "-target-feature" "+zcm" 
"-target-feature" "+zcz" "-target-feature" "+v8.5a" "-target-feature" "+aes" 
"-target-feature" "+crc" "-target-feature" "+dotprod" "-target-feature" 
"+complxnum" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" 
"-target-feature" "+fp16fml" "-target-feature" "+jsconv" "-target-feature" 
"+lse" "-target-feature" "+pauth" "-target-feature" "+ras" "-target-feature" 
"+rcpc" "-target-feature" "+rdm" "-target-feature" "+sha2" "-

[clang] [llvm] [AArch64] set AppleA14 architecture version to v8.4-a (PR #92600)

2024-06-05 Thread Tomas Matheson via cfe-commits

https://github.com/tmatheson-arm updated 
https://github.com/llvm/llvm-project/pull/92600

>From 518b83ab69c4852f7e7ea71c17df3f58e8ff50ef Mon Sep 17 00:00:00 2001
From: Tomas Matheson 
Date: Fri, 17 May 2024 21:39:17 +0100
Subject: [PATCH 1/5] [AArch64] set AppleA14 architecture version to 8.5

---
 llvm/lib/Target/AArch64/AArch64Processors.td | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/AArch64/AArch64Processors.td 
b/llvm/lib/Target/AArch64/AArch64Processors.td
index f2286ae17dba5..96422758bc618 100644
--- a/llvm/lib/Target/AArch64/AArch64Processors.td
+++ b/llvm/lib/Target/AArch64/AArch64Processors.td
@@ -718,7 +718,7 @@ def ProcessorFeatures {
   list AppleA13 = [HasV8_4aOps, FeatureCrypto, 
FeatureFPARMv8,
  FeatureNEON, FeaturePerfMon, 
FeatureFullFP16,
  FeatureFP16FML, FeatureSHA3];
-  list AppleA14 = [HasV8_4aOps, FeatureCrypto, 
FeatureFPARMv8,
+  list AppleA14 = [HasV8_5aOps, FeatureCrypto, 
FeatureFPARMv8,
  FeatureNEON, FeaturePerfMon, 
FeatureFRInt3264,
  FeatureSpecRestrict, FeatureSSBS, 
FeatureSB,
  FeaturePredRes, FeatureCacheDeepPersist,

>From 74f6d426fa67b1f794a8ba2ac7c864830ee9c2b2 Mon Sep 17 00:00:00 2001
From: Tomas Matheson 
Date: Mon, 20 May 2024 12:38:52 +0100
Subject: [PATCH 2/5] make m1+a14 v8.4 instead

---
 clang/lib/Basic/Targets/AArch64.cpp|  4 +++-
 clang/test/Driver/aarch64-mac-cpus.c   |  2 +-
 clang/test/Preprocessor/aarch64-target-features.c  |  8 +++-
 .../llvm/TargetParser/AArch64TargetParser.h|  4 ++--
 llvm/lib/Target/AArch64/AArch64Processors.td   | 14 +-
 llvm/test/DebugInfo/debug_frame_symbol.ll  |  2 +-
 .../AddressSanitizer/calls-only-smallfn.ll |  2 +-
 .../Instrumentation/AddressSanitizer/calls-only.ll |  2 +-
 llvm/unittests/TargetParser/TargetParserTest.cpp   |  8 
 9 files changed, 29 insertions(+), 17 deletions(-)

diff --git a/clang/lib/Basic/Targets/AArch64.cpp 
b/clang/lib/Basic/Targets/AArch64.cpp
index 5db1ce78c657f..692ec58235efe 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -286,7 +286,6 @@ void AArch64TargetInfo::getTargetDefinesARMV84A(const 
LangOptions &Opts,
 void AArch64TargetInfo::getTargetDefinesARMV85A(const LangOptions &Opts,
 MacroBuilder &Builder) const {
   Builder.defineMacro("__ARM_FEATURE_FRINT", "1");
-  Builder.defineMacro("__ARM_FEATURE_BTI", "1");
   // Also include the Armv8.4 defines
   getTargetDefinesARMV84A(Opts, Builder);
 }
@@ -499,6 +498,9 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions 
&Opts,
   if (HasPAuthLR)
 Builder.defineMacro("__ARM_FEATURE_PAUTH_LR", "1");
 
+  if (HasBTI)
+Builder.defineMacro("__ARM_FEATURE_BTI", "1");
+
   if (HasUnalignedAccess)
 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
 
diff --git a/clang/test/Driver/aarch64-mac-cpus.c 
b/clang/test/Driver/aarch64-mac-cpus.c
index 5179731268950..488298cfd2d24 100644
--- a/clang/test/Driver/aarch64-mac-cpus.c
+++ b/clang/test/Driver/aarch64-mac-cpus.c
@@ -16,7 +16,7 @@
 // RUN: %clang --target=arm64-apple-macos -mcpu=apple-m1 -### -c %s 2>&1 | 
FileCheck --check-prefix=EXPLICIT-M1 %s
 
 // CHECK: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "apple-m1"
-// CHECK-SAME: "-target-feature" "+v8.5a"
+// CHECK-SAME: "-target-feature" "+v8.4a"
 
 // EXPLICIT-A11: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "apple-a11"
 // EXPLICIT-A7: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "apple-a7"
diff --git a/clang/test/Preprocessor/aarch64-target-features.c 
b/clang/test/Preprocessor/aarch64-target-features.c
index 82304a15a04a3..3f2c2929c7129 100644
--- a/clang/test/Preprocessor/aarch64-target-features.c
+++ b/clang/test/Preprocessor/aarch64-target-features.c
@@ -335,7 +335,7 @@
 // CHECK-MCPU-CARMEL: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" 
"+v8.2a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" 
"+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+lse" 
"-target-feature" "+ras" "-target-feature" "+rdm" "-target-feature" "+sha2" 
"-target-feature" "+neon"
 
 // RUN: %clang -target x86_64-apple-macosx -arch arm64 -### -c %s 2>&1 | 
FileCheck --check-prefix=CHECK-ARCH-ARM64 %s
-// CHECK-ARCH-ARM64: "-target-cpu" "apple-m1" "-target-feature" "+zcm" 
"-target-feature" "+zcz" "-target-feature" "+v8.5a" "-target-feature" "+aes" 
"-target-feature" "+crc" "-target-feature" "+dotprod" "-target-feature" 
"+complxnum" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" 
"-target-feature" "+fp16fml" "-target-feature" "+jsconv" "-target-feature" 
"+lse" "-target-feature" "+pauth" "-target-feature" "+ras" "-target-feature" 
"+rcpc" "-target-feature" "+rdm" "-target-feature" "+sha2" "-

[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

2024-06-05 Thread Haojian Wu via cfe-commits

https://github.com/hokein updated 
https://github.com/llvm/llvm-project/pull/86512

>From 3ce87797dbc36ae792b4d82077cd8f27f1eee53e Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Mon, 25 Mar 2024 15:10:51 +0100
Subject: [PATCH] [clang] Implement a bitwise_copyable builtin type trait.

This patch implements a `__is_bitwise_copyable` builtin in clang.

The bitwise copyable types act as the trivially copyable types, but
they support a wider range of types (e.g. classes with virtual methods) --
their underlying types can be safely copied by `memcopy` or `memmove`,
the clang compiler guarantees that both source and destination objects
have the same *object* representations after the copy operation, and the
lifetime of the destination object implicitly starts.

A particular use case of this builtin is to clone an object via memcopy
(without running the constructor):

```
Message* clone(const Message* src, char* buffer, int size) {
  if constexpr __is_bitwise_copyable(Message) {
// bitwise copy to buffer
__builtin_memcpy(buffer, src, size);
// using __builtin_launder to prevent miscompile for 
-fstrict-vtable-pointers.
return __builtin_launder(reinterpret_cast(buffer));
  }
  // Fallback the operator new, which calls the constructor to start the 
lifetime.
  return new(buffer) Message(src);
}
```

Note that the definition of bitwise copyable is not tied to the Rule Of
Five, so users of this builtin must guarantee that program semantic constraints
are satisfied, e.g. no double resource deallocations.

Context: https://discourse.llvm.org/t/extension-for-creating-objects-via-memcpy
---
 clang/docs/LanguageExtensions.rst | 24 
 clang/docs/ReleaseNotes.rst   |  3 ++
 clang/include/clang/AST/Type.h| 14 +++
 clang/include/clang/Basic/TokenKinds.def  |  2 +
 clang/lib/AST/Type.cpp| 37 +++
 clang/lib/Sema/SemaExprCXX.cpp|  3 ++
 ...builtin-is-bitwise-cloneable-fsanitize.cpp | 34 +
 .../SemaCXX/builtin-is-bitwise-cloneable.cpp  |  8 
 clang/test/SemaObjCXX/arc-type-traits.mm  |  9 +
 9 files changed, 134 insertions(+)
 create mode 100644 
clang/test/SemaCXX/builtin-is-bitwise-cloneable-fsanitize.cpp
 create mode 100644 clang/test/SemaCXX/builtin-is-bitwise-cloneable.cpp

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index 46f99d0bbdd06..a49e4122ffc10 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -4016,6 +4016,30 @@ Note that the `size` argument must be a compile time 
constant.
 
 Note that this intrinsic cannot yet be called in a ``constexpr`` context.
 
+``__is_bitwise_cloneable``
+--
+
+A type trait is used to check whether a type can be safely copied by memcpy.
+
+**Syntax**:
+
+.. code-block:: c++
+
+  bool __is_bitwise_cloneable(Type)
+
+**Description**:
+
+Objects of bitwise cloneable types can be bitwise copied by memcpy/memmove. The
+Clang compiler warrants that this behavior is well defined, and won't be
+broken by compiler optimizations and sanitizers.
+
+For implicit-lifetime types, the lifetime of the new object is implicitly
+started after the copy. For other types (e.g., classes with virtual methods),
+the lifetime isn't started, and using the object results in undefined behavior
+according to the C++ Standard.
+
+This builtin can be used in constant expressions.
+
 Atomic Min/Max builtins with memory ordering
 
 
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 39a9013c75a41..3d54144bf9206 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -337,6 +337,9 @@ Non-comprehensive list of changes in this release
   ``-Winvalid-constexpr`` is not enabled for the function definition, which
   should result in mild compile-time performance improvements.
 
+- Added ``__is_bitwise_cloneable`` which is used to check whether a type
+  can be safely copied by memcpy/memmove.
+
 New Compiler Flags
 --
 - ``-fsanitize=implicit-bitfield-conversion`` checks implicit truncation and
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 263b632df23ce..9eb3f6c09e3d3 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -1120,6 +1120,20 @@ class QualType {
   /// Return true if this is a trivially copyable type (C++0x [basic.types]p9)
   bool isTriviallyCopyableType(const ASTContext &Context) const;
 
+  /// Return true if the type is safe to bitwise copy using memcpy/memmove.
+  ///
+  /// This is an extension in clang: bitwise cloneable types act as trivially
+  /// copyable types, meaning their underlying bytes can be safely copied by
+  /// memcpy or memmove. After the copy, the destination object has the same
+  /// object representation.
+  ///
+  /// However, there are cases where it is

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

2024-06-05 Thread Hassnaa Hamdi via cfe-commits


@@ -118,6 +124,37 @@ llvm::Type *CodeGenTypes::ConvertTypeForMem(QualType T, 
bool ForBitField) {
   return R;
 }
 
+bool CodeGenTypes::LLVMTypeLayoutMatchesAST(QualType ASTTy,
+llvm::Type *LLVMTy) {
+  CharUnits ASTSize = Context.getTypeSizeInChars(ASTTy);
+  CharUnits LLVMSize =
+  CharUnits::fromQuantity(getDataLayout().getTypeAllocSize(LLVMTy));
+  return ASTSize == LLVMSize;
+}
+
+llvm::Type *CodeGenTypes::convertTypeForLoadStore(QualType T,
+  llvm::Type *LLVMTy) {
+  if (!LLVMTy)
+LLVMTy = ConvertType(T);
+
+  if (!T->isBitIntType() && LLVMTy->isIntegerTy(1))
+return llvm::IntegerType::get(getLLVMContext(),
+  (unsigned)Context.getTypeSize(T));
+
+  if (T->isBitIntType()) {
+llvm::Type *R = ConvertType(T);
+if (!LLVMTypeLayoutMatchesAST(T, R))
+  return llvm::Type::getIntNTy(
+  getLLVMContext(), Context.getTypeSizeInChars(T).getQuantity() * 8);

hassnaaHamdi wrote:

`return llvm::Type::getIntNTy(
  getLLVMContext(), Context.getTypeSizeInChars(T).getQuantity() * 8);`
Could you plz explain the logic behind using this implementation ? do you 
support all types > 128 and also types < 128 ? or it's specific to the types > 
128 only ?

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


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

2024-06-05 Thread Mariya Podchishchaeva via cfe-commits


@@ -118,6 +124,37 @@ llvm::Type *CodeGenTypes::ConvertTypeForMem(QualType T, 
bool ForBitField) {
   return R;
 }
 
+bool CodeGenTypes::LLVMTypeLayoutMatchesAST(QualType ASTTy,
+llvm::Type *LLVMTy) {
+  CharUnits ASTSize = Context.getTypeSizeInChars(ASTTy);
+  CharUnits LLVMSize =
+  CharUnits::fromQuantity(getDataLayout().getTypeAllocSize(LLVMTy));
+  return ASTSize == LLVMSize;
+}
+
+llvm::Type *CodeGenTypes::convertTypeForLoadStore(QualType T,
+  llvm::Type *LLVMTy) {
+  if (!LLVMTy)
+LLVMTy = ConvertType(T);
+
+  if (!T->isBitIntType() && LLVMTy->isIntegerTy(1))
+return llvm::IntegerType::get(getLLVMContext(),
+  (unsigned)Context.getTypeSize(T));
+
+  if (T->isBitIntType()) {
+llvm::Type *R = ConvertType(T);
+if (!LLVMTypeLayoutMatchesAST(T, R))
+  return llvm::Type::getIntNTy(
+  getLLVMContext(), Context.getTypeSizeInChars(T).getQuantity() * 8);

Fznamznon wrote:

We intend to support all types. In general, _BitInt(N) is lowered to iN type in 
LLVM IR. However it is not possible for certain sizes and some targets now due 
to different alignment defined for iN and _BitInt(N). This now happens for 
_BitInt(>=129) for x86_64 targets. `LLVMTypeLayoutMatchesAST` checks for this 
mismatch. If there is mismatch, say NBytes = sizeof(_BitInt(N)), we use [i8 x 
NBytes] as in-memory type. It is better to load and store value using iNBytes 
type instead of an array type since it is better for optimization and 
guarantees that all bits of the loaded/stores value is valid. For more info, 
please refer to 
https://github.com/llvm/llvm-project/pull/91364#issuecomment-2099351151 as well.

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


[clang] [analyzer] New optin.taint.TaintedAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-06-05 Thread Balazs Benics via cfe-commits

https://github.com/steakhal approved this pull request.


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


[clang] 3388c5a - [clang][Interp][NFC] Add missing assertion to Block ctor

2024-06-05 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-06-05T13:57:23+02:00
New Revision: 3388c5aadd8583b5a596576c52be886104d557f2

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

LOG: [clang][Interp][NFC] Add missing assertion to Block ctor

We have this assertion in all the other constructors.

Added: 


Modified: 
clang/lib/AST/Interp/InterpBlock.h

Removed: 




diff  --git a/clang/lib/AST/Interp/InterpBlock.h 
b/clang/lib/AST/Interp/InterpBlock.h
index 506034e880d0b..2bb195648a9a9 100644
--- a/clang/lib/AST/Interp/InterpBlock.h
+++ b/clang/lib/AST/Interp/InterpBlock.h
@@ -125,13 +125,15 @@ class Block final {
   void dump() const { dump(llvm::errs()); }
   void dump(llvm::raw_ostream &OS) const;
 
-protected:
+private:
   friend class Pointer;
   friend class DeadBlock;
   friend class InterpState;
 
   Block(const Descriptor *Desc, bool IsExtern, bool IsStatic, bool IsDead)
-  : IsStatic(IsStatic), IsExtern(IsExtern), IsDead(true), Desc(Desc) {}
+  : IsStatic(IsStatic), IsExtern(IsExtern), IsDead(true), Desc(Desc) {
+assert(Desc);
+  }
 
   /// Deletes a dead block at the end of its lifetime.
   void cleanup();



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


[clang] a16d33e - [clang][Interp][NFC] Don't invoke block dtor on uninitialized globals

2024-06-05 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-06-05T13:57:23+02:00
New Revision: a16d33eaebb3fdbc9435c125c206372c8a7374d5

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

LOG: [clang][Interp][NFC] Don't invoke block dtor on uninitialized globals

That can't ever work.

Added: 


Modified: 
clang/lib/AST/Interp/Program.h

Removed: 




diff  --git a/clang/lib/AST/Interp/Program.h b/clang/lib/AST/Interp/Program.h
index 36b5a1faa513a..ec7c0744b8856 100644
--- a/clang/lib/AST/Interp/Program.h
+++ b/clang/lib/AST/Interp/Program.h
@@ -45,7 +45,8 @@ class Program final {
 // but primitive arrays might have an InitMap* heap allocated and
 // that needs to be freed.
 for (Global *G : Globals)
-  G->block()->invokeDtor();
+  if (Block *B = G->block(); B->isInitialized())
+B->invokeDtor();
 
 // Records might actually allocate memory themselves, but they
 // are allocated using a BumpPtrAllocator. Call their desctructors



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


[clang] c70fa55 - [clang][Interp][NFC] Add cleanup() infrastructure to EvalEmitter

2024-06-05 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-06-05T13:57:23+02:00
New Revision: c70fa55bed45fc0cc0063e9f0bf93f163b5a1962

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

LOG: [clang][Interp][NFC] Add cleanup() infrastructure to EvalEmitter

Unused for now.

Added: 


Modified: 
clang/lib/AST/Interp/Context.cpp
clang/lib/AST/Interp/EvalEmitter.cpp
clang/lib/AST/Interp/EvalEmitter.h
clang/lib/AST/Interp/InterpState.cpp
clang/lib/AST/Interp/InterpState.h

Removed: 




diff  --git a/clang/lib/AST/Interp/Context.cpp 
b/clang/lib/AST/Interp/Context.cpp
index 4ecfa0f9bfd75..b0b22b059b77a 100644
--- a/clang/lib/AST/Interp/Context.cpp
+++ b/clang/lib/AST/Interp/Context.cpp
@@ -46,6 +46,7 @@ bool Context::evaluateAsRValue(State &Parent, const Expr *E, 
APValue &Result) {
   auto Res = C.interpretExpr(E, /*ConvertResultToRValue=*/E->isGLValue());
 
   if (Res.isInvalid()) {
+C.cleanup();
 Stk.clear();
 return false;
   }
@@ -70,6 +71,7 @@ bool Context::evaluate(State &Parent, const Expr *E, APValue 
&Result) {
 
   auto Res = C.interpretExpr(E);
   if (Res.isInvalid()) {
+C.cleanup();
 Stk.clear();
 return false;
   }
@@ -97,6 +99,7 @@ bool Context::evaluateAsInitializer(State &Parent, const 
VarDecl *VD,
   (VD->getType()->isRecordType() || VD->getType()->isArrayType());
   auto Res = C.interpretDecl(VD, CheckGlobalInitialized);
   if (Res.isInvalid()) {
+C.cleanup();
 Stk.clear();
 return false;
   }

diff  --git a/clang/lib/AST/Interp/EvalEmitter.cpp 
b/clang/lib/AST/Interp/EvalEmitter.cpp
index 388c3612f292b..6d8aa3f20f01f 100644
--- a/clang/lib/AST/Interp/EvalEmitter.cpp
+++ b/clang/lib/AST/Interp/EvalEmitter.cpp
@@ -32,6 +32,11 @@ EvalEmitter::~EvalEmitter() {
   }
 }
 
+/// Clean up all our resources. This needs to done in failed evaluations before
+/// we call InterpStack::clear(), because there might be a Pointer on the stack
+/// pointing into a Block in the EvalEmitter.
+void EvalEmitter::cleanup() { S.cleanup(); }
+
 EvaluationResult EvalEmitter::interpretExpr(const Expr *E,
 bool ConvertResultToRValue) {
   S.setEvalLocation(E->getExprLoc());

diff  --git a/clang/lib/AST/Interp/EvalEmitter.h 
b/clang/lib/AST/Interp/EvalEmitter.h
index 116f1d6fc134a..98d6026bbcce4 100644
--- a/clang/lib/AST/Interp/EvalEmitter.h
+++ b/clang/lib/AST/Interp/EvalEmitter.h
@@ -38,6 +38,9 @@ class EvalEmitter : public SourceMapper {
  bool ConvertResultToRValue = false);
   EvaluationResult interpretDecl(const VarDecl *VD, bool 
CheckFullyInitialized);
 
+  /// Clean up all resources.
+  void cleanup();
+
   InterpState &getState() { return S; }
 
 protected:

diff  --git a/clang/lib/AST/Interp/InterpState.cpp 
b/clang/lib/AST/Interp/InterpState.cpp
index 2cb87ef07fe58..550bc9f1a84b9 100644
--- a/clang/lib/AST/Interp/InterpState.cpp
+++ b/clang/lib/AST/Interp/InterpState.cpp
@@ -33,6 +33,8 @@ InterpState::~InterpState() {
   }
 }
 
+void InterpState::cleanup() {}
+
 Frame *InterpState::getCurrentFrame() {
   if (Current && Current->Caller)
 return Current;

diff  --git a/clang/lib/AST/Interp/InterpState.h 
b/clang/lib/AST/Interp/InterpState.h
index d483c60c58e24..0938a723a76d0 100644
--- a/clang/lib/AST/Interp/InterpState.h
+++ b/clang/lib/AST/Interp/InterpState.h
@@ -39,6 +39,8 @@ class InterpState final : public State, public SourceMapper {
 
   ~InterpState();
 
+  void cleanup();
+
   InterpState(const InterpState &) = delete;
   InterpState &operator=(const InterpState &) = delete;
 



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


[clang] [clang-repl] Support wasm execution (PR #86402)

2024-06-05 Thread Aaron Ballman via cfe-commits

AaronBallman wrote:

So are we in a chicken-and-egg situation where we need some support in-tree in 
order to have a reason to set up a postcommit test bot but we don't want to 
land untested changes?

At the end of the day, if we're claiming support for something, we need it to 
be tested and this seems like a situation where we'd need an actual buildbot 
specific for the need. So we may want to proceed here in a few stages: 1) push 
up these changes without testing, 2) get a bot set up and have it test these 
changes, once it's green and we're happy then we publicly claim support, 3) if 
we don't get a bot set up within some reasonable timeframe, we agree to remove 
these changes so we don't leave untested code in the repo.

WDYT?

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


[clang] [Clang] Static and explicit object member functions with the same parameter-type-lists (PR #93430)

2024-06-05 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman approved this pull request.

LGTM!

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


[clang] [Clang] Static and explicit object member functions with the same parameter-type-lists (PR #93430)

2024-06-05 Thread Aaron Ballman via cfe-commits

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


[clang] [clang] Fix-it hint for `++this` -> `++*this` when deref is modifiable (PR #94159)

2024-06-05 Thread via cfe-commits


@@ -13367,6 +13367,8 @@ static void DiagnoseConstAssignment(Sema &S, const Expr 
*E,
 if (!DiagnosticEmitted) {
   S.Diag(Loc, diag::err_typecheck_assign_const)
   << ExprRange << ConstVariable << VD << VD->getType();
+  S.Diag(Loc, diag::note_typecheck_expression_not_modifiable_lvalue)
+  << E->getSourceRange();

Sirraide wrote:

Yup, the diagnostic should not be issued in this case since `j` is not of 
pointer type; that’s pretty much exactly what I meant by ‘make sure that the 
failures actually make sense’.

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


[clang] [clang-repl] Support wasm execution (PR #86402)

2024-06-05 Thread Vassil Vassilev via cfe-commits

vgvassilev wrote:

That would make sense. I am not sure if we can set a post commit bot though. 
@argentite what do you think?

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


[clang] [clang-repl] Support wasm execution (PR #86402)

2024-06-05 Thread Vassil Vassilev via cfe-commits

vgvassilev wrote:

@AaronBallman, to be fair, clang is testing the wasm features in terms of 
output. So this is wiring up a bunch of tested features that will allow 
execution. Clang generally does not test execution but output, so we are not 
creating a precedent here since that PR can be considered plumbing for 
downstream consumers. 

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


[clang] [clang-repl] Support wasm execution (PR #86402)

2024-06-05 Thread Aaron Ballman via cfe-commits

AaronBallman wrote:

> @AaronBallman, to be fair, clang is testing the wasm features in terms of 
> output. So this is wiring up a bunch of tested features that will allow 
> execution. Clang generally does not test execution but output, so we are not 
> creating a precedent here since that PR can be considered plumbing for 
> downstream consumers.

If we don't have community test coverage, we'll regress that plumbing for 
downstream consumers. In general, we shouldn't claim we support something we 
don't test. However, if there is a downstream consumer that agrees to be 
actively responsible for repairing breakages, we sometimes allow it (e.g., 
https://discourse.llvm.org/t/rfc-building-llvm-for-webassembly/79073)

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


[clang] [clang-repl] Support wasm execution (PR #86402)

2024-06-05 Thread Vassil Vassilev via cfe-commits

vgvassilev wrote:

> > @AaronBallman, to be fair, clang is testing the wasm features in terms of 
> > output. So this is wiring up a bunch of tested features that will allow 
> > execution. Clang generally does not test execution but output, so we are 
> > not creating a precedent here since that PR can be considered plumbing for 
> > downstream consumers.
> 
> If we don't have community test coverage, we'll regress that plumbing for 
> downstream consumers. In general, we shouldn't claim we support something we 
> don't test. However, if there is a downstream consumer that agrees to be 
> actively responsible for repairing breakages, we sometimes allow it (e.g., 
> https://discourse.llvm.org/t/rfc-building-llvm-for-webassembly/79073)

I am not sure if we have the same definition for "claim". FWIW I am not saying 
we should put any of this on the website or elsewhere. We have a downstream 
consumer which intergrates the emscripten version of wasm 
[here](https://github.com/emscripten-forge/recipes/tree/main/recipes/recipes_emscripten/llvm).
 @derthorsten is my go-to person when it comes to emscripten and llvm. I 
believe they are quite sensitive about breakages. In any case we will develop 
tests in the CppInterOp project, too. 

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


[clang] [clang-repl] Support wasm execution (PR #86402)

2024-06-05 Thread Aaron Ballman via cfe-commits

AaronBallman wrote:

> > > @AaronBallman, to be fair, clang is testing the wasm features in terms of 
> > > output. So this is wiring up a bunch of tested features that will allow 
> > > execution. Clang generally does not test execution but output, so we are 
> > > not creating a precedent here since that PR can be considered plumbing 
> > > for downstream consumers.
> > 
> > 
> > If we don't have community test coverage, we'll regress that plumbing for 
> > downstream consumers. In general, we shouldn't claim we support something 
> > we don't test. However, if there is a downstream consumer that agrees to be 
> > actively responsible for repairing breakages, we sometimes allow it (e.g., 
> > https://discourse.llvm.org/t/rfc-building-llvm-for-webassembly/79073)
> 
> I am not sure if we have the same definition for "claim". FWIW I am not 
> saying we should put any of this on the website or elsewhere. We have a 
> downstream consumer which intergrates the emscripten version of wasm 
> [here](https://github.com/emscripten-forge/recipes/tree/main/recipes/recipes_emscripten/llvm).
>  @DerThorsten is my go-to person when it comes to emscripten and llvm. I 
> believe they are quite sensitive about breakages. In any case we will develop 
> tests in the CppInterOp project, too.

I wouldn't focus on "claim" too heavily. We should not have code in-tree that's 
not tested except in exceptional situations and it's not clear to me that this 
is (or isn't) such an exceptional situation.

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


[clang] [flang] [Flang][OpenMP] Add -fopenmp-force-usm option to flang (PR #94359)

2024-06-05 Thread Sergio Afonso via cfe-commits

https://github.com/skatrak updated 
https://github.com/llvm/llvm-project/pull/94359

>From 88a2553168b4fd3ad1b65b855c2bdf5aba09d126 Mon Sep 17 00:00:00 2001
From: Sergio Afonso 
Date: Tue, 4 Jun 2024 15:26:38 +0100
Subject: [PATCH 1/2] [Flang][OpenMP] Add -fopenmp-force-usm option to flang

This patch enables the `-fopenmp-force-usm` option to be passed to the flang
driver, which forwards it to the compiler frontend. This flag, when set,
results in the introduction of the `unified_shared_memory` bit to the
`omp.requires` attribute of the top-level module operation.

This is later combined with any other target device-related REQUIRES clauses
that may have been explicitly set in the compilation unit.
---
 clang/include/clang/Driver/Options.td |  2 +-
 clang/lib/Driver/ToolChains/Flang.cpp |  2 ++
 flang/include/flang/Frontend/LangOptions.def  |  2 ++
 flang/include/flang/Tools/CrossToolHelpers.h  | 20 ---
 flang/lib/Frontend/CompilerInvocation.cpp |  3 +++
 flang/lib/Lower/OpenMP/OpenMP.cpp |  4 +++-
 flang/test/Driver/omp-driver-offload.f90  | 20 +++
 flang/test/Lower/OpenMP/force-usm.f90 | 12 +++
 .../test/Lower/OpenMP/requires-force-usm.f90  | 15 ++
 flang/tools/bbc/bbc.cpp   | 15 +-
 10 files changed, 81 insertions(+), 14 deletions(-)
 create mode 100644 flang/test/Lower/OpenMP/force-usm.f90
 create mode 100644 flang/test/Lower/OpenMP/requires-force-usm.f90

diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 5ab2d49c7a497..f04c220d6e1db 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3592,7 +3592,7 @@ def fopenmp_offload_mandatory : Flag<["-"], 
"fopenmp-offload-mandatory">, Group<
   HelpText<"Do not create a host fallback if offloading to the device fails.">,
   MarshallingInfoFlag>;
 def fopenmp_force_usm : Flag<["-"], "fopenmp-force-usm">, Group,
-  Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CC1Option]>,
+  Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CC1Option, FlangOption, 
FC1Option]>,
   HelpText<"Force behvaior as if the user specified pragma omp requires 
unified_shared_memory.">,
   MarshallingInfoFlag>;
 def fopenmp_target_jit : Flag<["-"], "fopenmp-target-jit">, Group,
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp 
b/clang/lib/Driver/ToolChains/Flang.cpp
index 42ca060186fd8..b7abe7b1c19bc 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -766,6 +766,8 @@ void Flang::ConstructJob(Compilation &C, const JobAction 
&JA,
   Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_version_EQ);
 
   // FIXME: Clang supports a whole bunch more flags here.
+  if (Args.hasArg(options::OPT_fopenmp_force_usm))
+CmdArgs.push_back("-fopenmp-force-usm");
   break;
 default:
   // By default, if Clang doesn't know how to generate useful OpenMP code
diff --git a/flang/include/flang/Frontend/LangOptions.def 
b/flang/include/flang/Frontend/LangOptions.def
index 2bf10826120a8..d3e1e972d1519 100644
--- a/flang/include/flang/Frontend/LangOptions.def
+++ b/flang/include/flang/Frontend/LangOptions.def
@@ -42,6 +42,8 @@ LANGOPT(OpenMPVersion, 32, 0)
 LANGOPT(OpenMPIsTargetDevice, 1, false)
 /// Generate OpenMP target code only for GPUs
 LANGOPT(OpenMPIsGPU, 1, false)
+/// Generate OpenMP target code only for GPUs
+LANGOPT(OpenMPForceUSM, 1, false)
 /// Enable debugging in the OpenMP offloading device RTL
 LANGOPT(OpenMPTargetDebug, 32, 0)
 /// Assume work-shared loops do not have more iterations than participating
diff --git a/flang/include/flang/Tools/CrossToolHelpers.h 
b/flang/include/flang/Tools/CrossToolHelpers.h
index 77b68fc6187fa..26fbe51d329c7 100644
--- a/flang/include/flang/Tools/CrossToolHelpers.h
+++ b/flang/include/flang/Tools/CrossToolHelpers.h
@@ -130,16 +130,16 @@ struct OffloadModuleOpts {
   OffloadModuleOpts(uint32_t OpenMPTargetDebug, bool OpenMPTeamSubscription,
   bool OpenMPThreadSubscription, bool OpenMPNoThreadState,
   bool OpenMPNoNestedParallelism, bool OpenMPIsTargetDevice,
-  bool OpenMPIsGPU, uint32_t OpenMPVersion, std::string OMPHostIRFile = {},
-  bool NoGPULib = false)
+  bool OpenMPIsGPU, bool OpenMPForceUSM, uint32_t OpenMPVersion,
+  std::string OMPHostIRFile = {}, bool NoGPULib = false)
   : OpenMPTargetDebug(OpenMPTargetDebug),
 OpenMPTeamSubscription(OpenMPTeamSubscription),
 OpenMPThreadSubscription(OpenMPThreadSubscription),
 OpenMPNoThreadState(OpenMPNoThreadState),
 OpenMPNoNestedParallelism(OpenMPNoNestedParallelism),
 OpenMPIsTargetDevice(OpenMPIsTargetDevice), OpenMPIsGPU(OpenMPIsGPU),
-OpenMPVersion(OpenMPVersion), OMPHostIRFile(OMPHostIRFile),
-NoGPULib(NoGPULib) {}
+OpenMPForceUSM(OpenMPForceUSM), OpenMPVersion(OpenMPVersion),
+OMPHostIRFile(OMPHostIRFile

[clang-tools-extra] [clang-tidy] `doesNotMutateObject`: Handle calls to member functions … (PR #94362)

2024-06-05 Thread Felix Berger via cfe-commits


@@ -259,9 +258,9 @@ void 
UnnecessaryCopyInitialization::registerMatchers(MatchFinder *Finder) {
 .bind("blockStmt");
   };
 
-  
Finder->addMatcher(LocalVarCopiedFrom(anyOf(isConstRefReturningFunctionCall(),
-  isConstRefReturningMethodCall(
-  ExcludedContainerTypes))),
+  Finder->addMatcher(LocalVarCopiedFrom(anyOf(
+ isConstRefReturningFunctionCall(),
+ isRefReturningMethodCall(ExcludedContainerTypes))),

fberger wrote:

Could we call this `isRefReturningMethodCallWithConstOverloads()`?

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


[clang] [clang-repl] Support wasm execution (PR #86402)

2024-06-05 Thread Vassil Vassilev via cfe-commits

vgvassilev wrote:

> > > > @AaronBallman, to be fair, clang is testing the wasm features in terms 
> > > > of output. So this is wiring up a bunch of tested features that will 
> > > > allow execution. Clang generally does not test execution but output, so 
> > > > we are not creating a precedent here since that PR can be considered 
> > > > plumbing for downstream consumers.
> > > 
> > > 
> > > If we don't have community test coverage, we'll regress that plumbing for 
> > > downstream consumers. In general, we shouldn't claim we support something 
> > > we don't test. However, if there is a downstream consumer that agrees to 
> > > be actively responsible for repairing breakages, we sometimes allow it 
> > > (e.g., 
> > > https://discourse.llvm.org/t/rfc-building-llvm-for-webassembly/79073)
> > 
> > 
> > I am not sure if we have the same definition for "claim". FWIW I am not 
> > saying we should put any of this on the website or elsewhere. We have a 
> > downstream consumer which intergrates the emscripten version of wasm 
> > [here](https://github.com/emscripten-forge/recipes/tree/main/recipes/recipes_emscripten/llvm).
> >  @DerThorsten is my go-to person when it comes to emscripten and llvm. I 
> > believe they are quite sensitive about breakages. In any case we will 
> > develop tests in the CppInterOp project, too.
> 
> I wouldn't focus on "claim" too heavily.

Ok.

> We should not have code in-tree that's not tested except in exceptional 
> situations and it's not clear to me that this is (or isn't) such an 
> exceptional situation.

Well, as of today I do not see how we can test execution of jit-based wasm in 
tree. I am not a wasm expert but IIUC, testing would require a browser and 
compiling llvm for emscripten and somehow running some remote execution 
service... 

My worry is that we are losing the forest for the trees because this work has 
stayed as a patch since maybe more than a year. It'd be a pity to wait more 
because that blocks downstream consumers in practice...

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


[clang] [clang-repl] Extend the C support. (PR #89804)

2024-06-05 Thread Haojian Wu via cfe-commits

hokein wrote:

@vgvassilev 

The reland d999ce0302f06d250f6d496b56a5a5f2dc331e61 makes the clang reject the 
valid code now:

```
$ cat /tmp/t33.cpp
#include 
#include 

int main() {

}

  
$  ./bin/clang -Xclang -fsyntax-only -Xclang=-fincremental-extensions 
-stdlib=libc++ /tmp/t33.cpp  <<<
In file included from /tmp/t33.cpp:2:
In file included from /usr/include/c++/v1/algorithm:1712:
In file included from /usr/include/c++/v1/memory:877:
In file included from /usr/include/c++/v1/iterator:684:
In file included from /usr/include/c++/v1/__iterator/common_iterator.h:22:
/usr/include/c++/v1/variant:1024:43: error: use of undeclared identifier 
'__arg'; did you mean '_pthread_cleanup_buffer::__arg'?
 1024 |   } __impl{this, _VSTD::forward<_Arg>(__arg)};
  |   ^
/usr/include/pthread.h:162:9: note: '_pthread_cleanup_buffer::__arg' declared 
here
  162 |   void *__arg;/* Its argument.  */
  | ^
In file included from /tmp/t33.cpp:2:
In file included from /usr/include/c++/v1/algorithm:1861:
In file included from 
/usr/include/c++/v1/__algorithm/ranges_stable_partition.h:15:
/usr/include/c++/v1/__algorithm/stable_partition.h:246:18: error: use of 
undeclared label '__second_half_done'
  246 | goto __second_half_done;
  |  ^
2 errors generated.
```

Can you take a look?

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


[clang] [Clang][Comments] Support for parsing headers in Doxygen \par commands (PR #91100)

2024-06-05 Thread Aaron Ballman via cfe-commits


@@ -149,6 +149,63 @@ class TextTokenRetokenizer {
 addToken();
   }
 
+  /// Check if this line starts with @par or \par
+  bool startsWithParCommand() {
+unsigned Offset = 1;
+
+/// Skip all whitespace characters at the beginning.
+/// This needs to backtrack because Pos has already advanced past the
+/// actual \par or @par command by the time this function is called.
+while (isWhitespace(*(Pos.BufferPtr - Offset)))
+  Offset++;

AaronBallman wrote:

Rather than backtracking, can't we still do a peek ahead? e.g., once we've seen 
`@par`, we can do a peek to see if the next token is a newline or not (or do a 
scan through the buffer to see if there is a non-whitespace character or only 
whitespace ending with a newline/eof)?

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


[clang] [clang-repl] Extend the C support. (PR #89804)

2024-06-05 Thread Vassil Vassilev via cfe-commits

vgvassilev wrote:

@hokein, ah, that's annoying. Can you provide the entire proprocessed file that 
does not work? I'd like to bisect and debug.

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


[clang-tools-extra] [clang-tidy] `doesNotMutateObject`: Handle calls to member functions … (PR #94362)

2024-06-05 Thread Felix Berger via cfe-commits


@@ -36,6 +36,111 @@ void extractNodesByIdTo(ArrayRef Matches, 
StringRef ID,
 Nodes.insert(Match.getNodeAs(ID));
 }
 
+// If `D` has a const-qualified overload with otherwise identical
+// ref-qualifiers, returns that overload.
+const CXXMethodDecl *findConstOverload(const CXXMethodDecl &D) {
+  assert(!D.isConst());
+
+  DeclContext::lookup_result lookup_result =
+  D.getParent()->lookup(D.getNameInfo().getName());
+  if (lookup_result.isSingleResult()) {
+// No overload.
+return nullptr;
+  }
+  for (const Decl *overload : lookup_result) {
+const CXXMethodDecl *candidate = dyn_cast(overload);
+if (candidate && !candidate->isDeleted() && candidate->isConst() &&
+candidate->getRefQualifier() == D.getRefQualifier()) {

fberger wrote:

It looks like we look up by name, do we also need to confirm that the return 
types are the same, or would overloading otherwise not be allowed and that's 
why it's implied?

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


[clang-tools-extra] [clang-tidy] `doesNotMutateObject`: Handle calls to member functions … (PR #94362)

2024-06-05 Thread Felix Berger via cfe-commits


@@ -36,6 +36,111 @@ void extractNodesByIdTo(ArrayRef Matches, 
StringRef ID,
 Nodes.insert(Match.getNodeAs(ID));
 }
 
+// If `D` has a const-qualified overload with otherwise identical
+// ref-qualifiers, returns that overload.
+const CXXMethodDecl *findConstOverload(const CXXMethodDecl &D) {
+  assert(!D.isConst());
+
+  DeclContext::lookup_result lookup_result =
+  D.getParent()->lookup(D.getNameInfo().getName());
+  if (lookup_result.isSingleResult()) {
+// No overload.
+return nullptr;
+  }
+  for (const Decl *overload : lookup_result) {
+const CXXMethodDecl *candidate = dyn_cast(overload);
+if (candidate && !candidate->isDeleted() && candidate->isConst() &&
+candidate->getRefQualifier() == D.getRefQualifier()) {
+  return candidate;
+}
+  }
+  return nullptr;
+}
+
+// Returns true if both types refer to the same to the same type,
+// ignoring the const-qualifier.
+bool isSameTypeIgnoringConst(QualType A, QualType B) {
+  A = A.getCanonicalType();
+  B = B.getCanonicalType();
+  A.addConst();
+  B.addConst();
+  return A == B;
+}
+
+// Returns true if both types are pointers or reference to the same type,
+// ignoring the const-qualifier.
+bool pointsToSameTypeIgnoringConst(QualType A, QualType B) {
+  assert(A->isPointerType() || A->isReferenceType());
+  assert(B->isPointerType() || B->isReferenceType());
+  return isSameTypeIgnoringConst(A->getPointeeType(), B->getPointeeType());
+}
+
+// Return true if non-const member function `M` likely does not mutate `*this`.
+//
+// Note that if the member call selects a method/operator `f` that
+// is not const-qualified, then we also consider that the object is
+// not mutated if:
+//  - (A) there is a const-qualified overload `cf` of `f` that has
+//  the
+//same ref-qualifiers;
+//  - (B) * `f` returns a value, or
+//* if `f` returns a `T&`, `cf` returns a `const T&` (up to
+//  possible aliases such as `reference` and
+//  `const_reference`), or
+//* if `f` returns a `T*`, `cf` returns a `const T*` (up to
+//  possible aliases).
+//  - (C) the result of the call is not mutated.
+//
+// The assumption that `cf` has the same semantics as `f`.
+// For example:
+//   - In `std::vector v; const T t = v[...];`, we consider that
+// expression `v[...]` does not mutate `v` as
+//`T& std::vector::operator[]` has a const overload
+// `const T& std::vector::operator[] const`, and the
+// result expression of type `T&` is only used as a `const T&`;
+//   - In `std::map m; V v = m.at(...);`, we consider
+// `m.at(...)` to be an immutable access for the same reason.
+// However:
+//   - In `std::map m; const V v = m[...];`, We consider that
+// `m[...]` mutates `m` as `V& std::map::operator[]` does
+// not have a const overload.
+//   - In `std::vector v; T& t = v[...];`, we consider that
+// expression `v[...]` mutates `v` as the result is kept as a
+// mutable reference.
+//
+// This function checks (A) ad (B), but the caller should make sure that the
+// object is not mutated through the return value.
+bool isLikelyShallowConst(const CXXMethodDecl &M) {
+  assert(!M.isConst());
+  // The method can mutate our variable.
+
+  // (A)
+  const CXXMethodDecl *ConstOverload = findConstOverload(M);
+  if (ConstOverload == nullptr) {
+return false;
+  }
+
+  // (B)
+  const QualType CallTy = M.getReturnType().getCanonicalType();
+  const QualType OverloadTy = 
ConstOverload->getReturnType().getCanonicalType();
+  if (CallTy->isReferenceType()) {
+if (!(OverloadTy->isReferenceType() &&

fberger wrote:

I would find: `(!isReferenceType() || !pointsToSameTypIgnoringConst())` 
easier to parse here.

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


[clang-tools-extra] [clang-tidy] `doesNotMutateObject`: Handle calls to member functions … (PR #94362)

2024-06-05 Thread Felix Berger via cfe-commits


@@ -36,6 +36,111 @@ void extractNodesByIdTo(ArrayRef Matches, 
StringRef ID,
 Nodes.insert(Match.getNodeAs(ID));
 }
 
+// If `D` has a const-qualified overload with otherwise identical
+// ref-qualifiers, returns that overload.
+const CXXMethodDecl *findConstOverload(const CXXMethodDecl &D) {
+  assert(!D.isConst());
+
+  DeclContext::lookup_result lookup_result =
+  D.getParent()->lookup(D.getNameInfo().getName());
+  if (lookup_result.isSingleResult()) {
+// No overload.
+return nullptr;
+  }
+  for (const Decl *overload : lookup_result) {
+const CXXMethodDecl *candidate = dyn_cast(overload);
+if (candidate && !candidate->isDeleted() && candidate->isConst() &&
+candidate->getRefQualifier() == D.getRefQualifier()) {
+  return candidate;
+}
+  }
+  return nullptr;
+}
+
+// Returns true if both types refer to the same to the same type,
+// ignoring the const-qualifier.
+bool isSameTypeIgnoringConst(QualType A, QualType B) {
+  A = A.getCanonicalType();
+  B = B.getCanonicalType();
+  A.addConst();
+  B.addConst();
+  return A == B;
+}
+
+// Returns true if both types are pointers or reference to the same type,
+// ignoring the const-qualifier.
+bool pointsToSameTypeIgnoringConst(QualType A, QualType B) {
+  assert(A->isPointerType() || A->isReferenceType());
+  assert(B->isPointerType() || B->isReferenceType());
+  return isSameTypeIgnoringConst(A->getPointeeType(), B->getPointeeType());
+}
+
+// Return true if non-const member function `M` likely does not mutate `*this`.
+//
+// Note that if the member call selects a method/operator `f` that
+// is not const-qualified, then we also consider that the object is
+// not mutated if:
+//  - (A) there is a const-qualified overload `cf` of `f` that has
+//  the
+//same ref-qualifiers;
+//  - (B) * `f` returns a value, or
+//* if `f` returns a `T&`, `cf` returns a `const T&` (up to
+//  possible aliases such as `reference` and
+//  `const_reference`), or
+//* if `f` returns a `T*`, `cf` returns a `const T*` (up to
+//  possible aliases).
+//  - (C) the result of the call is not mutated.
+//
+// The assumption that `cf` has the same semantics as `f`.
+// For example:
+//   - In `std::vector v; const T t = v[...];`, we consider that
+// expression `v[...]` does not mutate `v` as
+//`T& std::vector::operator[]` has a const overload
+// `const T& std::vector::operator[] const`, and the
+// result expression of type `T&` is only used as a `const T&`;
+//   - In `std::map m; V v = m.at(...);`, we consider
+// `m.at(...)` to be an immutable access for the same reason.
+// However:
+//   - In `std::map m; const V v = m[...];`, We consider that
+// `m[...]` mutates `m` as `V& std::map::operator[]` does
+// not have a const overload.
+//   - In `std::vector v; T& t = v[...];`, we consider that
+// expression `v[...]` mutates `v` as the result is kept as a
+// mutable reference.
+//
+// This function checks (A) ad (B), but the caller should make sure that the
+// object is not mutated through the return value.
+bool isLikelyShallowConst(const CXXMethodDecl &M) {
+  assert(!M.isConst());
+  // The method can mutate our variable.
+
+  // (A)
+  const CXXMethodDecl *ConstOverload = findConstOverload(M);
+  if (ConstOverload == nullptr) {
+return false;
+  }
+
+  // (B)
+  const QualType CallTy = M.getReturnType().getCanonicalType();
+  const QualType OverloadTy = 
ConstOverload->getReturnType().getCanonicalType();
+  if (CallTy->isReferenceType()) {
+if (!(OverloadTy->isReferenceType() &&
+  pointsToSameTypeIgnoringConst(CallTy, OverloadTy))) {
+  return false;
+}

fberger wrote:

Can we return true here early and avoid nesting below?

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


[clang-tools-extra] [clang-tidy] `doesNotMutateObject`: Handle calls to member functions … (PR #94362)

2024-06-05 Thread Felix Berger via cfe-commits


@@ -36,6 +36,111 @@ void extractNodesByIdTo(ArrayRef Matches, 
StringRef ID,
 Nodes.insert(Match.getNodeAs(ID));
 }
 
+// If `D` has a const-qualified overload with otherwise identical
+// ref-qualifiers, returns that overload.
+const CXXMethodDecl *findConstOverload(const CXXMethodDecl &D) {
+  assert(!D.isConst());
+
+  DeclContext::lookup_result lookup_result =
+  D.getParent()->lookup(D.getNameInfo().getName());
+  if (lookup_result.isSingleResult()) {
+// No overload.
+return nullptr;
+  }
+  for (const Decl *overload : lookup_result) {
+const CXXMethodDecl *candidate = dyn_cast(overload);
+if (candidate && !candidate->isDeleted() && candidate->isConst() &&
+candidate->getRefQualifier() == D.getRefQualifier()) {
+  return candidate;
+}
+  }
+  return nullptr;
+}
+
+// Returns true if both types refer to the same to the same type,

fberger wrote:

Nit: Remove duplicae "to the same".

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


[clang] [clang-repl] Extend the C support. (PR #89804)

2024-06-05 Thread Vassil Vassilev via cfe-commits

vgvassilev wrote:

I realize I do not entirely understand the role of the IdResolver chain in c++. 
Perhaps we are better of changing this line to:

```cpp
if (!PP.isIncrementalProcessingEnabled() || getLangOpts().ObjC)
  IdResolver.RemoveDecl(D);
 ```
 to
 ```
if (!PP.isIncrementalProcessingEnabled() || !getLangOpts().C)
  IdResolver.RemoveDecl(D);
  ```

This way will limit the scope to the actual intent without assuming the 
IdResolver changes are irrelevant for languages such as C++. Can you test if 
that works?

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


[clang] [clang-repl] Support wasm execution (PR #86402)

2024-06-05 Thread Thorsten Beier via cfe-commits

DerThorsten wrote:

> > > @AaronBallman, to be fair, clang is testing the wasm features in terms of 
> > > output. So this is wiring up a bunch of tested features that will allow 
> > > execution. Clang generally does not test execution but output, so we are 
> > > not creating a precedent here since that PR can be considered plumbing 
> > > for downstream consumers.
> > 
> > 
> > If we don't have community test coverage, we'll regress that plumbing for 
> > downstream consumers. In general, we shouldn't claim we support something 
> > we don't test. However, if there is a downstream consumer that agrees to be 
> > actively responsible for repairing breakages, we sometimes allow it (e.g., 
> > https://discourse.llvm.org/t/rfc-building-llvm-for-webassembly/79073)
> 
> I am not sure if we have the same definition for "claim". FWIW I am not 
> saying we should put any of this on the website or elsewhere. We have a 
> downstream consumer which intergrates the emscripten version of wasm 
> [here](https://github.com/emscripten-forge/recipes/tree/main/recipes/recipes_emscripten/llvm).
>  @DerThorsten is my go-to person when it comes to emscripten and llvm. I 
> believe they are quite sensitive about breakages. In any case we will develop 
> tests in the CppInterOp project, too.

For emscripten-forge recipes of xeus-cpp /clang  you can break whatever you 
want.
I am sure there are no deployments  / users yet

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


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

2024-06-05 Thread Fanbo Meng via cfe-commits

fanbo-meng wrote:

@uweigand can you review again pls? thanks

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


[clang] [OpenACC] Loop construct basic Sema and AST work (PR #93742)

2024-06-05 Thread Erich Keane via cfe-commits

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


[clang] 42f4e50 - [OpenACC] Loop construct basic Sema and AST work (#93742)

2024-06-05 Thread via cfe-commits

Author: Erich Keane
Date: 2024-06-05T06:21:48-07:00
New Revision: 42f4e505a38480b6a714b503dd94631ae029

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

LOG: [OpenACC] Loop construct basic Sema and AST work (#93742)

This patch implements the 'loop' construct AST, as well as the basic
appertainment rule. Additionally, it sets up the 'parent' compute
construct, which is necessary for codegen/other diagnostics.

A 'loop' can apply to a for or range-for loop, otherwise it has no other
restrictions (though some of its clauses do).

Added: 
clang/test/AST/ast-print-openacc-loop-construct.cpp
clang/test/SemaOpenACC/loop-ast.cpp
clang/test/SemaOpenACC/loop-loc-and-stmt.c
clang/test/SemaOpenACC/loop-loc-and-stmt.cpp

Modified: 
clang/include/clang-c/Index.h
clang/include/clang/AST/RecursiveASTVisitor.h
clang/include/clang/AST/StmtOpenACC.h
clang/include/clang/AST/TextNodeDumper.h
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Basic/StmtNodes.td
clang/include/clang/Sema/SemaOpenACC.h
clang/include/clang/Serialization/ASTBitCodes.h
clang/lib/AST/StmtOpenACC.cpp
clang/lib/AST/StmtPrinter.cpp
clang/lib/AST/StmtProfile.cpp
clang/lib/AST/TextNodeDumper.cpp
clang/lib/CodeGen/CGStmt.cpp
clang/lib/CodeGen/CodeGenFunction.h
clang/lib/Parse/ParseOpenACC.cpp
clang/lib/Sema/SemaExceptionSpec.cpp
clang/lib/Sema/SemaOpenACC.cpp
clang/lib/Sema/TreeTransform.h
clang/lib/Serialization/ASTReaderStmt.cpp
clang/lib/Serialization/ASTWriterStmt.cpp
clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
clang/test/ParserOpenACC/parse-clauses.c
clang/test/ParserOpenACC/parse-clauses.cpp
clang/test/ParserOpenACC/parse-constructs.c
clang/test/SemaOpenACC/compute-construct-async-clause.c
clang/test/SemaOpenACC/compute-construct-attach-clause.c
clang/test/SemaOpenACC/compute-construct-copy-clause.c
clang/test/SemaOpenACC/compute-construct-copyin-clause.c
clang/test/SemaOpenACC/compute-construct-copyout-clause.c
clang/test/SemaOpenACC/compute-construct-create-clause.c
clang/test/SemaOpenACC/compute-construct-default-clause.c
clang/test/SemaOpenACC/compute-construct-deviceptr-clause.c
clang/test/SemaOpenACC/compute-construct-firstprivate-clause.c
clang/test/SemaOpenACC/compute-construct-if-clause.c
clang/test/SemaOpenACC/compute-construct-no_create-clause.c
clang/test/SemaOpenACC/compute-construct-num_gangs-clause.c
clang/test/SemaOpenACC/compute-construct-num_workers-clause.c
clang/test/SemaOpenACC/compute-construct-present-clause.c
clang/test/SemaOpenACC/compute-construct-self-clause.c
clang/test/SemaOpenACC/compute-construct-vector_length-clause.c
clang/test/SemaOpenACC/compute-construct-wait-clause.c
clang/tools/libclang/CIndex.cpp
clang/tools/libclang/CXCursor.cpp

Removed: 




diff  --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index 365b607c74117..ce2282937f86c 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -2150,7 +2150,11 @@ enum CXCursorKind {
*/
   CXCursor_OpenACCComputeConstruct = 320,
 
-  CXCursor_LastStmt = CXCursor_OpenACCComputeConstruct,
+  /** OpenACC Loop Construct.
+   */
+  CXCursor_OpenACCLoopConstruct = 321,
+
+  CXCursor_LastStmt = CXCursor_OpenACCLoopConstruct,
 
   /**
* Cursor that represents the translation unit itself.

diff  --git a/clang/include/clang/AST/RecursiveASTVisitor.h 
b/clang/include/clang/AST/RecursiveASTVisitor.h
index 99093aa17972c..aa55e2e7e8718 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -4000,6 +4000,8 @@ bool RecursiveASTVisitor::VisitOpenACCClauseList(
 
 DEF_TRAVERSE_STMT(OpenACCComputeConstruct,
   { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
+DEF_TRAVERSE_STMT(OpenACCLoopConstruct,
+  { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
 
 // FIXME: look at the following tricky-seeming exprs to see if we
 // need to recurse on anything.  These are ones that have methods

diff  --git a/clang/include/clang/AST/StmtOpenACC.h 
b/clang/include/clang/AST/StmtOpenACC.h
index 04daf511f5871..b3aea09be03dd 100644
--- a/clang/include/clang/AST/StmtOpenACC.h
+++ b/clang/include/clang/AST/StmtOpenACC.h
@@ -113,6 +113,8 @@ class OpenACCAssociatedStmtConstruct : public 
OpenACCConstructStmt {
 return const_cast(this)->children();
   }
 };
+
+class OpenACCLoopConstruct;
 /// This class represents a compute construct, representing a 'Kind' of
 /// `parallel', 'serial', or 'kernel'. These constructs are associated with a
 /// 'structured block', defined as:
@@ -165,6 +167,11 @@ class OpenACCComputeConstr

[clang] [clang-repl] Extend the C support. (PR #89804)

2024-06-05 Thread Haojian Wu via cfe-commits

hokein wrote:

Thanks for the prompt response. I think limiting it to C-only will fix the 
issue (note that there is no `C` in `LangOpts`, you may want to use 
`!getLangOpts().CPlusPlus` to exclude C++).

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


[clang] Support [[guarded_by(mutex)]] attribute inside C struct (PR #94216)

2024-06-05 Thread Pierre d'Herbemont via cfe-commits

pdherbemont wrote:

> One question I have is whether there will be follow-up work for other thread 
> safety attributes (`acquire_capability`, `try_acquire_capability`, etc)?

They already work fine in C so far. But if you are aware of some issues don't 
hesitate to let me know!

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


[clang] [clang-repl] Extend the C support. (PR #89804)

2024-06-05 Thread Vassil Vassilev via cfe-commits

vgvassilev wrote:

> Thanks for the prompt response. I think limiting it to C-only will fix the 
> issue (note that there is no `C` in `LangOpts`, you may want to use 
> `!getLangOpts().CPlusPlus` to exclude C++).

Makes sense. If that works for you, we can check this in. I want to somehow 
record this breakage in the form of a test for our future selves when decide to 
revisit this workaround-looking code.

Out of curiosity, in what context you use `-fincremental-extensions`?

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


[clang] [clang-repl] Support wasm execution (PR #86402)

2024-06-05 Thread Vassil Vassilev via cfe-commits

vgvassilev wrote:

> > > > @AaronBallman, to be fair, clang is testing the wasm features in terms 
> > > > of output. So this is wiring up a bunch of tested features that will 
> > > > allow execution. Clang generally does not test execution but output, so 
> > > > we are not creating a precedent here since that PR can be considered 
> > > > plumbing for downstream consumers.
> > > 
> > > 
> > > If we don't have community test coverage, we'll regress that plumbing for 
> > > downstream consumers. In general, we shouldn't claim we support something 
> > > we don't test. However, if there is a downstream consumer that agrees to 
> > > be actively responsible for repairing breakages, we sometimes allow it 
> > > (e.g., 
> > > https://discourse.llvm.org/t/rfc-building-llvm-for-webassembly/79073)
> > 
> > 
> > I am not sure if we have the same definition for "claim". FWIW I am not 
> > saying we should put any of this on the website or elsewhere. We have a 
> > downstream consumer which intergrates the emscripten version of wasm 
> > [here](https://github.com/emscripten-forge/recipes/tree/main/recipes/recipes_emscripten/llvm).
> >  @DerThorsten is my go-to person when it comes to emscripten and llvm. I 
> > believe they are quite sensitive about breakages. In any case we will 
> > develop tests in the CppInterOp project, too.
> 
> For emscripten-forge recipes of xeus-cpp /clang you can break whatever you 
> want. I am sure there are no deployments / users yet



> > > > @AaronBallman, to be fair, clang is testing the wasm features in terms 
> > > > of output. So this is wiring up a bunch of tested features that will 
> > > > allow execution. Clang generally does not test execution but output, so 
> > > > we are not creating a precedent here since that PR can be considered 
> > > > plumbing for downstream consumers.
> > > 
> > > 
> > > If we don't have community test coverage, we'll regress that plumbing for 
> > > downstream consumers. In general, we shouldn't claim we support something 
> > > we don't test. However, if there is a downstream consumer that agrees to 
> > > be actively responsible for repairing breakages, we sometimes allow it 
> > > (e.g., 
> > > https://discourse.llvm.org/t/rfc-building-llvm-for-webassembly/79073)
> > 
> > 
> > I am not sure if we have the same definition for "claim". FWIW I am not 
> > saying we should put any of this on the website or elsewhere. We have a 
> > downstream consumer which intergrates the emscripten version of wasm 
> > [here](https://github.com/emscripten-forge/recipes/tree/main/recipes/recipes_emscripten/llvm).
> >  @DerThorsten is my go-to person when it comes to emscripten and llvm. I 
> > believe they are quite sensitive about breakages. In any case we will 
> > develop tests in the CppInterOp project, too.
> 
> For emscripten-forge recipes of xeus-cpp /clang you can break whatever you 
> want. I am sure there are no deployments / users yet

I think Aaron's question was if we land this PR and it regresses over time, 
would our downstream clients be able to catch it in a timely manner.

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


[clang] [clang-repl] Extend the C support. (PR #89804)

2024-06-05 Thread Haojian Wu via cfe-commits

hokein wrote:

> Out of curiosity, in what context you use -fincremental-extensions?

The code snippet I provided is extracted from our internal test. We have an 
internal clang-tool (with the `incremental-extensions` on) to generate headers 

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


[clang] [clang-repl] Support wasm execution (PR #86402)

2024-06-05 Thread Aaron Ballman via cfe-commits

AaronBallman wrote:

> > > > > @AaronBallman, to be fair, clang is testing the wasm features in 
> > > > > terms of output. So this is wiring up a bunch of tested features that 
> > > > > will allow execution. Clang generally does not test execution but 
> > > > > output, so we are not creating a precedent here since that PR can be 
> > > > > considered plumbing for downstream consumers.
> > > > 
> > > > 
> > > > If we don't have community test coverage, we'll regress that plumbing 
> > > > for downstream consumers. In general, we shouldn't claim we support 
> > > > something we don't test. However, if there is a downstream consumer 
> > > > that agrees to be actively responsible for repairing breakages, we 
> > > > sometimes allow it (e.g., 
> > > > https://discourse.llvm.org/t/rfc-building-llvm-for-webassembly/79073)
> > > 
> > > 
> > > I am not sure if we have the same definition for "claim". FWIW I am not 
> > > saying we should put any of this on the website or elsewhere. We have a 
> > > downstream consumer which intergrates the emscripten version of wasm 
> > > [here](https://github.com/emscripten-forge/recipes/tree/main/recipes/recipes_emscripten/llvm).
> > >  @DerThorsten is my go-to person when it comes to emscripten and llvm. I 
> > > believe they are quite sensitive about breakages. In any case we will 
> > > develop tests in the CppInterOp project, too.
> > 
> > 
> > I wouldn't focus on "claim" too heavily.
> 
> Ok.
> 
> > We should not have code in-tree that's not tested except in exceptional 
> > situations and it's not clear to me that this is (or isn't) such an 
> > exceptional situation.
> 
> Well, as of today I do not see how we can test execution of jit-based wasm in 
> tree. I am not a wasm expert but IIUC, testing would require a browser and 
> compiling llvm for emscripten and somehow running some remote execution 
> service...

Yeah, we don't have any existing test infrastructure we could lean on for it. 
However, this doesn't seem impossible to test; surely other projects have 
figured out a test harness for WASM?

> My worry is that we are losing the forest for the trees because this work has 
> stayed as a patch since maybe more than a year. It'd be a pity to wait more 
> because that blocks downstream consumers in practice...

Yeah, it's a tough tradeoff. The two things I'm specifically worried about are: 
1) users of the downstream see a break and (eventually) report it to Clang 
rather than the downstream, so now we have to triage it without a way to 
reproduce, 2) we change internal APIs and need to update this code but have no 
way to determine if those updates will or won't break the functionality.

If the downstream that needs this functionality can commit to be responsible 
for maintaining it within Clang, that would help alleviate the concerns 
somewhat.

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


[clang] [clang-repl] Extend the C support. (PR #89804)

2024-06-05 Thread Vassil Vassilev via cfe-commits

vgvassilev wrote:

> > Out of curiosity, in what context you use -fincremental-extensions?
> 
> The code snippet I provided is extracted from our internal test. We have an 
> internal clang-tool (with the `incremental-extensions` on) to generate headers

I am a bit overwhelmed right now, are you willing to open a PR with that change 
so we can merge it -- otherwise I could look later this week :(

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


[clang] [flang] [Flang][OpenMP] Add -fopenmp-force-usm option to flang (PR #94359)

2024-06-05 Thread Sergio Afonso via cfe-commits

skatrak wrote:

Thank your for the reviews. Merging now since buildbot failure is unrelated.

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


[clang] b954926 - [Flang][OpenMP] Add -fopenmp-force-usm option to flang (#94359)

2024-06-05 Thread via cfe-commits

Author: Sergio Afonso
Date: 2024-06-05T14:43:58+01:00
New Revision: b9549261e218cee2ad1305fb7272b831799b7bfe

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

LOG: [Flang][OpenMP] Add -fopenmp-force-usm option to flang (#94359)

This patch enables the `-fopenmp-force-usm` option to be passed to the
flang driver, which forwards it to the compiler frontend. This flag,
when set, results in the introduction of the `unified_shared_memory` bit
to the `omp.requires` attribute of the top-level module operation.

This is later combined with any other target device-related REQUIRES
clauses that may have been explicitly set in the compilation unit.

Added: 
flang/test/Lower/OpenMP/force-usm.f90
flang/test/Lower/OpenMP/requires-force-usm.f90

Modified: 
clang/include/clang/Driver/Options.td
clang/lib/Driver/ToolChains/Flang.cpp
flang/include/flang/Frontend/LangOptions.def
flang/include/flang/Tools/CrossToolHelpers.h
flang/lib/Frontend/CompilerInvocation.cpp
flang/lib/Lower/OpenMP/OpenMP.cpp
flang/test/Driver/omp-driver-offload.f90
flang/tools/bbc/bbc.cpp

Removed: 




diff  --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 5ab2d49c7a497..f04c220d6e1db 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3592,7 +3592,7 @@ def fopenmp_offload_mandatory : Flag<["-"], 
"fopenmp-offload-mandatory">, Group<
   HelpText<"Do not create a host fallback if offloading to the device fails.">,
   MarshallingInfoFlag>;
 def fopenmp_force_usm : Flag<["-"], "fopenmp-force-usm">, Group,
-  Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CC1Option]>,
+  Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CC1Option, FlangOption, 
FC1Option]>,
   HelpText<"Force behvaior as if the user specified pragma omp requires 
unified_shared_memory.">,
   MarshallingInfoFlag>;
 def fopenmp_target_jit : Flag<["-"], "fopenmp-target-jit">, Group,

diff  --git a/clang/lib/Driver/ToolChains/Flang.cpp 
b/clang/lib/Driver/ToolChains/Flang.cpp
index 42ca060186fd8..9609a1dc65c09 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -765,6 +765,9 @@ void Flang::ConstructJob(Compilation &C, const JobAction 
&JA,
   CmdArgs.push_back("-fopenmp");
   Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_version_EQ);
 
+  if (Args.hasArg(options::OPT_fopenmp_force_usm))
+CmdArgs.push_back("-fopenmp-force-usm");
+
   // FIXME: Clang supports a whole bunch more flags here.
   break;
 default:

diff  --git a/flang/include/flang/Frontend/LangOptions.def 
b/flang/include/flang/Frontend/LangOptions.def
index 2bf10826120a8..d3e1e972d1519 100644
--- a/flang/include/flang/Frontend/LangOptions.def
+++ b/flang/include/flang/Frontend/LangOptions.def
@@ -42,6 +42,8 @@ LANGOPT(OpenMPVersion, 32, 0)
 LANGOPT(OpenMPIsTargetDevice, 1, false)
 /// Generate OpenMP target code only for GPUs
 LANGOPT(OpenMPIsGPU, 1, false)
+/// Generate OpenMP target code only for GPUs
+LANGOPT(OpenMPForceUSM, 1, false)
 /// Enable debugging in the OpenMP offloading device RTL
 LANGOPT(OpenMPTargetDebug, 32, 0)
 /// Assume work-shared loops do not have more iterations than participating

diff  --git a/flang/include/flang/Tools/CrossToolHelpers.h 
b/flang/include/flang/Tools/CrossToolHelpers.h
index 77b68fc6187fa..1d890fd8e1f6f 100644
--- a/flang/include/flang/Tools/CrossToolHelpers.h
+++ b/flang/include/flang/Tools/CrossToolHelpers.h
@@ -130,16 +130,16 @@ struct OffloadModuleOpts {
   OffloadModuleOpts(uint32_t OpenMPTargetDebug, bool OpenMPTeamSubscription,
   bool OpenMPThreadSubscription, bool OpenMPNoThreadState,
   bool OpenMPNoNestedParallelism, bool OpenMPIsTargetDevice,
-  bool OpenMPIsGPU, uint32_t OpenMPVersion, std::string OMPHostIRFile = {},
-  bool NoGPULib = false)
+  bool OpenMPIsGPU, bool OpenMPForceUSM, uint32_t OpenMPVersion,
+  std::string OMPHostIRFile = {}, bool NoGPULib = false)
   : OpenMPTargetDebug(OpenMPTargetDebug),
 OpenMPTeamSubscription(OpenMPTeamSubscription),
 OpenMPThreadSubscription(OpenMPThreadSubscription),
 OpenMPNoThreadState(OpenMPNoThreadState),
 OpenMPNoNestedParallelism(OpenMPNoNestedParallelism),
 OpenMPIsTargetDevice(OpenMPIsTargetDevice), OpenMPIsGPU(OpenMPIsGPU),
-OpenMPVersion(OpenMPVersion), OMPHostIRFile(OMPHostIRFile),
-NoGPULib(NoGPULib) {}
+OpenMPForceUSM(OpenMPForceUSM), OpenMPVersion(OpenMPVersion),
+OMPHostIRFile(OMPHostIRFile), NoGPULib(NoGPULib) {}
 
   OffloadModuleOpts(Fortran::frontend::LangOptions &Opts)
   : OpenMPTargetDebug(Opts.OpenMPTargetDebug),
@@ -148,8 +148,9 @@ struct OffloadModuleOpts {
 OpenMPNoThre

[clang] [flang] [Flang][OpenMP] Add -fopenmp-force-usm option to flang (PR #94359)

2024-06-05 Thread Sergio Afonso via cfe-commits

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


[clang] [clang-repl] Extend the C support. (PR #89804)

2024-06-05 Thread Haojian Wu via cfe-commits

hokein wrote:

> I want to somehow record this breakage in the form of a test for our future 
> selves when decide to revisit this workaround-looking code.

This is the processed file  
https://gist.github.com/hokein/e4a5881329c3956494afa2de7d350476.

> I am a bit overwhelmed right now, are you willing to open a PR with that 
> change so we can merge it -- otherwise I could look later this week :(

Sure, I will prepare one.

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


[clang] [llvm] [AArch64] Decouple feature dependency expansion. (PR #94279)

2024-06-05 Thread Alexandros Lamprineas via cfe-commits

https://github.com/labrinea updated 
https://github.com/llvm/llvm-project/pull/94279

>From a413428bb0fdcd45b4a251e385b6cc00ff6a0a2c Mon Sep 17 00:00:00 2001
From: Alexandros Lamprineas 
Date: Mon, 3 Jun 2024 19:57:49 +0100
Subject: [PATCH 1/3] [AArch64] Decouple feature dependency expansion.

The dependency expansion step which was introduced by FMV has been
erroneously used for non-FMV features, for example when parsing the
target attribute. The PR #93695 has rectified most of the tests which
were relying on dependency expansion of target features specified on
the -cc1 command line. In this patch I am decoupling the dependency
expansion of features specified on the target attribute from FMV.

To do that first I am expanding FMV dependencies before passing the
list of target features to initFeatureMap(). Similarly when parsing
the target attribute I am reconstructing an ExtensionSet from the
list of target features which was created during the command line
option parsing. The attribute parsing may toggle bits of that
ExtensionSet and at the end it is converted to a list of target
features. Those are passed to initFeatureMap(), which no longer
requires an override.

A side effect of this refactoring is that features specified on the
target_version attribute now supersede the command line options,
which is what should be happening in the first place.
---
 clang/include/clang/AST/ASTContext.h  |   3 -
 clang/lib/AST/ASTContext.cpp  |  53 -
 clang/lib/Basic/Targets/AArch64.cpp   |  99 +
 clang/lib/Basic/Targets/AArch64.h |   4 -
 .../CodeGen/aarch64-cpu-supports-target.c |   2 +-
 .../aarch64-sme-attrs.cpp |   2 +-
 clang/test/CodeGen/aarch64-targetattr.c   |  41 ---
 clang/test/CodeGen/attr-target-version.c  |  46 
 clang/test/Sema/aarch64-neon-target.c |   4 +-
 clang/test/Sema/builtin-cpu-supports.c|   2 +-
 .../llvm/TargetParser/AArch64TargetParser.h   | 104 +++---
 llvm/lib/Target/AArch64/AArch64Features.td|   2 +-
 llvm/lib/TargetParser/AArch64TargetParser.cpp |  53 ++---
 13 files changed, 201 insertions(+), 214 deletions(-)

diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index a1d1d1c51cd41..8bce4812f0d48 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -3203,9 +3203,6 @@ class ASTContext : public RefCountedBase {
   /// valid feature names.
   ParsedTargetAttr filterFunctionTargetAttrs(const TargetAttr *TD) const;
 
-  std::vector
-  filterFunctionTargetVersionAttrs(const TargetVersionAttr *TV) const;
-
   void getFunctionFeatureMap(llvm::StringMap &FeatureMap,
  const FunctionDecl *) const;
   void getFunctionFeatureMap(llvm::StringMap &FeatureMap,
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 73d3b152c49f1..6b7cfbe48796a 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -87,6 +87,7 @@
 #include "llvm/Support/MD5.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/TargetParser/AArch64TargetParser.h"
 #include "llvm/TargetParser/Triple.h"
 #include 
 #include 
@@ -13663,17 +13664,18 @@ QualType 
ASTContext::getCorrespondingSignedFixedPointType(QualType Ty) const {
   }
 }
 
-std::vector ASTContext::filterFunctionTargetVersionAttrs(
-const TargetVersionAttr *TV) const {
-  assert(TV != nullptr);
-  llvm::SmallVector Feats;
-  std::vector ResFeats;
-  TV->getFeatures(Feats);
-  for (auto &Feature : Feats)
-if (Target->validateCpuSupports(Feature.str()))
-  // Use '?' to mark features that came from TargetVersion.
-  ResFeats.push_back("?" + Feature.str());
-  return ResFeats;
+// Given a list of FMV features, add each of their backend features to the 
list.
+static void
+getFMVBackendFeaturesFor(const llvm::SmallVectorImpl 
&FMVFeatStrings,
+ std::vector &BackendFeats) {
+  for (StringRef F : FMVFeatStrings) {
+if (auto FMVExt = llvm::AArch64::parseArchExtension(F)) {
+  SmallVector Feats;
+  FMVExt->DependentFeatures.split(Feats, ',', -1, false);
+  for (StringRef F : Feats)
+BackendFeats.push_back(F.str());
+}
+  }
 }
 
 ParsedTargetAttr
@@ -13708,10 +13710,12 @@ void 
ASTContext::getFunctionFeatureMap(llvm::StringMap &FeatureMap,
 
 // Make a copy of the features as passed on the command line into the
 // beginning of the additional features from the function to override.
-ParsedAttr.Features.insert(
-ParsedAttr.Features.begin(),
-Target->getTargetOpts().FeaturesAsWritten.begin(),
-Target->getTargetOpts().FeaturesAsWritten.end());
+// AArch64 handles command line option features in parseTargetAttr().
+if (!Target->getTriple().isAArch64())
+  ParsedAttr.Features.insert(
+  ParsedAttr.Features.begin(),
+ 

[clang] Fix clang reject valid C++ code after d999ce0302f06d250f6d496b56a5a5f (PR #94471)

2024-06-05 Thread Haojian Wu via cfe-commits

https://github.com/hokein created 
https://github.com/llvm/llvm-project/pull/94471



The incremental processing mode doesn't seem to work well for C++.

>From 8457c4aa1758d10188da5978d30d2d1ed505e01e Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Wed, 5 Jun 2024 15:46:56 +0200
Subject: [PATCH] Fix clang reject valid C++ code after
 d999ce0302f06d250f6d496b56a5a5f2dc331e61

The incremental processing mode doesn't seem to work well for C++.
---
 clang/lib/Sema/SemaDecl.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index a6734ef8c30aa..4b9b735f1cfb4 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2288,7 +2288,8 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
 // Partial translation units that are created in incremental processing 
must
 // not clean up the IdResolver because PTUs should take into account the
 // declarations that came from previous PTUs.
-if (!PP.isIncrementalProcessingEnabled() || getLangOpts().ObjC)
+if (!PP.isIncrementalProcessingEnabled() || getLangOpts().ObjC ||
+getLangOpts().CPlusPlus)
   IdResolver.RemoveDecl(D);
 
 // Warn on it if we are shadowing a declaration.

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


[clang] Fix clang reject valid C++ code after d999ce0302f06d250f6d496b56a5a5f (PR #94471)

2024-06-05 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Haojian Wu (hokein)


Changes



The incremental processing mode doesn't seem to work well for C++.

---
Full diff: https://github.com/llvm/llvm-project/pull/94471.diff


1 Files Affected:

- (modified) clang/lib/Sema/SemaDecl.cpp (+2-1) 


``diff
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index a6734ef8c30aa..4b9b735f1cfb4 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2288,7 +2288,8 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
 // Partial translation units that are created in incremental processing 
must
 // not clean up the IdResolver because PTUs should take into account the
 // declarations that came from previous PTUs.
-if (!PP.isIncrementalProcessingEnabled() || getLangOpts().ObjC)
+if (!PP.isIncrementalProcessingEnabled() || getLangOpts().ObjC ||
+getLangOpts().CPlusPlus)
   IdResolver.RemoveDecl(D);
 
 // Warn on it if we are shadowing a declaration.

``




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


[clang] [libc] [llvm] [AMDGPU] Implement variadic functions by IR lowering (PR #93362)

2024-06-05 Thread Pierre van Houtryve via cfe-commits


@@ -0,0 +1,1037 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a variadic function into a va_list
+// and fix up the call sites. The majority of the pass is target independent.
+// The exceptions are the va_list type itself and the rules for where to store
+// variables in memory such that va_arg can iterate over them given a va_list.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. That packing is
+// exactly what is done by va_start. Further, the transform from ... to va_list
+// replaced va_start with an operation to copy a va_list from the new argument,
+// which is exactly a va_copy. This is useful for reducing target-dependence.
+//
+// A va_list instance is a forward iterator, where the primary operation va_arg
+// is dereference-then-increment. This interface forces significant convergent
+// evolution between target specific implementations. The variation in runtime
+// data layout is limited to that representable by the iterator, parameterised
+// by the type passed to the va_arg instruction.
+//
+// Therefore the majority of the target specific subtlety is packing arguments
+// into a stack allocated buffer such that a va_list can be initialised with it
+// and the va_arg expansion for the target will find the arguments at runtime.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+// There is one "clever" invariant in use. va_start intrinsics that are not
+// within a varidic functions are an error in the IR verifier. When this
+// transform moves blocks from a variadic function into a fixed arity one, it
+// moves va_start intrinsics along with everything else. That means that the
+// va_start intrinsics that need to be rewritten to use the trailing argument
+// are exactly those that are in non-variadic functions so no further state
+// is needed to distinguish those that need to be rewritten.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+namespace {
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::Unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::Unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::Disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::Optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::Lowering, "lowering",
+  "Change variadic calling convention")));
+
+bool commandLineOverride() {
+  return ExpandVariadicsModeOption != ExpandVariadicsMode::Unspecified;
+}
+
+// Instances of this class encapsulate the target-dependant behaviour as a
+// function of triple. Implementing a new ABI is adding a case to the switch
+// in create(llvm::Triple) at the end of this file.
+class VariadicABIInfo {
+protected:
+  VariadicABIInfo() {}
+
+public:
+  static std::unique_ptr create(llvm::Triple const &Triple);
+
+  // Allow overriding whether the pass runs on a per-target basis
+  virtual bool enableForTarget() = 0;
+
+  

[clang] [libc] [llvm] [AMDGPU] Implement variadic functions by IR lowering (PR #93362)

2024-06-05 Thread Pierre van Houtryve via cfe-commits


@@ -0,0 +1,1037 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a variadic function into a va_list
+// and fix up the call sites. The majority of the pass is target independent.
+// The exceptions are the va_list type itself and the rules for where to store
+// variables in memory such that va_arg can iterate over them given a va_list.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. That packing is
+// exactly what is done by va_start. Further, the transform from ... to va_list
+// replaced va_start with an operation to copy a va_list from the new argument,
+// which is exactly a va_copy. This is useful for reducing target-dependence.
+//
+// A va_list instance is a forward iterator, where the primary operation va_arg
+// is dereference-then-increment. This interface forces significant convergent
+// evolution between target specific implementations. The variation in runtime
+// data layout is limited to that representable by the iterator, parameterised
+// by the type passed to the va_arg instruction.
+//
+// Therefore the majority of the target specific subtlety is packing arguments
+// into a stack allocated buffer such that a va_list can be initialised with it
+// and the va_arg expansion for the target will find the arguments at runtime.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+// There is one "clever" invariant in use. va_start intrinsics that are not
+// within a varidic functions are an error in the IR verifier. When this
+// transform moves blocks from a variadic function into a fixed arity one, it
+// moves va_start intrinsics along with everything else. That means that the
+// va_start intrinsics that need to be rewritten to use the trailing argument
+// are exactly those that are in non-variadic functions so no further state
+// is needed to distinguish those that need to be rewritten.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+namespace {
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::Unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::Unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::Disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::Optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::Lowering, "lowering",
+  "Change variadic calling convention")));
+
+bool commandLineOverride() {
+  return ExpandVariadicsModeOption != ExpandVariadicsMode::Unspecified;
+}
+
+// Instances of this class encapsulate the target-dependant behaviour as a
+// function of triple. Implementing a new ABI is adding a case to the switch
+// in create(llvm::Triple) at the end of this file.
+class VariadicABIInfo {
+protected:
+  VariadicABIInfo() {}

Pierre-vh wrote:

```suggestion
  VariadicABIInfo() = default;
```


https://github.com/llvm/llvm-project/pull/93362
___
cfe-

[clang] [libc] [llvm] [AMDGPU] Implement variadic functions by IR lowering (PR #93362)

2024-06-05 Thread Pierre van Houtryve via cfe-commits


@@ -0,0 +1,1037 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a variadic function into a va_list
+// and fix up the call sites. The majority of the pass is target independent.
+// The exceptions are the va_list type itself and the rules for where to store
+// variables in memory such that va_arg can iterate over them given a va_list.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. That packing is
+// exactly what is done by va_start. Further, the transform from ... to va_list
+// replaced va_start with an operation to copy a va_list from the new argument,
+// which is exactly a va_copy. This is useful for reducing target-dependence.
+//
+// A va_list instance is a forward iterator, where the primary operation va_arg
+// is dereference-then-increment. This interface forces significant convergent
+// evolution between target specific implementations. The variation in runtime
+// data layout is limited to that representable by the iterator, parameterised
+// by the type passed to the va_arg instruction.
+//
+// Therefore the majority of the target specific subtlety is packing arguments
+// into a stack allocated buffer such that a va_list can be initialised with it
+// and the va_arg expansion for the target will find the arguments at runtime.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+// There is one "clever" invariant in use. va_start intrinsics that are not
+// within a varidic functions are an error in the IR verifier. When this
+// transform moves blocks from a variadic function into a fixed arity one, it
+// moves va_start intrinsics along with everything else. That means that the
+// va_start intrinsics that need to be rewritten to use the trailing argument
+// are exactly those that are in non-variadic functions so no further state
+// is needed to distinguish those that need to be rewritten.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+namespace {
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::Unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::Unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::Disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::Optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::Lowering, "lowering",
+  "Change variadic calling convention")));
+
+bool commandLineOverride() {
+  return ExpandVariadicsModeOption != ExpandVariadicsMode::Unspecified;
+}
+
+// Instances of this class encapsulate the target-dependant behaviour as a
+// function of triple. Implementing a new ABI is adding a case to the switch
+// in create(llvm::Triple) at the end of this file.
+class VariadicABIInfo {
+protected:
+  VariadicABIInfo() {}
+
+public:
+  static std::unique_ptr create(llvm::Triple const &Triple);
+
+  // Allow overriding whether the pass runs on a per-target basis
+  virtual bool enableForTarget() = 0;
+
+  

[clang] [libc] [llvm] [AMDGPU] Implement variadic functions by IR lowering (PR #93362)

2024-06-05 Thread Pierre van Houtryve via cfe-commits


@@ -0,0 +1,1037 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a variadic function into a va_list
+// and fix up the call sites. The majority of the pass is target independent.
+// The exceptions are the va_list type itself and the rules for where to store
+// variables in memory such that va_arg can iterate over them given a va_list.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. That packing is
+// exactly what is done by va_start. Further, the transform from ... to va_list
+// replaced va_start with an operation to copy a va_list from the new argument,
+// which is exactly a va_copy. This is useful for reducing target-dependence.
+//
+// A va_list instance is a forward iterator, where the primary operation va_arg
+// is dereference-then-increment. This interface forces significant convergent
+// evolution between target specific implementations. The variation in runtime
+// data layout is limited to that representable by the iterator, parameterised
+// by the type passed to the va_arg instruction.
+//
+// Therefore the majority of the target specific subtlety is packing arguments
+// into a stack allocated buffer such that a va_list can be initialised with it
+// and the va_arg expansion for the target will find the arguments at runtime.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+// There is one "clever" invariant in use. va_start intrinsics that are not
+// within a varidic functions are an error in the IR verifier. When this
+// transform moves blocks from a variadic function into a fixed arity one, it
+// moves va_start intrinsics along with everything else. That means that the
+// va_start intrinsics that need to be rewritten to use the trailing argument
+// are exactly those that are in non-variadic functions so no further state
+// is needed to distinguish those that need to be rewritten.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+namespace {
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::Unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::Unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::Disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::Optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::Lowering, "lowering",
+  "Change variadic calling convention")));
+
+bool commandLineOverride() {
+  return ExpandVariadicsModeOption != ExpandVariadicsMode::Unspecified;
+}
+
+// Instances of this class encapsulate the target-dependant behaviour as a
+// function of triple. Implementing a new ABI is adding a case to the switch
+// in create(llvm::Triple) at the end of this file.
+class VariadicABIInfo {
+protected:
+  VariadicABIInfo() {}
+
+public:
+  static std::unique_ptr create(llvm::Triple const &Triple);
+
+  // Allow overriding whether the pass runs on a per-target basis
+  virtual bool enableForTarget() = 0;
+
+  

[clang] [libc] [llvm] [AMDGPU] Implement variadic functions by IR lowering (PR #93362)

2024-06-05 Thread Pierre van Houtryve via cfe-commits


@@ -0,0 +1,1037 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a variadic function into a va_list
+// and fix up the call sites. The majority of the pass is target independent.
+// The exceptions are the va_list type itself and the rules for where to store
+// variables in memory such that va_arg can iterate over them given a va_list.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. That packing is
+// exactly what is done by va_start. Further, the transform from ... to va_list
+// replaced va_start with an operation to copy a va_list from the new argument,
+// which is exactly a va_copy. This is useful for reducing target-dependence.
+//
+// A va_list instance is a forward iterator, where the primary operation va_arg
+// is dereference-then-increment. This interface forces significant convergent
+// evolution between target specific implementations. The variation in runtime
+// data layout is limited to that representable by the iterator, parameterised
+// by the type passed to the va_arg instruction.
+//
+// Therefore the majority of the target specific subtlety is packing arguments
+// into a stack allocated buffer such that a va_list can be initialised with it
+// and the va_arg expansion for the target will find the arguments at runtime.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+// There is one "clever" invariant in use. va_start intrinsics that are not
+// within a varidic functions are an error in the IR verifier. When this
+// transform moves blocks from a variadic function into a fixed arity one, it
+// moves va_start intrinsics along with everything else. That means that the
+// va_start intrinsics that need to be rewritten to use the trailing argument
+// are exactly those that are in non-variadic functions so no further state
+// is needed to distinguish those that need to be rewritten.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+namespace {
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::Unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::Unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::Disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::Optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::Lowering, "lowering",
+  "Change variadic calling convention")));
+
+bool commandLineOverride() {
+  return ExpandVariadicsModeOption != ExpandVariadicsMode::Unspecified;
+}
+
+// Instances of this class encapsulate the target-dependant behaviour as a
+// function of triple. Implementing a new ABI is adding a case to the switch
+// in create(llvm::Triple) at the end of this file.
+class VariadicABIInfo {
+protected:
+  VariadicABIInfo() {}
+
+public:
+  static std::unique_ptr create(llvm::Triple const &Triple);
+
+  // Allow overriding whether the pass runs on a per-target basis
+  virtual bool enableForTarget() = 0;
+
+  

[clang] [libc] [llvm] [AMDGPU] Implement variadic functions by IR lowering (PR #93362)

2024-06-05 Thread Pierre van Houtryve via cfe-commits


@@ -0,0 +1,1037 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a variadic function into a va_list
+// and fix up the call sites. The majority of the pass is target independent.
+// The exceptions are the va_list type itself and the rules for where to store
+// variables in memory such that va_arg can iterate over them given a va_list.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. That packing is
+// exactly what is done by va_start. Further, the transform from ... to va_list
+// replaced va_start with an operation to copy a va_list from the new argument,
+// which is exactly a va_copy. This is useful for reducing target-dependence.
+//
+// A va_list instance is a forward iterator, where the primary operation va_arg
+// is dereference-then-increment. This interface forces significant convergent
+// evolution between target specific implementations. The variation in runtime
+// data layout is limited to that representable by the iterator, parameterised
+// by the type passed to the va_arg instruction.
+//
+// Therefore the majority of the target specific subtlety is packing arguments
+// into a stack allocated buffer such that a va_list can be initialised with it
+// and the va_arg expansion for the target will find the arguments at runtime.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+// There is one "clever" invariant in use. va_start intrinsics that are not
+// within a varidic functions are an error in the IR verifier. When this
+// transform moves blocks from a variadic function into a fixed arity one, it
+// moves va_start intrinsics along with everything else. That means that the
+// va_start intrinsics that need to be rewritten to use the trailing argument
+// are exactly those that are in non-variadic functions so no further state
+// is needed to distinguish those that need to be rewritten.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+namespace {
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::Unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::Unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::Disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::Optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::Lowering, "lowering",
+  "Change variadic calling convention")));
+
+bool commandLineOverride() {
+  return ExpandVariadicsModeOption != ExpandVariadicsMode::Unspecified;
+}
+
+// Instances of this class encapsulate the target-dependant behaviour as a
+// function of triple. Implementing a new ABI is adding a case to the switch
+// in create(llvm::Triple) at the end of this file.
+class VariadicABIInfo {
+protected:
+  VariadicABIInfo() {}
+
+public:
+  static std::unique_ptr create(llvm::Triple const &Triple);

Pierre-vh wrote:

```suggestion
  static std::unique_ptr create(const llvm::Triple &Triple);
```

[clang] [libc] [llvm] [AMDGPU] Implement variadic functions by IR lowering (PR #93362)

2024-06-05 Thread Pierre van Houtryve via cfe-commits


@@ -0,0 +1,1037 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a variadic function into a va_list
+// and fix up the call sites. The majority of the pass is target independent.
+// The exceptions are the va_list type itself and the rules for where to store
+// variables in memory such that va_arg can iterate over them given a va_list.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. That packing is
+// exactly what is done by va_start. Further, the transform from ... to va_list
+// replaced va_start with an operation to copy a va_list from the new argument,
+// which is exactly a va_copy. This is useful for reducing target-dependence.
+//
+// A va_list instance is a forward iterator, where the primary operation va_arg
+// is dereference-then-increment. This interface forces significant convergent
+// evolution between target specific implementations. The variation in runtime
+// data layout is limited to that representable by the iterator, parameterised
+// by the type passed to the va_arg instruction.
+//
+// Therefore the majority of the target specific subtlety is packing arguments
+// into a stack allocated buffer such that a va_list can be initialised with it
+// and the va_arg expansion for the target will find the arguments at runtime.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+// There is one "clever" invariant in use. va_start intrinsics that are not
+// within a varidic functions are an error in the IR verifier. When this
+// transform moves blocks from a variadic function into a fixed arity one, it
+// moves va_start intrinsics along with everything else. That means that the
+// va_start intrinsics that need to be rewritten to use the trailing argument
+// are exactly those that are in non-variadic functions so no further state
+// is needed to distinguish those that need to be rewritten.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+namespace {
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::Unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::Unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::Disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::Optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::Lowering, "lowering",
+  "Change variadic calling convention")));
+
+bool commandLineOverride() {
+  return ExpandVariadicsModeOption != ExpandVariadicsMode::Unspecified;
+}
+
+// Instances of this class encapsulate the target-dependant behaviour as a
+// function of triple. Implementing a new ABI is adding a case to the switch
+// in create(llvm::Triple) at the end of this file.
+class VariadicABIInfo {
+protected:
+  VariadicABIInfo() {}
+
+public:
+  static std::unique_ptr create(llvm::Triple const &Triple);
+
+  // Allow overriding whether the pass runs on a per-target basis
+  virtual bool enableForTarget() = 0;
+
+  

[clang] [libc] [llvm] [AMDGPU] Implement variadic functions by IR lowering (PR #93362)

2024-06-05 Thread Pierre van Houtryve via cfe-commits


@@ -0,0 +1,1037 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a variadic function into a va_list
+// and fix up the call sites. The majority of the pass is target independent.
+// The exceptions are the va_list type itself and the rules for where to store
+// variables in memory such that va_arg can iterate over them given a va_list.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. That packing is
+// exactly what is done by va_start. Further, the transform from ... to va_list
+// replaced va_start with an operation to copy a va_list from the new argument,
+// which is exactly a va_copy. This is useful for reducing target-dependence.
+//
+// A va_list instance is a forward iterator, where the primary operation va_arg
+// is dereference-then-increment. This interface forces significant convergent
+// evolution between target specific implementations. The variation in runtime
+// data layout is limited to that representable by the iterator, parameterised
+// by the type passed to the va_arg instruction.
+//
+// Therefore the majority of the target specific subtlety is packing arguments
+// into a stack allocated buffer such that a va_list can be initialised with it
+// and the va_arg expansion for the target will find the arguments at runtime.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+// There is one "clever" invariant in use. va_start intrinsics that are not
+// within a varidic functions are an error in the IR verifier. When this
+// transform moves blocks from a variadic function into a fixed arity one, it
+// moves va_start intrinsics along with everything else. That means that the
+// va_start intrinsics that need to be rewritten to use the trailing argument
+// are exactly those that are in non-variadic functions so no further state
+// is needed to distinguish those that need to be rewritten.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+namespace {
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::Unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::Unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::Disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::Optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::Lowering, "lowering",
+  "Change variadic calling convention")));
+
+bool commandLineOverride() {
+  return ExpandVariadicsModeOption != ExpandVariadicsMode::Unspecified;
+}
+
+// Instances of this class encapsulate the target-dependant behaviour as a
+// function of triple. Implementing a new ABI is adding a case to the switch
+// in create(llvm::Triple) at the end of this file.
+class VariadicABIInfo {
+protected:
+  VariadicABIInfo() {}
+
+public:
+  static std::unique_ptr create(llvm::Triple const &Triple);
+
+  // Allow overriding whether the pass runs on a per-target basis
+  virtual bool enableForTarget() = 0;
+
+  

[clang] [libc] [llvm] [AMDGPU] Implement variadic functions by IR lowering (PR #93362)

2024-06-05 Thread Pierre van Houtryve via cfe-commits


@@ -0,0 +1,1037 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a variadic function into a va_list
+// and fix up the call sites. The majority of the pass is target independent.
+// The exceptions are the va_list type itself and the rules for where to store
+// variables in memory such that va_arg can iterate over them given a va_list.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. That packing is
+// exactly what is done by va_start. Further, the transform from ... to va_list
+// replaced va_start with an operation to copy a va_list from the new argument,
+// which is exactly a va_copy. This is useful for reducing target-dependence.
+//
+// A va_list instance is a forward iterator, where the primary operation va_arg
+// is dereference-then-increment. This interface forces significant convergent
+// evolution between target specific implementations. The variation in runtime
+// data layout is limited to that representable by the iterator, parameterised
+// by the type passed to the va_arg instruction.
+//
+// Therefore the majority of the target specific subtlety is packing arguments
+// into a stack allocated buffer such that a va_list can be initialised with it
+// and the va_arg expansion for the target will find the arguments at runtime.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+// There is one "clever" invariant in use. va_start intrinsics that are not
+// within a varidic functions are an error in the IR verifier. When this
+// transform moves blocks from a variadic function into a fixed arity one, it
+// moves va_start intrinsics along with everything else. That means that the
+// va_start intrinsics that need to be rewritten to use the trailing argument
+// are exactly those that are in non-variadic functions so no further state
+// is needed to distinguish those that need to be rewritten.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+namespace {
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::Unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::Unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::Disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::Optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::Lowering, "lowering",
+  "Change variadic calling convention")));
+
+bool commandLineOverride() {
+  return ExpandVariadicsModeOption != ExpandVariadicsMode::Unspecified;
+}
+
+// Instances of this class encapsulate the target-dependant behaviour as a
+// function of triple. Implementing a new ABI is adding a case to the switch
+// in create(llvm::Triple) at the end of this file.
+class VariadicABIInfo {
+protected:
+  VariadicABIInfo() {}
+
+public:
+  static std::unique_ptr create(llvm::Triple const &Triple);
+
+  // Allow overriding whether the pass runs on a per-target basis
+  virtual bool enableForTarget() = 0;
+
+  

[clang] [libc] [llvm] [AMDGPU] Implement variadic functions by IR lowering (PR #93362)

2024-06-05 Thread Pierre van Houtryve via cfe-commits


@@ -0,0 +1,1037 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a variadic function into a va_list
+// and fix up the call sites. The majority of the pass is target independent.
+// The exceptions are the va_list type itself and the rules for where to store
+// variables in memory such that va_arg can iterate over them given a va_list.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. That packing is
+// exactly what is done by va_start. Further, the transform from ... to va_list
+// replaced va_start with an operation to copy a va_list from the new argument,
+// which is exactly a va_copy. This is useful for reducing target-dependence.
+//
+// A va_list instance is a forward iterator, where the primary operation va_arg
+// is dereference-then-increment. This interface forces significant convergent
+// evolution between target specific implementations. The variation in runtime
+// data layout is limited to that representable by the iterator, parameterised
+// by the type passed to the va_arg instruction.
+//
+// Therefore the majority of the target specific subtlety is packing arguments
+// into a stack allocated buffer such that a va_list can be initialised with it
+// and the va_arg expansion for the target will find the arguments at runtime.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+// There is one "clever" invariant in use. va_start intrinsics that are not
+// within a varidic functions are an error in the IR verifier. When this
+// transform moves blocks from a variadic function into a fixed arity one, it
+// moves va_start intrinsics along with everything else. That means that the
+// va_start intrinsics that need to be rewritten to use the trailing argument
+// are exactly those that are in non-variadic functions so no further state
+// is needed to distinguish those that need to be rewritten.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+namespace {
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::Unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::Unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::Disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::Optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::Lowering, "lowering",
+  "Change variadic calling convention")));
+
+bool commandLineOverride() {
+  return ExpandVariadicsModeOption != ExpandVariadicsMode::Unspecified;
+}
+
+// Instances of this class encapsulate the target-dependant behaviour as a
+// function of triple. Implementing a new ABI is adding a case to the switch
+// in create(llvm::Triple) at the end of this file.
+class VariadicABIInfo {
+protected:
+  VariadicABIInfo() {}
+
+public:
+  static std::unique_ptr create(llvm::Triple const &Triple);
+
+  // Allow overriding whether the pass runs on a per-target basis
+  virtual bool enableForTarget() = 0;
+
+  

[clang] [libc] [llvm] [AMDGPU] Implement variadic functions by IR lowering (PR #93362)

2024-06-05 Thread Pierre van Houtryve via cfe-commits


@@ -0,0 +1,1037 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a variadic function into a va_list
+// and fix up the call sites. The majority of the pass is target independent.
+// The exceptions are the va_list type itself and the rules for where to store
+// variables in memory such that va_arg can iterate over them given a va_list.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. That packing is
+// exactly what is done by va_start. Further, the transform from ... to va_list
+// replaced va_start with an operation to copy a va_list from the new argument,
+// which is exactly a va_copy. This is useful for reducing target-dependence.
+//
+// A va_list instance is a forward iterator, where the primary operation va_arg
+// is dereference-then-increment. This interface forces significant convergent
+// evolution between target specific implementations. The variation in runtime
+// data layout is limited to that representable by the iterator, parameterised
+// by the type passed to the va_arg instruction.
+//
+// Therefore the majority of the target specific subtlety is packing arguments
+// into a stack allocated buffer such that a va_list can be initialised with it
+// and the va_arg expansion for the target will find the arguments at runtime.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+// There is one "clever" invariant in use. va_start intrinsics that are not
+// within a varidic functions are an error in the IR verifier. When this
+// transform moves blocks from a variadic function into a fixed arity one, it
+// moves va_start intrinsics along with everything else. That means that the
+// va_start intrinsics that need to be rewritten to use the trailing argument
+// are exactly those that are in non-variadic functions so no further state
+// is needed to distinguish those that need to be rewritten.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+namespace {
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::Unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::Unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::Disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::Optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::Lowering, "lowering",
+  "Change variadic calling convention")));
+
+bool commandLineOverride() {
+  return ExpandVariadicsModeOption != ExpandVariadicsMode::Unspecified;
+}
+
+// Instances of this class encapsulate the target-dependant behaviour as a
+// function of triple. Implementing a new ABI is adding a case to the switch
+// in create(llvm::Triple) at the end of this file.
+class VariadicABIInfo {
+protected:
+  VariadicABIInfo() {}
+
+public:
+  static std::unique_ptr create(llvm::Triple const &Triple);
+
+  // Allow overriding whether the pass runs on a per-target basis
+  virtual bool enableForTarget() = 0;
+
+  

[clang] [libc] [llvm] [AMDGPU] Implement variadic functions by IR lowering (PR #93362)

2024-06-05 Thread Pierre van Houtryve via cfe-commits


@@ -0,0 +1,1037 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a variadic function into a va_list
+// and fix up the call sites. The majority of the pass is target independent.
+// The exceptions are the va_list type itself and the rules for where to store
+// variables in memory such that va_arg can iterate over them given a va_list.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. That packing is
+// exactly what is done by va_start. Further, the transform from ... to va_list
+// replaced va_start with an operation to copy a va_list from the new argument,
+// which is exactly a va_copy. This is useful for reducing target-dependence.
+//
+// A va_list instance is a forward iterator, where the primary operation va_arg
+// is dereference-then-increment. This interface forces significant convergent
+// evolution between target specific implementations. The variation in runtime
+// data layout is limited to that representable by the iterator, parameterised
+// by the type passed to the va_arg instruction.
+//
+// Therefore the majority of the target specific subtlety is packing arguments
+// into a stack allocated buffer such that a va_list can be initialised with it
+// and the va_arg expansion for the target will find the arguments at runtime.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+// There is one "clever" invariant in use. va_start intrinsics that are not
+// within a varidic functions are an error in the IR verifier. When this
+// transform moves blocks from a variadic function into a fixed arity one, it
+// moves va_start intrinsics along with everything else. That means that the
+// va_start intrinsics that need to be rewritten to use the trailing argument
+// are exactly those that are in non-variadic functions so no further state
+// is needed to distinguish those that need to be rewritten.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+namespace {
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::Unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::Unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::Disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::Optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::Lowering, "lowering",
+  "Change variadic calling convention")));
+
+bool commandLineOverride() {
+  return ExpandVariadicsModeOption != ExpandVariadicsMode::Unspecified;
+}
+
+// Instances of this class encapsulate the target-dependant behaviour as a
+// function of triple. Implementing a new ABI is adding a case to the switch
+// in create(llvm::Triple) at the end of this file.
+class VariadicABIInfo {
+protected:
+  VariadicABIInfo() {}
+
+public:
+  static std::unique_ptr create(llvm::Triple const &Triple);
+
+  // Allow overriding whether the pass runs on a per-target basis
+  virtual bool enableForTarget() = 0;
+
+  

[clang] [libc] [llvm] [AMDGPU] Implement variadic functions by IR lowering (PR #93362)

2024-06-05 Thread Pierre van Houtryve via cfe-commits


@@ -0,0 +1,1037 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a variadic function into a va_list
+// and fix up the call sites. The majority of the pass is target independent.
+// The exceptions are the va_list type itself and the rules for where to store
+// variables in memory such that va_arg can iterate over them given a va_list.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. That packing is
+// exactly what is done by va_start. Further, the transform from ... to va_list
+// replaced va_start with an operation to copy a va_list from the new argument,
+// which is exactly a va_copy. This is useful for reducing target-dependence.
+//
+// A va_list instance is a forward iterator, where the primary operation va_arg
+// is dereference-then-increment. This interface forces significant convergent
+// evolution between target specific implementations. The variation in runtime
+// data layout is limited to that representable by the iterator, parameterised
+// by the type passed to the va_arg instruction.
+//
+// Therefore the majority of the target specific subtlety is packing arguments
+// into a stack allocated buffer such that a va_list can be initialised with it
+// and the va_arg expansion for the target will find the arguments at runtime.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+// There is one "clever" invariant in use. va_start intrinsics that are not
+// within a varidic functions are an error in the IR verifier. When this
+// transform moves blocks from a variadic function into a fixed arity one, it
+// moves va_start intrinsics along with everything else. That means that the
+// va_start intrinsics that need to be rewritten to use the trailing argument
+// are exactly those that are in non-variadic functions so no further state
+// is needed to distinguish those that need to be rewritten.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+namespace {
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::Unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::Unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::Disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::Optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::Lowering, "lowering",
+  "Change variadic calling convention")));
+
+bool commandLineOverride() {
+  return ExpandVariadicsModeOption != ExpandVariadicsMode::Unspecified;
+}
+
+// Instances of this class encapsulate the target-dependant behaviour as a
+// function of triple. Implementing a new ABI is adding a case to the switch
+// in create(llvm::Triple) at the end of this file.
+class VariadicABIInfo {
+protected:
+  VariadicABIInfo() {}
+
+public:
+  static std::unique_ptr create(llvm::Triple const &Triple);
+
+  // Allow overriding whether the pass runs on a per-target basis
+  virtual bool enableForTarget() = 0;
+
+  

[clang] [libc] [llvm] [AMDGPU] Implement variadic functions by IR lowering (PR #93362)

2024-06-05 Thread Pierre van Houtryve via cfe-commits


@@ -0,0 +1,1037 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a variadic function into a va_list
+// and fix up the call sites. The majority of the pass is target independent.
+// The exceptions are the va_list type itself and the rules for where to store
+// variables in memory such that va_arg can iterate over them given a va_list.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. That packing is
+// exactly what is done by va_start. Further, the transform from ... to va_list
+// replaced va_start with an operation to copy a va_list from the new argument,
+// which is exactly a va_copy. This is useful for reducing target-dependence.
+//
+// A va_list instance is a forward iterator, where the primary operation va_arg
+// is dereference-then-increment. This interface forces significant convergent
+// evolution between target specific implementations. The variation in runtime
+// data layout is limited to that representable by the iterator, parameterised
+// by the type passed to the va_arg instruction.
+//
+// Therefore the majority of the target specific subtlety is packing arguments
+// into a stack allocated buffer such that a va_list can be initialised with it
+// and the va_arg expansion for the target will find the arguments at runtime.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+// There is one "clever" invariant in use. va_start intrinsics that are not
+// within a varidic functions are an error in the IR verifier. When this
+// transform moves blocks from a variadic function into a fixed arity one, it
+// moves va_start intrinsics along with everything else. That means that the
+// va_start intrinsics that need to be rewritten to use the trailing argument
+// are exactly those that are in non-variadic functions so no further state
+// is needed to distinguish those that need to be rewritten.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+namespace {
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::Unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::Unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::Disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::Optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::Lowering, "lowering",
+  "Change variadic calling convention")));
+
+bool commandLineOverride() {
+  return ExpandVariadicsModeOption != ExpandVariadicsMode::Unspecified;
+}
+
+// Instances of this class encapsulate the target-dependant behaviour as a
+// function of triple. Implementing a new ABI is adding a case to the switch
+// in create(llvm::Triple) at the end of this file.
+class VariadicABIInfo {
+protected:
+  VariadicABIInfo() {}
+
+public:
+  static std::unique_ptr create(llvm::Triple const &Triple);
+
+  // Allow overriding whether the pass runs on a per-target basis
+  virtual bool enableForTarget() = 0;
+
+  

[clang] [libc] [llvm] [AMDGPU] Implement variadic functions by IR lowering (PR #93362)

2024-06-05 Thread Pierre van Houtryve via cfe-commits


@@ -0,0 +1,1037 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a variadic function into a va_list
+// and fix up the call sites. The majority of the pass is target independent.
+// The exceptions are the va_list type itself and the rules for where to store
+// variables in memory such that va_arg can iterate over them given a va_list.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. That packing is
+// exactly what is done by va_start. Further, the transform from ... to va_list
+// replaced va_start with an operation to copy a va_list from the new argument,
+// which is exactly a va_copy. This is useful for reducing target-dependence.
+//
+// A va_list instance is a forward iterator, where the primary operation va_arg
+// is dereference-then-increment. This interface forces significant convergent
+// evolution between target specific implementations. The variation in runtime
+// data layout is limited to that representable by the iterator, parameterised
+// by the type passed to the va_arg instruction.
+//
+// Therefore the majority of the target specific subtlety is packing arguments
+// into a stack allocated buffer such that a va_list can be initialised with it
+// and the va_arg expansion for the target will find the arguments at runtime.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+// There is one "clever" invariant in use. va_start intrinsics that are not
+// within a varidic functions are an error in the IR verifier. When this
+// transform moves blocks from a variadic function into a fixed arity one, it
+// moves va_start intrinsics along with everything else. That means that the
+// va_start intrinsics that need to be rewritten to use the trailing argument
+// are exactly those that are in non-variadic functions so no further state
+// is needed to distinguish those that need to be rewritten.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+namespace {
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::Unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::Unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::Disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::Optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::Lowering, "lowering",
+  "Change variadic calling convention")));
+
+bool commandLineOverride() {
+  return ExpandVariadicsModeOption != ExpandVariadicsMode::Unspecified;
+}
+
+// Instances of this class encapsulate the target-dependant behaviour as a
+// function of triple. Implementing a new ABI is adding a case to the switch
+// in create(llvm::Triple) at the end of this file.
+class VariadicABIInfo {
+protected:
+  VariadicABIInfo() {}
+
+public:
+  static std::unique_ptr create(llvm::Triple const &Triple);
+
+  // Allow overriding whether the pass runs on a per-target basis
+  virtual bool enableForTarget() = 0;
+
+  

[clang] [libc] [llvm] [AMDGPU] Implement variadic functions by IR lowering (PR #93362)

2024-06-05 Thread Pierre van Houtryve via cfe-commits


@@ -0,0 +1,1037 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a variadic function into a va_list
+// and fix up the call sites. The majority of the pass is target independent.
+// The exceptions are the va_list type itself and the rules for where to store
+// variables in memory such that va_arg can iterate over them given a va_list.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. That packing is
+// exactly what is done by va_start. Further, the transform from ... to va_list
+// replaced va_start with an operation to copy a va_list from the new argument,
+// which is exactly a va_copy. This is useful for reducing target-dependence.
+//
+// A va_list instance is a forward iterator, where the primary operation va_arg
+// is dereference-then-increment. This interface forces significant convergent
+// evolution between target specific implementations. The variation in runtime
+// data layout is limited to that representable by the iterator, parameterised
+// by the type passed to the va_arg instruction.
+//
+// Therefore the majority of the target specific subtlety is packing arguments
+// into a stack allocated buffer such that a va_list can be initialised with it
+// and the va_arg expansion for the target will find the arguments at runtime.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+// There is one "clever" invariant in use. va_start intrinsics that are not
+// within a varidic functions are an error in the IR verifier. When this
+// transform moves blocks from a variadic function into a fixed arity one, it
+// moves va_start intrinsics along with everything else. That means that the
+// va_start intrinsics that need to be rewritten to use the trailing argument
+// are exactly those that are in non-variadic functions so no further state
+// is needed to distinguish those that need to be rewritten.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+namespace {
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::Unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::Unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::Disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::Optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::Lowering, "lowering",
+  "Change variadic calling convention")));
+
+bool commandLineOverride() {
+  return ExpandVariadicsModeOption != ExpandVariadicsMode::Unspecified;
+}
+
+// Instances of this class encapsulate the target-dependant behaviour as a
+// function of triple. Implementing a new ABI is adding a case to the switch
+// in create(llvm::Triple) at the end of this file.
+class VariadicABIInfo {
+protected:
+  VariadicABIInfo() {}
+
+public:
+  static std::unique_ptr create(llvm::Triple const &Triple);
+
+  // Allow overriding whether the pass runs on a per-target basis
+  virtual bool enableForTarget() = 0;
+
+  

[clang] [libc] [llvm] [AMDGPU] Implement variadic functions by IR lowering (PR #93362)

2024-06-05 Thread Pierre van Houtryve via cfe-commits


@@ -0,0 +1,1037 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a variadic function into a va_list
+// and fix up the call sites. The majority of the pass is target independent.
+// The exceptions are the va_list type itself and the rules for where to store
+// variables in memory such that va_arg can iterate over them given a va_list.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. That packing is
+// exactly what is done by va_start. Further, the transform from ... to va_list
+// replaced va_start with an operation to copy a va_list from the new argument,
+// which is exactly a va_copy. This is useful for reducing target-dependence.
+//
+// A va_list instance is a forward iterator, where the primary operation va_arg
+// is dereference-then-increment. This interface forces significant convergent
+// evolution between target specific implementations. The variation in runtime
+// data layout is limited to that representable by the iterator, parameterised
+// by the type passed to the va_arg instruction.
+//
+// Therefore the majority of the target specific subtlety is packing arguments
+// into a stack allocated buffer such that a va_list can be initialised with it
+// and the va_arg expansion for the target will find the arguments at runtime.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+// There is one "clever" invariant in use. va_start intrinsics that are not
+// within a varidic functions are an error in the IR verifier. When this
+// transform moves blocks from a variadic function into a fixed arity one, it
+// moves va_start intrinsics along with everything else. That means that the
+// va_start intrinsics that need to be rewritten to use the trailing argument
+// are exactly those that are in non-variadic functions so no further state
+// is needed to distinguish those that need to be rewritten.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+namespace {
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::Unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::Unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::Disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::Optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::Lowering, "lowering",
+  "Change variadic calling convention")));
+
+bool commandLineOverride() {
+  return ExpandVariadicsModeOption != ExpandVariadicsMode::Unspecified;
+}
+
+// Instances of this class encapsulate the target-dependant behaviour as a
+// function of triple. Implementing a new ABI is adding a case to the switch
+// in create(llvm::Triple) at the end of this file.
+class VariadicABIInfo {
+protected:
+  VariadicABIInfo() {}
+
+public:
+  static std::unique_ptr create(llvm::Triple const &Triple);
+
+  // Allow overriding whether the pass runs on a per-target basis
+  virtual bool enableForTarget() = 0;
+
+  

[clang] [libc] [llvm] [AMDGPU] Implement variadic functions by IR lowering (PR #93362)

2024-06-05 Thread Pierre van Houtryve via cfe-commits


@@ -0,0 +1,1037 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a variadic function into a va_list
+// and fix up the call sites. The majority of the pass is target independent.
+// The exceptions are the va_list type itself and the rules for where to store
+// variables in memory such that va_arg can iterate over them given a va_list.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. That packing is
+// exactly what is done by va_start. Further, the transform from ... to va_list
+// replaced va_start with an operation to copy a va_list from the new argument,
+// which is exactly a va_copy. This is useful for reducing target-dependence.
+//
+// A va_list instance is a forward iterator, where the primary operation va_arg
+// is dereference-then-increment. This interface forces significant convergent
+// evolution between target specific implementations. The variation in runtime
+// data layout is limited to that representable by the iterator, parameterised
+// by the type passed to the va_arg instruction.
+//
+// Therefore the majority of the target specific subtlety is packing arguments
+// into a stack allocated buffer such that a va_list can be initialised with it
+// and the va_arg expansion for the target will find the arguments at runtime.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+// There is one "clever" invariant in use. va_start intrinsics that are not
+// within a varidic functions are an error in the IR verifier. When this
+// transform moves blocks from a variadic function into a fixed arity one, it
+// moves va_start intrinsics along with everything else. That means that the
+// va_start intrinsics that need to be rewritten to use the trailing argument
+// are exactly those that are in non-variadic functions so no further state
+// is needed to distinguish those that need to be rewritten.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+namespace {
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::Unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::Unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::Disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::Optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::Lowering, "lowering",
+  "Change variadic calling convention")));
+
+bool commandLineOverride() {
+  return ExpandVariadicsModeOption != ExpandVariadicsMode::Unspecified;
+}
+
+// Instances of this class encapsulate the target-dependant behaviour as a
+// function of triple. Implementing a new ABI is adding a case to the switch
+// in create(llvm::Triple) at the end of this file.
+class VariadicABIInfo {
+protected:
+  VariadicABIInfo() {}
+
+public:
+  static std::unique_ptr create(llvm::Triple const &Triple);
+
+  // Allow overriding whether the pass runs on a per-target basis
+  virtual bool enableForTarget() = 0;
+
+  

[clang] Support [[guarded_by(mutex)]] attribute inside C struct (PR #94216)

2024-06-05 Thread Pierre d'Herbemont via cfe-commits

https://github.com/pdherbemont updated 
https://github.com/llvm/llvm-project/pull/94216

>From 0fd6864d7f0a85ca82f3c926a51403383c7ea0c7 Mon Sep 17 00:00:00 2001
From: Pierre d'Herbemont 
Date: Wed, 29 May 2024 11:11:03 +0200
Subject: [PATCH] Support [[guarded_by(mutex)]] attribute inside C struct

Today, it's only supported inside C++ classes or top level C/C++
declaration.

I mostly copied and adapted over the code from the
[[counted_by(value)]] lookup.

I had to change ast-dump-color.cpp because of the way the expression
marking now marks the mutex as "used" instead of "referenced". If I
change the expression parsing to use
`ExpressionEvaluationContext::Unevaluated` then I get the mutex as
"referenced" but I lose the C++ check for "invalid use of non-static
data member".
---
 clang/include/clang/Basic/Attr.td |  4 +-
 clang/include/clang/Parse/Parser.h|  8 +++
 clang/include/clang/Sema/Sema.h   |  6 +-
 clang/lib/Parse/ParseDecl.cpp | 64 ++-
 clang/lib/Sema/SemaExpr.cpp   |  4 +-
 clang/test/AST/ast-dump-color.cpp |  4 +-
 clang/test/Sema/warn-thread-safety-analysis.c | 10 ++-
 .../SemaCXX/warn-thread-safety-parsing.cpp|  6 +-
 8 files changed, 90 insertions(+), 16 deletions(-)

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index c6f08860f203a..15663c9eac686 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -3633,7 +3633,7 @@ def NoThreadSafetyAnalysis : InheritableAttr {
 def GuardedBy : InheritableAttr {
   let Spellings = [GNU<"guarded_by">];
   let Args = [ExprArgument<"Arg">];
-  let LateParsed = LateAttrParseStandard;
+  let LateParsed = LateAttrParseExperimentalExt;
   let TemplateDependent = 1;
   let ParseArgumentsAsUnevaluated = 1;
   let InheritEvenIfAlreadyPresent = 1;
@@ -3644,7 +3644,7 @@ def GuardedBy : InheritableAttr {
 def PtGuardedBy : InheritableAttr {
   let Spellings = [GNU<"pt_guarded_by">];
   let Args = [ExprArgument<"Arg">];
-  let LateParsed = LateAttrParseStandard;
+  let LateParsed = LateAttrParseExperimentalExt;
   let TemplateDependent = 1;
   let ParseArgumentsAsUnevaluated = 1;
   let InheritEvenIfAlreadyPresent = 1;
diff --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index d054b8cf0d240..39cc6b8e1fbeb 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -3128,6 +3128,14 @@ class Parser : public CodeCompletionHandler {
 IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
 ParsedAttr::Form Form);
 
+  void ParseGuardedByAttribute(IdentifierInfo &AttrName,
+   SourceLocation AttrNameLoc,
+   ParsedAttributes &Attrs,
+   IdentifierInfo *ScopeName,
+   SourceLocation ScopeLoc,
+   SourceLocation *EndLoc,
+   ParsedAttr::Form Form);
+
   void ParseTypeofSpecifier(DeclSpec &DS);
   SourceLocation ParseDecltypeSpecifier(DeclSpec &DS);
   void AnnotateExistingDecltypeSpecifier(const DeclSpec &DS,
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 7dea2b6826cfd..d41557270fe31 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5078,7 +5078,7 @@ class Sema final : public SemaBase {
 enum ExpressionKind {
   EK_Decltype,
   EK_TemplateArgument,
-  EK_BoundsAttrArgument,
+  EK_AttrArgument,
   EK_Other
 } ExprContext;
 
@@ -5185,10 +5185,10 @@ class Sema final : public SemaBase {
 return const_cast(this)->parentEvaluationContext();
   };
 
-  bool isBoundsAttrContext() const {
+  bool isAttrContext() const {
 return ExprEvalContexts.back().ExprContext ==
ExpressionEvaluationContextRecord::ExpressionKind::
-   EK_BoundsAttrArgument;
+   EK_AttrArgument;
   }
 
   /// Increment when we find a reference; decrement when we find an ignored
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index c528917437332..cfa6fa8b4926f 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -671,6 +671,12 @@ void Parser::ParseGNUAttributeArgs(
 ParseBoundsAttribute(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc,
  Form);
 return;
+  } else if (AttrKind == ParsedAttr::AT_GuardedBy ||
+ AttrKind == ParsedAttr::AT_PtGuardedBy) {
+ParseGuardedByAttribute(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc,
+EndLoc,
+Form);
+return;
   } else if (AttrKind == ParsedAttr::AT_CXXAssume) {
 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, EndLoc, Form);
 return;
@@ -3330,6 +3336,62 @@ void Parser::DistributeCLateParsedAttrs(Decl *

[clang] [Clang] Prevent null pointer dereferences in SVE tuple functions (PR #94267)

2024-06-05 Thread via cfe-commits


@@ -10211,8 +10211,8 @@ Value *CodeGenFunction::EmitSVETupleSetOrGet(const 
SVETypeFlags &TypeFlags,
  "Expects TypleFlag isTupleSet or TypeFlags.isTupleSet()");
 
   unsigned I = cast(Ops[1])->getSExtValue();
-  auto *SingleVecTy = dyn_cast(
-  TypeFlags.isTupleSet() ? Ops[2]->getType() : Ty);
+  auto *SingleVecTy = cast(

CarolineConcatto wrote:

I am not sure we want the compile to crash  that way, at least that is my 
impression.
Should this be an if  statement
if(auto *SingleVecTy = cast){
value *Idx = ConstantInt::get(CGM.Int64Ty,
I * SingleVecTy->getMinNumElements());
}
Is it possible to add a test for this change too?

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


[clang] Support [[guarded_by(mutex)]] attribute inside C struct (PR #94216)

2024-06-05 Thread Pierre d'Herbemont via cfe-commits

https://github.com/pdherbemont updated 
https://github.com/llvm/llvm-project/pull/94216

>From 7d01e8aae371e02f23b118d5b92f39fcee72723f Mon Sep 17 00:00:00 2001
From: Pierre d'Herbemont 
Date: Wed, 29 May 2024 11:11:03 +0200
Subject: [PATCH] Support [[guarded_by(mutex)]] attribute inside C struct

Today, it's only supported inside C++ classes or top level C/C++
declaration.

I mostly copied and adapted over the code from the
[[counted_by(value)]] lookup.

I had to change ast-dump-color.cpp because of the way the expression
marking now marks the mutex as "used" instead of "referenced". If I
change the expression parsing to use
`ExpressionEvaluationContext::Unevaluated` then I get the mutex as
"referenced" but I lose the C++ check for "invalid use of non-static
data member".
---
 clang/include/clang/Basic/Attr.td |  4 +-
 clang/include/clang/Parse/Parser.h|  7 +++
 clang/include/clang/Sema/Sema.h   |  7 +--
 clang/lib/Parse/ParseDecl.cpp | 60 ++-
 clang/lib/Sema/SemaExpr.cpp   |  4 +-
 clang/test/AST/ast-dump-color.cpp |  4 +-
 clang/test/Sema/warn-thread-safety-analysis.c |  8 +++
 .../SemaCXX/warn-thread-safety-parsing.cpp|  6 +-
 8 files changed, 84 insertions(+), 16 deletions(-)

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index c6f08860f203a..15663c9eac686 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -3633,7 +3633,7 @@ def NoThreadSafetyAnalysis : InheritableAttr {
 def GuardedBy : InheritableAttr {
   let Spellings = [GNU<"guarded_by">];
   let Args = [ExprArgument<"Arg">];
-  let LateParsed = LateAttrParseStandard;
+  let LateParsed = LateAttrParseExperimentalExt;
   let TemplateDependent = 1;
   let ParseArgumentsAsUnevaluated = 1;
   let InheritEvenIfAlreadyPresent = 1;
@@ -3644,7 +3644,7 @@ def GuardedBy : InheritableAttr {
 def PtGuardedBy : InheritableAttr {
   let Spellings = [GNU<"pt_guarded_by">];
   let Args = [ExprArgument<"Arg">];
-  let LateParsed = LateAttrParseStandard;
+  let LateParsed = LateAttrParseExperimentalExt;
   let TemplateDependent = 1;
   let ParseArgumentsAsUnevaluated = 1;
   let InheritEvenIfAlreadyPresent = 1;
diff --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index d054b8cf0d240..fa60ef0515df1 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -3128,6 +3128,13 @@ class Parser : public CodeCompletionHandler {
 IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
 ParsedAttr::Form Form);
 
+  void ParseGuardedByAttribute(IdentifierInfo &AttrName,
+   SourceLocation AttrNameLoc,
+   ParsedAttributes &Attrs,
+   IdentifierInfo *ScopeName,
+   SourceLocation ScopeLoc, SourceLocation *EndLoc,
+   ParsedAttr::Form Form);
+
   void ParseTypeofSpecifier(DeclSpec &DS);
   SourceLocation ParseDecltypeSpecifier(DeclSpec &DS);
   void AnnotateExistingDecltypeSpecifier(const DeclSpec &DS,
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 7dea2b6826cfd..5207a03bb7853 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5078,7 +5078,7 @@ class Sema final : public SemaBase {
 enum ExpressionKind {
   EK_Decltype,
   EK_TemplateArgument,
-  EK_BoundsAttrArgument,
+  EK_AttrArgument,
   EK_Other
 } ExprContext;
 
@@ -5185,10 +5185,9 @@ class Sema final : public SemaBase {
 return const_cast(this)->parentEvaluationContext();
   };
 
-  bool isBoundsAttrContext() const {
+  bool isAttrContext() const {
 return ExprEvalContexts.back().ExprContext ==
-   ExpressionEvaluationContextRecord::ExpressionKind::
-   EK_BoundsAttrArgument;
+   ExpressionEvaluationContextRecord::ExpressionKind::EK_AttrArgument;
   }
 
   /// Increment when we find a reference; decrement when we find an ignored
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index c528917437332..a2d2522a2a6ba 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -671,6 +671,11 @@ void Parser::ParseGNUAttributeArgs(
 ParseBoundsAttribute(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc,
  Form);
 return;
+  } else if (AttrKind == ParsedAttr::AT_GuardedBy ||
+ AttrKind == ParsedAttr::AT_PtGuardedBy) {
+ParseGuardedByAttribute(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc,
+EndLoc, Form);
+return;
   } else if (AttrKind == ParsedAttr::AT_CXXAssume) {
 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, EndLoc, Form);
 return;
@@ -3330,6 +3335,59 @@ void Parser::DistributeCLateParsedAttrs(Decl *Dcl,
   }
 }
 

[clang] Support [[guarded_by(mutex)]] attribute inside C struct (PR #94216)

2024-06-05 Thread Pierre d'Herbemont via cfe-commits


@@ -3330,6 +3340,63 @@ void Parser::DistributeCLateParsedAttrs(Decl *Dcl,
   }
 }
 
+/// GuardedBy attributes (e.g., guarded_by):
+///   AttrName '(' expression ')'
+void Parser::ParseGuardedByAttribute(IdentifierInfo &AttrName,
+ SourceLocation AttrNameLoc,
+ ParsedAttributes &Attrs,
+ IdentifierInfo *ScopeName,
+ SourceLocation ScopeLoc,
+ SourceLocation *EndLoc,
+ ParsedAttr::Form Form) {
+  assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
+
+  BalancedDelimiterTracker Parens(*this, tok::l_paren);
+  Parens.consumeOpen();
+
+  if (Tok.is(tok::r_paren)) {
+Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
+Parens.consumeClose();
+return;
+  }
+
+  ArgsVector ArgExprs;
+  // Don't evaluate argument when the attribute is ignored.
+  using ExpressionKind =
+  Sema::ExpressionEvaluationContextRecord::ExpressionKind;
+  EnterExpressionEvaluationContext EC(
+  Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluated, 
nullptr,
+  ExpressionKind::EK_BoundsAttrArgument);
+
+  ExprResult ArgExpr(
+  Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()));
+
+  if (ArgExpr.isInvalid()) {
+Parens.skipToEnd();
+return;
+  }
+
+  ArgExprs.push_back(ArgExpr.get());
+
+  auto RParens = Tok.getLocation();
+  auto &AL = *Attrs.addNew(
+  &AttrName, SourceRange(AttrNameLoc, RParens), ScopeName,
+  ScopeLoc, ArgExprs.data(), ArgExprs.size(), Form);
+
+  if (EndLoc) {
+ *EndLoc = Tok.getLocation();
+  }

pdherbemont wrote:

Switched to `EK_AttrArgument` and fixed the style (using the clang-format) 
thank you for the feedback!

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


[clang] Support [[guarded_by(mutex)]] attribute inside C struct (PR #94216)

2024-06-05 Thread Pierre d'Herbemont via cfe-commits


@@ -671,6 +671,16 @@ void Parser::ParseGNUAttributeArgs(
 ParseBoundsAttribute(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc,
  Form);
 return;
+  } else if (AttrKind == ParsedAttr::AT_GuardedBy) {
+ParseGuardedByAttribute(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc,
+EndLoc,
+Form);
+return;
+  } else if (AttrKind == ParsedAttr::AT_PtGuardedBy) {
+ParseGuardedByAttribute(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc,
+EndLoc,
+Form);
+return;

pdherbemont wrote:

Done!

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


[clang] Support [[guarded_by(mutex)]] attribute inside C struct (PR #94216)

2024-06-05 Thread Pierre d'Herbemont via cfe-commits


@@ -28,7 +28,12 @@
 struct LOCKABLE Mutex {};
 
 struct Foo {
-  struct Mutex *mu_;
+struct Mutex *mu_;
+struct Bar {
+struct Mutex *other_mu;
+} bar;
+  int  a_value GUARDED_BY(mu_);

pdherbemont wrote:

Fixed

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


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

2024-06-05 Thread Momchil Velikov via cfe-commits


@@ -118,6 +124,37 @@ llvm::Type *CodeGenTypes::ConvertTypeForMem(QualType T, 
bool ForBitField) {
   return R;
 }
 
+bool CodeGenTypes::LLVMTypeLayoutMatchesAST(QualType ASTTy,
+llvm::Type *LLVMTy) {
+  CharUnits ASTSize = Context.getTypeSizeInChars(ASTTy);
+  CharUnits LLVMSize =
+  CharUnits::fromQuantity(getDataLayout().getTypeAllocSize(LLVMTy));
+  return ASTSize == LLVMSize;
+}
+
+llvm::Type *CodeGenTypes::convertTypeForLoadStore(QualType T,
+  llvm::Type *LLVMTy) {
+  if (!LLVMTy)
+LLVMTy = ConvertType(T);
+
+  if (!T->isBitIntType() && LLVMTy->isIntegerTy(1))
+return llvm::IntegerType::get(getLLVMContext(),
+  (unsigned)Context.getTypeSize(T));
+
+  if (T->isBitIntType()) {
+llvm::Type *R = ConvertType(T);
+if (!LLVMTypeLayoutMatchesAST(T, R))
+  return llvm::Type::getIntNTy(
+  getLLVMContext(), Context.getTypeSizeInChars(T).getQuantity() * 8);

momchil-velikov wrote:

I don't understand why the choice of type is conditional. No matter of the 
"layout" matches or not, the stores have to produce valid in-memory 
representation (according to the target ABI), which in the general case means 
writing **all the** bits of the in-memory representation.

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


[clang] Support [[guarded_by(mutex)]] attribute inside C struct (PR #94216)

2024-06-05 Thread Vlad Serebrennikov via cfe-commits

https://github.com/Endilll commented:

`Sema.h` changes look good to me.

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


[clang] Fix clang reject valid C++ code after d999ce0302f06d250f6d496b56a5a5f (PR #94471)

2024-06-05 Thread Vassil Vassilev via cfe-commits

https://github.com/vgvassilev approved this pull request.

LGTM, can you include the produced errors and the steps to reproduce the 
failure in the commit log? Or refer to the github post describing it?

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


[clang] Support [[guarded_by(mutex)]] attribute inside C struct (PR #94216)

2024-06-05 Thread Aaron Ballman via cfe-commits

AaronBallman wrote:

> > One question I have is whether there will be follow-up work for other 
> > thread safety attributes (`acquire_capability`, `try_acquire_capability`, 
> > etc)?
> 
> They already work fine in C so far. But if you are aware of some issues don't 
> hesitate to let me know!

Ah, sorry, of course I picked examples that appertain to functions rather than 
fields. But some of the other thread safety attributes have the same problem as 
`guarded_by`: https://godbolt.org/z/hWTMxzrns

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


[clang] Support [[guarded_by(mutex)]] attribute inside C struct (PR #94216)

2024-06-05 Thread Pierre d'Herbemont via cfe-commits

pdherbemont wrote:

> You may also want to consider making the attribute late parsed in C when 
> `-fexperimental-late-parse-attributes` is enabled. See 
> https://github.com/llvm/llvm-project/pull/93121/files#diff-ae2ec9524bdbeea1f06917607482634dd89af5bcbb929805032463e5dafe79e7R2260
> 
> That will allow the code like below:
> 
> ```
>  struct Foo {
>int a_value GUARDED_BY(mu_); // attribute comes before `mu_` which needs 
> to be late parsed
>struct Mutext *mu_;
>  }
> ```

Adopted `LateAttrParseExperimentalExt`. Let me know if that looks okay.

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


[clang] Support [[guarded_by(mutex)]] attribute inside C struct (PR #94216)

2024-06-05 Thread Pierre d'Herbemont via cfe-commits

pdherbemont wrote:

> > > One question I have is whether there will be follow-up work for other 
> > > thread safety attributes (`acquire_capability`, `try_acquire_capability`, 
> > > etc)?
> > 
> > 
> > They already work fine in C so far. But if you are aware of some issues 
> > don't hesitate to let me know!
> 
> Ah, sorry, of course I picked examples that appertain to functions rather 
> than fields. But some of the other thread safety attributes have the same 
> problem as `guarded_by`: https://godbolt.org/z/hWTMxzrns

Oh yes – maybe it makes sense to fix them in this commit. Let me try to look 
into that quickly.

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


[clang] [clang][CodeGen] Make `UnqualPtrTy` truly unqualified (PR #94388)

2024-06-05 Thread Alex Voicu via cfe-commits

AlexVlx wrote:

> I think the point is there are two things going on here that people think of 
> as unqualified:
> 
> 1. "Give me a pointer that's whatever `void *` is"
> 2. "Give me a pointer in some address space just so I can put a global in 
> some metadata"
> 
> The vast majority of the time we're talking about 1, which is what most 
> people would think of unqualified as meaning. #93601 / #93914 are about the 
> three special cases that are case 2 above. But those are a special case, and 
> normally when people say unqualified they mean "default" address space / 
> `void *`.

Building on the above, let me add a bit more colour I should have added from 
the get go:

  - More often than not, for case (1) above, folks probably want (knowingly or 
not) a `void*` that "works",  
with no actual concern for the address  space (the "default");
  - As an example, for targets which model themselves / draw inspiration from 
e.g. OpenCL, this'd be a 
generic / flat pointer, but there's no way for the FE to query that  from 
the target (today?), and that 
information isn't really observably encoded in something like the 
DataLayout; if we were to add 
something like that, then unqualified would / should correspond to this, 
IMHO (could well happen to be 0 
in practice);
  - We have targets that map `LangAS::Default`oddly / differently from the 
above expectation, and hence it 
 appeared profitable to have `UnqualPtrTy`, which is a generally useful / 
everywhere usable pointer type, 
 be different from `Int8PtrTy` / `VoidPtrTy` which are pointer types which 
correspond to the target's 
 default (perhaps I am being overly cautious here though).

Having said that, this change is somewhat inert at the moment beyond carving 
out the name / making it shorthand for calling `getUnqual()`. In the future, we 
could either:

- extend DL to expose a target's flat/generic AS
- (more intrusive / might be infeasible) make unqualified `ptr`s be 
generic/everywhere usable in IR, without 
  the target exposing a flat/generic AS, letting the target figure out the 
legality of e.g. this or that ascast.

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


  1   2   3   4   5   >