[PATCH] D122865: [HLSL][clang][Driver] Support target profile command line option.

2022-04-02 Thread Xiang Li via Phabricator via cfe-commits
python3kgae updated this revision to Diff 419954.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122865/new/

https://reviews.llvm.org/D122865

Files:
  clang/include/clang/Basic/DiagnosticDriverKinds.td
  clang/include/clang/Driver/Driver.h
  clang/include/clang/Driver/Options.h
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/CMakeLists.txt
  clang/lib/Driver/Driver.cpp
  clang/lib/Driver/ToolChain.cpp
  clang/lib/Driver/ToolChains/HLSL.cpp
  clang/lib/Driver/ToolChains/HLSL.h
  clang/lib/Driver/Types.cpp
  clang/test/lit.cfg.py
  clang/unittests/Driver/ToolChainTest.cpp

Index: clang/unittests/Driver/ToolChainTest.cpp
===
--- clang/unittests/Driver/ToolChainTest.cpp
+++ clang/unittests/Driver/ToolChainTest.cpp
@@ -300,6 +300,12 @@
   EXPECT_TRUE(Res.ModeSuffix == "clang-cl");
   EXPECT_STREQ(Res.DriverMode, "--driver-mode=cl");
   EXPECT_FALSE(Res.TargetIsValid);
+
+  Res = ToolChain::getTargetAndModeFromProgramName("clang-dxc");
+  EXPECT_TRUE(Res.TargetPrefix.empty());
+  EXPECT_TRUE(Res.ModeSuffix == "clang-dxc");
+  EXPECT_STREQ(Res.DriverMode, "--driver-mode=dxc");
+  EXPECT_FALSE(Res.TargetIsValid);
 }
 
 TEST(ToolChainTest, CommandOutput) {
@@ -361,4 +367,141 @@
   EXPECT_EQ(getDriverMode(Args[0], llvm::makeArrayRef(Args).slice(1)), "bar");
 }
 
+TEST(DxcModeTest, TargetProfileValidation) {
+  IntrusiveRefCntPtr DiagID(new DiagnosticIDs());
+  struct SimpleDiagnosticConsumer : public DiagnosticConsumer {
+void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+  const Diagnostic &Info) override {
+  if (DiagLevel == DiagnosticsEngine::Level::Error) {
+Errors.emplace_back();
+Info.FormatDiagnostic(Errors.back());
+  } else {
+Msgs.emplace_back();
+Info.FormatDiagnostic(Msgs.back());
+  }
+}
+void clear() override {
+  Msgs.clear();
+  Errors.clear();
+  DiagnosticConsumer::clear();
+}
+std::vector> Msgs;
+std::vector> Errors;
+  };
+
+  IntrusiveRefCntPtr InMemoryFileSystem(
+  new llvm::vfs::InMemoryFileSystem);
+
+  InMemoryFileSystem->addFile("foo.hlsl", 0,
+  llvm::MemoryBuffer::getMemBuffer("\n"));
+
+  auto *DiagConsumer = new SimpleDiagnosticConsumer;
+  IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions();
+  DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagConsumer);
+  Driver TheDriver("/bin/clang", "", Diags, "", InMemoryFileSystem);
+  std::unique_ptr C(
+  TheDriver.BuildCompilation({"clang", "--driver-mode=dxc", "foo.hlsl"}));
+  EXPECT_TRUE(C);
+  EXPECT_TRUE(!C->containsError());
+
+  auto &TC = C->getDefaultToolChain();
+  bool ContainsError = false;
+  auto Args = TheDriver.ParseArgStrings({"-Tvs_6_0"}, false, ContainsError);
+  EXPECT_FALSE(ContainsError);
+  auto Triple = TC.ComputeEffectiveClangTriple(Args);
+  EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.0-vertex");
+  EXPECT_EQ(Diags.getNumErrors(), 0);
+
+  Args = TheDriver.ParseArgStrings({"-Ths_6_1"}, false, ContainsError);
+  EXPECT_FALSE(ContainsError);
+  Triple = TC.ComputeEffectiveClangTriple(Args);
+  EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.1-hull");
+  EXPECT_EQ(Diags.getNumErrors(), 0);
+
+  Args = TheDriver.ParseArgStrings({"-Tds_6_2"}, false, ContainsError);
+  EXPECT_FALSE(ContainsError);
+  Triple = TC.ComputeEffectiveClangTriple(Args);
+  EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.2-domain");
+  EXPECT_EQ(Diags.getNumErrors(), 0);
+
+  Args = TheDriver.ParseArgStrings({"-Tds_6_2"}, false, ContainsError);
+  EXPECT_FALSE(ContainsError);
+  Triple = TC.ComputeEffectiveClangTriple(Args);
+  EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.2-domain");
+  EXPECT_EQ(Diags.getNumErrors(), 0);
+
+  Args = TheDriver.ParseArgStrings({"-Tgs_6_3"}, false, ContainsError);
+  EXPECT_FALSE(ContainsError);
+  Triple = TC.ComputeEffectiveClangTriple(Args);
+  EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.3-geometry");
+  EXPECT_EQ(Diags.getNumErrors(), 0);
+
+  Args = TheDriver.ParseArgStrings({"-Tps_6_4"}, false, ContainsError);
+  EXPECT_FALSE(ContainsError);
+  Triple = TC.ComputeEffectiveClangTriple(Args);
+  EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.4-pixel");
+  EXPECT_EQ(Diags.getNumErrors(), 0);
+
+  Args = TheDriver.ParseArgStrings({"-Tcs_6_5"}, false, ContainsError);
+  EXPECT_FALSE(ContainsError);
+  Triple = TC.ComputeEffectiveClangTriple(Args);
+  EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.5-compute");
+  EXPECT_EQ(Diags.getNumErrors(), 0);
+
+  Args = TheDriver.ParseArgStrings({"-Tms_6_6"}, false, ContainsError);
+  EXPECT_FALSE(ContainsError);
+  Triple = TC.ComputeEffectiveClangTriple(Args);
+  EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.6-mesh");
+  EXPECT_EQ(Diags.getNumErrors(), 0);
+
+  Args = TheDriver.ParseArgStrings({"-Tas_6_7"}, false, ContainsError);
+  EXPECT_FALSE(ContainsError);
+  Triple = TC.Comput

[PATCH] D122965: Corrected A Command

2022-04-02 Thread Priyansh Singh via Phabricator via cfe-commits
ps-19 added a comment.

I seriously can not understand why x64_Debian build if failing for every patch.




Comment at: clang/test/CodeGen/c-unicode.c:5
 int \uaccess = 0;
 // ALLOWED: "곎ss":
 // ALLOWED-NOT: "\uaccess":

Comment Line No: 5 is // ALLOWED: "곎ss": i think "곎ss" in istake here, 
according to google it is written in korean and i can not understand it's 
meaning, but it should be made more concise and readable for more user.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122965/new/

https://reviews.llvm.org/D122965

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


[PATCH] D122965: Corrected A Command

2022-04-02 Thread Priyansh Singh via Phabricator via cfe-commits
ps-19 added a comment.

In D122965#3424348 , @ps-19 wrote:

> I seriously can not understand why x64_Debian build if failing for every 
> patch.

I have ran clang-format command for every patch even multiple times.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122965/new/

https://reviews.llvm.org/D122965

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


[PATCH] D119609: [Clang][Sema] Prohibit expression statement in lambda default argument

2022-04-02 Thread Jun Zhang via Phabricator via cfe-commits
junaire updated this revision to Diff 419965.
junaire added a comment.

- Rebase.
- Update commit message.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D119609/new/

https://reviews.llvm.org/D119609

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/test/Sema/err-expr-stmt-in-default-arg.cpp
  clang/test/SemaTemplate/dependent-expr.cpp

Index: clang/test/SemaTemplate/dependent-expr.cpp
===
--- clang/test/SemaTemplate/dependent-expr.cpp
+++ clang/test/SemaTemplate/dependent-expr.cpp
@@ -141,15 +141,7 @@
   using U = float; // expected-error {{different types ('float' vs 'decltype(g())' (aka 'void'))}}
 
   void h(auto a, decltype(g())*) {} // expected-note {{previous}}
-  void h(auto a, void*) {} // expected-error {{redefinition}}
-
-  void i(auto a) {
-[](auto a, int = ({decltype(a) i; i * 2;})){}(a); // expected-error {{invalid operands to binary expression ('decltype(a)' (aka 'void *') and 'int')}} expected-note {{in instantiation of}}
-  }
-  void use_i() {
-i(0);
-i((void*)0); // expected-note {{instantiation of}}
-  }
+  void h(auto a, void *) {} // expected-error {{redefinition}}
 }
 
 namespace BindingInStmtExpr {
Index: clang/test/Sema/err-expr-stmt-in-default-arg.cpp
===
--- /dev/null
+++ clang/test/Sema/err-expr-stmt-in-default-arg.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c++20
+
+void foo() {
+  void fn(int i, int = ({ 1; })); // expected-error {{expression statement not permitted in default argument}}
+
+  auto a = [](int = ({ 1; })) {}; // expected-error {{expression statement not permitted in default argument}}
+
+  auto b = [](){}; // expected-error {{expression statement not permitted in default argument}}
+
+  void fn(int i, int j = ({{}, {}, {,}}), int k = ""); // expected-error {{expression statement not permitted in default argument}} expected-error {{cannot initialize a parameter of type 'int' with an lvalue of type 'const char[1]'}} expected-note {{passing argument to parameter 'k' here}}
+}
+
+template 
+int bar(Callable &&Call) {
+  return Call();
+}
+
+int baz() {
+  auto l = [](int a = ({ int x = 12; x; })) { // expected-error {{expression statement not permitted in default argument}}
+return 1;
+  };
+  return bar(l);
+}
Index: clang/lib/Parse/ParseTemplate.cpp
===
--- clang/lib/Parse/ParseTemplate.cpp
+++ clang/lib/Parse/ParseTemplate.cpp
@@ -19,6 +19,7 @@
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/ParsedTemplate.h"
 #include "clang/Sema/Scope.h"
+#include "clang/Sema/SemaDiagnostic.h"
 #include "llvm/Support/TimeProfiler.h"
 using namespace clang;
 
@@ -1007,18 +1008,23 @@
   SourceLocation EqualLoc;
   ExprResult DefaultArg;
   if (TryConsumeToken(tok::equal, EqualLoc)) {
-// C++ [temp.param]p15:
-//   When parsing a default template-argument for a non-type
-//   template-parameter, the first non-nested > is taken as the
-//   end of the template-parameter-list rather than a greater-than
-//   operator.
-GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);
-EnterExpressionEvaluationContext ConstantEvaluated(
-Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
-
-DefaultArg = Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
-if (DefaultArg.isInvalid())
+if (Tok.is(tok::l_paren) && NextToken().is(tok::l_brace)) {
+  Diag(Tok.getLocation(), diag::err_expr_statement_in_default_arg);
   SkipUntil(tok::comma, tok::greater, StopAtSemi | StopBeforeMatch);
+} else {
+  // C++ [temp.param]p15:
+  //   When parsing a default template-argument for a non-type
+  //   template-parameter, the first non-nested > is taken as the
+  //   end of the template-parameter-list rather than a greater-than
+  //   operator.
+  GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);
+  EnterExpressionEvaluationContext ConstantEvaluated(
+  Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
+  DefaultArg =
+  Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
+  if (DefaultArg.isInvalid())
+SkipUntil(tok::comma, tok::greater, StopAtSemi | StopBeforeMatch);
+}
   }
 
   // Create the parameter.
Index: clang/lib/Parse/ParseDecl.cpp
===
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -7066,8 +7066,16 @@
   if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
 DefArgResult = ParseBraceInitializer();
-  } else
+  } else {
+if (Tok.is

[PATCH] D119609: [Clang][Sema] Prohibit expr statement in the default argument

2022-04-02 Thread Jun Zhang via Phabricator via cfe-commits
junaire added a comment.

Hi @aaron.ballman, do you think it's time to consider reviewing this?

I don't why there's no response or progress in GCC, but I think I can submit a 
patch for them if they think this issue is low prior.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D119609/new/

https://reviews.llvm.org/D119609

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


[clang] cc21395 - [AMDPU][Sanitizer] Refactor sanitizer options handling for AMDGPU Toolchain

2022-04-02 Thread Ron Lieberman via cfe-commits

Author: Ron Lieberman
Date: 2022-04-02T11:01:09Z
New Revision: cc2139524f77248c7e147d4cc3befb31fe3e6daa

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

LOG: [AMDPU][Sanitizer] Refactor sanitizer options handling for AMDGPU Toolchain

authored by amit.pan...@amd.com  ampandey-AMD

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

Added: 


Modified: 
clang/include/clang/Basic/DiagnosticDriverKinds.td
clang/lib/Driver/ToolChains/AMDGPU.cpp
clang/lib/Driver/ToolChains/AMDGPU.h
clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
clang/lib/Driver/ToolChains/AMDGPUOpenMP.h
clang/lib/Driver/ToolChains/HIPAMD.cpp
clang/test/Driver/hip-sanitize-options.hip

Removed: 




diff  --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td 
b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 63913b933c8fb..fa17af52d6278 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -68,6 +68,9 @@ def err_drv_no_rocm_device_lib : Error<
   "cannot find ROCm device library%select{| for %1|for ABI version %1}0; 
provide its path via "
   "'--rocm-path' or '--rocm-device-lib-path', or pass '-nogpulib' to build "
   "without ROCm device library">;
+def err_drv_no_asan_rt_lib : Error<
+  "AMDGPU address sanitizer runtime library (asanrtl) is not found. "
+  "Please install ROCm device library which supports address sanitizer">;
 def err_drv_no_hip_runtime : Error<
   "cannot find HIP runtime; provide its path via '--rocm-path', or pass "
   "'-nogpuinc' to build without HIP runtime">;

diff  --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp 
b/clang/lib/Driver/ToolChains/AMDGPU.cpp
index 123d92664495e..56b3a2d33cdab 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp
@@ -911,6 +911,42 @@ RocmInstallationDetector::getCommonBitcodeLibs(
   return BCLibs;
 }
 
+bool AMDGPUToolChain::shouldSkipSanitizeOption(
+const ToolChain &TC, const llvm::opt::ArgList &DriverArgs,
+StringRef TargetID, const llvm::opt::Arg *A) const {
+  // For actions without targetID, do nothing.
+  if (TargetID.empty())
+return false;
+  Option O = A->getOption();
+  if (!O.matches(options::OPT_fsanitize_EQ))
+return false;
+
+  if (!DriverArgs.hasFlag(options::OPT_fgpu_sanitize,
+  options::OPT_fno_gpu_sanitize, true))
+return true;
+
+  auto &Diags = TC.getDriver().getDiags();
+
+  // For simplicity, we only allow -fsanitize=address
+  SanitizerMask K = parseSanitizerValue(A->getValue(), /*AllowGroups=*/false);
+  if (K != SanitizerKind::Address)
+return true;
+
+  llvm::StringMap FeatureMap;
+  auto OptionalGpuArch = parseTargetID(TC.getTriple(), TargetID, &FeatureMap);
+
+  assert(OptionalGpuArch && "Invalid Target ID");
+  (void)OptionalGpuArch;
+  auto Loc = FeatureMap.find("xnack");
+  if (Loc == FeatureMap.end() || !Loc->second) {
+Diags.Report(
+clang::diag::warn_drv_unsupported_option_for_offload_arch_req_feature)
+<< A->getAsString(DriverArgs) << TargetID << "xnack+";
+return true;
+  }
+  return false;
+}
+
 bool AMDGPUToolChain::shouldSkipArgument(const llvm::opt::Arg *A) const {
   Option O = A->getOption();
   if (O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie))

diff  --git a/clang/lib/Driver/ToolChains/AMDGPU.h 
b/clang/lib/Driver/ToolChains/AMDGPU.h
index ddcc124b25bac..6d8bb82c6449d 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.h
+++ b/clang/lib/Driver/ToolChains/AMDGPU.h
@@ -99,6 +99,12 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUToolChain : public 
Generic_ELF {
   /// Needed for translating LTO options.
   const char *getDefaultLinker() const override { return "ld.lld"; }
 
+  /// Should skip Sanitize options
+  bool shouldSkipSanitizeOption(const ToolChain &TC,
+const llvm::opt::ArgList &DriverArgs,
+StringRef TargetID,
+const llvm::opt::Arg *A) const;
+
   /// Should skip argument.
   bool shouldSkipArgument(const llvm::opt::Arg *Arg) const;
 

diff  --git a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp 
b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
index 998bb0b9f7c94..2989aabae5516 100644
--- a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
@@ -16,6 +16,7 @@
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/InputInfo.h"
 #include "clang/Driver/Options.h"
+#include "clang/Driver/SanitizerArgs.h"
 #include "clang/Driver/Tool.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/FileSystem.h"
@@ -304,7 +305,8 @@ llvm::opt::DerivedArgList 
*AMDGPUOpenMPToolChain::TranslateArgs(
 
   if (DeviceOffloadKind == Action::OFK_OpenMP) 

[PATCH] D122781: Refactor sanitizer options handling for AMDGPU Toolchain

2022-04-02 Thread Ron Lieberman via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGcc2139524f77: [AMDPU][Sanitizer] Refactor sanitizer options 
handling for AMDGPU Toolchain (authored by ronlieb).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122781/new/

https://reviews.llvm.org/D122781

Files:
  clang/include/clang/Basic/DiagnosticDriverKinds.td
  clang/lib/Driver/ToolChains/AMDGPU.cpp
  clang/lib/Driver/ToolChains/AMDGPU.h
  clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
  clang/lib/Driver/ToolChains/AMDGPUOpenMP.h
  clang/lib/Driver/ToolChains/HIPAMD.cpp
  clang/test/Driver/hip-sanitize-options.hip

Index: clang/test/Driver/hip-sanitize-options.hip
===
--- clang/test/Driver/hip-sanitize-options.hip
+++ clang/test/Driver/hip-sanitize-options.hip
@@ -62,7 +62,7 @@
 // RDC: {{"[^"]*clang[^"]*".* "-emit-llvm-bc".* "-fcuda-is-device".* "-mlink-bitcode-file" ".*asanrtl.bc".* "-mlink-builtin-bitcode" ".*hip.bc".* "-fsanitize=address".*}} "-o" "[[OUT:[^"]*.bc]]"
 // RDC-NOT: {{"[^"]*lld(\.exe){0,1}".*}} "[[OUT]]" {{".*asanrtl.bc" ".*hip.bc"}}
 
-// FAIL: AMDGPU address sanitizer runtime library (asanrtl) is not found. Please install ROCm device library which supports address sanitizer
+// FAIL: error: AMDGPU address sanitizer runtime library (asanrtl) is not found. Please install ROCm device library which supports address sanitizer
 
 // XNACK-DAG: warning: ignoring '-fsanitize=leak' option as it is not currently supported for target 'amdgcn-amd-amdhsa'
 // XNACK-DAG: warning: ignoring '-fsanitize=address' option as it is not currently supported for offload arch 'gfx900:xnack-'. Use it with an offload arch containing 'xnack+' instead
Index: clang/lib/Driver/ToolChains/HIPAMD.cpp
===
--- clang/lib/Driver/ToolChains/HIPAMD.cpp
+++ clang/lib/Driver/ToolChains/HIPAMD.cpp
@@ -35,43 +35,6 @@
 #define NULL_FILE "/dev/null"
 #endif
 
-static bool shouldSkipSanitizeOption(const ToolChain &TC,
- const llvm::opt::ArgList &DriverArgs,
- StringRef TargetID,
- const llvm::opt::Arg *A) {
-  // For actions without targetID, do nothing.
-  if (TargetID.empty())
-return false;
-  Option O = A->getOption();
-  if (!O.matches(options::OPT_fsanitize_EQ))
-return false;
-
-  if (!DriverArgs.hasFlag(options::OPT_fgpu_sanitize,
-  options::OPT_fno_gpu_sanitize, true))
-return true;
-
-  auto &Diags = TC.getDriver().getDiags();
-
-  // For simplicity, we only allow -fsanitize=address
-  SanitizerMask K = parseSanitizerValue(A->getValue(), /*AllowGroups=*/false);
-  if (K != SanitizerKind::Address)
-return true;
-
-  llvm::StringMap FeatureMap;
-  auto OptionalGpuArch = parseTargetID(TC.getTriple(), TargetID, &FeatureMap);
-
-  assert(OptionalGpuArch && "Invalid Target ID");
-  (void)OptionalGpuArch;
-  auto Loc = FeatureMap.find("xnack");
-  if (Loc == FeatureMap.end() || !Loc->second) {
-Diags.Report(
-clang::diag::warn_drv_unsupported_option_for_offload_arch_req_feature)
-<< A->getAsString(DriverArgs) << TargetID << "xnack+";
-return true;
-  }
-  return false;
-}
-
 void AMDGCN::Linker::constructLldCommand(Compilation &C, const JobAction &JA,
  const InputInfoList &Inputs,
  const InputInfo &Output,
@@ -337,12 +300,7 @@
 getSanitizerArgs(DriverArgs).needsAsanRt()) {
   auto AsanRTL = RocmInstallation.getAsanRTLPath();
   if (AsanRTL.empty()) {
-unsigned DiagID = getDriver().getDiags().getCustomDiagID(
-DiagnosticsEngine::Error,
-"AMDGPU address sanitizer runtime library (asanrtl) is not found. "
-"Please install ROCm device library which supports address "
-"sanitizer");
-getDriver().Diag(DiagID);
+getDriver().Diag(diag::err_drv_no_asan_rt_lib);
 return {};
   } else
 BCLibs.push_back({AsanRTL.str(), /*ShouldInternalize=*/false});
Index: clang/lib/Driver/ToolChains/AMDGPUOpenMP.h
===
--- clang/lib/Driver/ToolChains/AMDGPUOpenMP.h
+++ clang/lib/Driver/ToolChains/AMDGPUOpenMP.h
@@ -93,6 +93,10 @@
 
   SanitizerMask getSupportedSanitizers() const override;
 
+  RocmInstallationDetector getRocmInstallationLoc() const {
+return RocmInstallation;
+  }
+
   VersionTuple
   computeMSVCVersion(const Driver *D,
  const llvm::opt::ArgList &Args) const override;
Index: clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
===
--- clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
+++ clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
@@ -16,6 +16,7 @@
 #include "clang/Driver/Driver

[PATCH] D122781: Refactor sanitizer options handling for AMDGPU Toolchain

2022-04-02 Thread Ron Lieberman via Phabricator via cfe-commits
ronlieb added a comment.

i pushed it in. will watch for build bot issues


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122781/new/

https://reviews.llvm.org/D122781

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


[PATCH] D122768: [WIP][Clang] Support capturing structured bindings in lambdas

2022-04-02 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin updated this revision to Diff 419970.
cor3ntin added a comment.

- Add codegen test
- Fixed a typo that caused openmp test failures
- Cleanups & formatting


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122768/new/

https://reviews.llvm.org/D122768

Files:
  clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/AST/LambdaCapture.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/ScopeInfo.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/DeclCXX.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/Analysis/AnalysisDeclContext.cpp
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/Sema/ScopeInfo.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp
  clang/test/CodeGenCXX/cxx20-decomposition.cpp
  clang/test/SemaCXX/cxx1z-decomposition.cpp
  clang/test/SemaCXX/cxx20-decomposition.cpp
  clang/test/SemaCXX/decomposition-blocks.cpp
  clang/test/SemaCXX/decomposition-openmp.cpp
  clang/tools/libclang/CIndex.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1144,7 +1144,7 @@
 
   Structured binding extensions
   https://wg21.link/p1091r3";>P1091R3
-  Partial
+  Clang 15
 
   
 https://wg21.link/p1381r1";>P1381R1
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -3350,9 +3350,11 @@
C != CEnd; ++C) {
 if (!C->capturesVariable())
   continue;
-
-if (Visit(MakeCursorVariableRef(C->getCapturedVar(), C->getLocation(),
-TU)))
+// TODO: hamdle structured bindings here ?
+if (!isa(C->getCapturedVar()))
+  continue;
+if (Visit(MakeCursorVariableRef(cast(C->getCapturedVar()),
+C->getLocation(), TU)))
   return true;
   }
   // Visit init captures
Index: clang/test/SemaCXX/decomposition-openmp.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/decomposition-openmp.cpp
@@ -0,0 +1,13 @@
+
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 -fopenmp %s
+
+// FIXME: OpenMP should support capturing structured bindings
+auto f() {
+  int i[2] = {};
+  auto [a, b] = i; // expected-note 2{{declared here}}
+  return [=, &a] {
+// expected-error@-1 {{capturing a structured binding is not yet supported in OpenMP}}
+return a + b;
+// expected-error@-1 {{capturing a structured binding is not yet supported in OpenMP}}
+  };
+}
Index: clang/test/SemaCXX/decomposition-blocks.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/decomposition-blocks.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s -fblocks
+
+struct S {
+  int i : 1;
+  int j;
+};
+
+void run(void (^)());
+void test() {
+  auto [i, j] = S{1, 42}; // expected-note {{'i' declared here}}
+  run(^{
+(void)i; // expected-error {{reference to local binding 'i' declared in enclosing function 'test'}}
+  });
+}
Index: clang/test/SemaCXX/cxx20-decomposition.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/cxx20-decomposition.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
+// expected-no-diagnostics
+
+template 
+constexpr bool is_same = false;
+template 
+constexpr bool is_same = true;
+
+struct S {
+  int i;
+  int &j;
+};
+
+void check_category() {
+  int a = 42;
+  {
+auto [v, r] = S{1, a};
+(void)[ v, r ] {
+  static_assert(is_same);
+  static_assert(is_same);
+};
+  }
+  {
+auto [v, r] = S{1, a};
+(void)[&v, &r ] {
+  static_assert(is_same);
+  static_assert(is_same);
+};
+  }
+  {
+S s{1, a};
+const auto &[v, r] = s;
+(void)[ v, r ] {
+  static_assert(is_same);
+  static_assert(is_s

[PATCH] D122768: [Clang][C++20] Support capturing structured bindings in lambdas

2022-04-02 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin added inline comments.



Comment at: clang/lib/CodeGen/CGOpenMPRuntime.cpp:9060
 continue;
-  const VarDecl *VD = LC.getCapturedVar();
+  const VarDecl *VD = cast(LC.getCapturedVar());
   if (LC.getCaptureKind() != LCK_ByRef && !VD->getType()->isPointerType())

cor3ntin wrote:
> I'm not sure we currently prohibit capturing a structured binding in openmp, 
> i should fix that
I disabled the feature in OpenMP mode, as this needs more investigation


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122768/new/

https://reviews.llvm.org/D122768

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


[clang] f1e7eca - Revert "[AMDPU][Sanitizer] Refactor sanitizer options handling for AMDGPU Toolchain"

2022-04-02 Thread Ron Lieberman via cfe-commits

Author: Ron Lieberman
Date: 2022-04-02T13:25:50Z
New Revision: f1e7ecaa18a7b1c77fc95e4b83d3db02c4e2d211

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

LOG: Revert "[AMDPU][Sanitizer] Refactor sanitizer options handling for AMDGPU 
Toolchain"

This reverts commit cc2139524f77248c7e147d4cc3befb31fe3e6daa.

failed a few buildbots

Added: 


Modified: 
clang/include/clang/Basic/DiagnosticDriverKinds.td
clang/lib/Driver/ToolChains/AMDGPU.cpp
clang/lib/Driver/ToolChains/AMDGPU.h
clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
clang/lib/Driver/ToolChains/AMDGPUOpenMP.h
clang/lib/Driver/ToolChains/HIPAMD.cpp
clang/test/Driver/hip-sanitize-options.hip

Removed: 




diff  --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td 
b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index fa17af52d6278..63913b933c8fb 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -68,9 +68,6 @@ def err_drv_no_rocm_device_lib : Error<
   "cannot find ROCm device library%select{| for %1|for ABI version %1}0; 
provide its path via "
   "'--rocm-path' or '--rocm-device-lib-path', or pass '-nogpulib' to build "
   "without ROCm device library">;
-def err_drv_no_asan_rt_lib : Error<
-  "AMDGPU address sanitizer runtime library (asanrtl) is not found. "
-  "Please install ROCm device library which supports address sanitizer">;
 def err_drv_no_hip_runtime : Error<
   "cannot find HIP runtime; provide its path via '--rocm-path', or pass "
   "'-nogpuinc' to build without HIP runtime">;

diff  --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp 
b/clang/lib/Driver/ToolChains/AMDGPU.cpp
index 56b3a2d33cdab..123d92664495e 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp
@@ -911,42 +911,6 @@ RocmInstallationDetector::getCommonBitcodeLibs(
   return BCLibs;
 }
 
-bool AMDGPUToolChain::shouldSkipSanitizeOption(
-const ToolChain &TC, const llvm::opt::ArgList &DriverArgs,
-StringRef TargetID, const llvm::opt::Arg *A) const {
-  // For actions without targetID, do nothing.
-  if (TargetID.empty())
-return false;
-  Option O = A->getOption();
-  if (!O.matches(options::OPT_fsanitize_EQ))
-return false;
-
-  if (!DriverArgs.hasFlag(options::OPT_fgpu_sanitize,
-  options::OPT_fno_gpu_sanitize, true))
-return true;
-
-  auto &Diags = TC.getDriver().getDiags();
-
-  // For simplicity, we only allow -fsanitize=address
-  SanitizerMask K = parseSanitizerValue(A->getValue(), /*AllowGroups=*/false);
-  if (K != SanitizerKind::Address)
-return true;
-
-  llvm::StringMap FeatureMap;
-  auto OptionalGpuArch = parseTargetID(TC.getTriple(), TargetID, &FeatureMap);
-
-  assert(OptionalGpuArch && "Invalid Target ID");
-  (void)OptionalGpuArch;
-  auto Loc = FeatureMap.find("xnack");
-  if (Loc == FeatureMap.end() || !Loc->second) {
-Diags.Report(
-clang::diag::warn_drv_unsupported_option_for_offload_arch_req_feature)
-<< A->getAsString(DriverArgs) << TargetID << "xnack+";
-return true;
-  }
-  return false;
-}
-
 bool AMDGPUToolChain::shouldSkipArgument(const llvm::opt::Arg *A) const {
   Option O = A->getOption();
   if (O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie))

diff  --git a/clang/lib/Driver/ToolChains/AMDGPU.h 
b/clang/lib/Driver/ToolChains/AMDGPU.h
index 6d8bb82c6449d..ddcc124b25bac 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.h
+++ b/clang/lib/Driver/ToolChains/AMDGPU.h
@@ -99,12 +99,6 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUToolChain : public 
Generic_ELF {
   /// Needed for translating LTO options.
   const char *getDefaultLinker() const override { return "ld.lld"; }
 
-  /// Should skip Sanitize options
-  bool shouldSkipSanitizeOption(const ToolChain &TC,
-const llvm::opt::ArgList &DriverArgs,
-StringRef TargetID,
-const llvm::opt::Arg *A) const;
-
   /// Should skip argument.
   bool shouldSkipArgument(const llvm::opt::Arg *Arg) const;
 

diff  --git a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp 
b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
index 2989aabae5516..998bb0b9f7c94 100644
--- a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
@@ -16,7 +16,6 @@
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/InputInfo.h"
 #include "clang/Driver/Options.h"
-#include "clang/Driver/SanitizerArgs.h"
 #include "clang/Driver/Tool.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/FileSystem.h"
@@ -305,8 +304,7 @@ llvm::opt::DerivedArgList 
*AMDGPUOpenMPToolChain::TranslateArgs(
 
   if (DeviceOffloadKind == Action::OFK_OpenMP) {
 

[clang] b93893e - [AArch64] Default HBC/MOPS features in clang

2022-04-02 Thread via cfe-commits

Author: tyb0807
Date: 2022-04-02T14:51:23+01:00
New Revision: b93893e60f0c860e5814cea6cc285c8e89e035af

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

LOG: [AArch64] Default HBC/MOPS features in clang

This implements minimum support in clang for default HBC/MOPS features
on v8.8-a/v9.3-a or later architectures.

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

Added: 


Modified: 
clang/lib/Basic/Targets/AArch64.cpp
clang/lib/Driver/ToolChains/Arch/AArch64.cpp
clang/test/Driver/aarch64-hbc.c
clang/test/Driver/aarch64-mops.c
clang/test/Preprocessor/aarch64-target-features.c

Removed: 




diff  --git a/clang/lib/Basic/Targets/AArch64.cpp 
b/clang/lib/Basic/Targets/AArch64.cpp
index 964cf5c824140..f4aecd3675b1d 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -226,8 +226,6 @@ void AArch64TargetInfo::getTargetDefinesARMV87A(const 
LangOptions &Opts,
 
 void AArch64TargetInfo::getTargetDefinesARMV88A(const LangOptions &Opts,
 MacroBuilder &Builder) const {
-  // FIXME: this does not handle the case where MOPS is disabled using +nomops
-  Builder.defineMacro("__ARM_FEATURE_MOPS", "1");
   // Also include the Armv8.7 defines
   getTargetDefinesARMV87A(Opts, Builder);
 }

diff  --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp 
b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
index a0be30f881e52..1691b7faf668a 100644
--- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
@@ -461,13 +461,24 @@ void aarch64::getAArch64TargetFeatures(const Driver &D,
 }
   }
 
-  const char *Archs[] = {"+v8.6a", "+v8.7a", "+v8.8a",
- "+v9.1a", "+v9.2a", "+v9.3a"};
-  auto Pos = std::find_first_of(Features.begin(), Features.end(),
-std::begin(Archs), std::end(Archs));
+  // FIXME: these insertions should ideally be automated using default
+  // extensions support from the backend target parser.
+  const char *v8691OrLater[] = {"+v8.6a", "+v8.7a", "+v8.8a",
+"+v9.1a", "+v9.2a", "+v9.3a"};
+  auto Pos =
+  std::find_first_of(Features.begin(), Features.end(),
+ std::begin(v8691OrLater), std::end(v8691OrLater));
   if (Pos != std::end(Features))
 Pos = Features.insert(std::next(Pos), {"+i8mm", "+bf16"});
 
+  // For Armv8.8-a/Armv9.3-a or later, FEAT_HBC and FEAT_MOPS are enabled by
+  // default.
+  const char *v8893OrLater[] = {"+v8.8a", "+v9.3a"};
+  Pos = std::find_first_of(Features.begin(), Features.end(),
+   std::begin(v8893OrLater), std::end(v8893OrLater));
+  if (Pos != std::end(Features))
+Pos = Features.insert(std::next(Pos), {"+hbc", "+mops"});
+
   if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
options::OPT_munaligned_access)) {
 if (A->getOption().matches(options::OPT_mno_unaligned_access))

diff  --git a/clang/test/Driver/aarch64-hbc.c b/clang/test/Driver/aarch64-hbc.c
index 3681542ace471..b25e7c3f52809 100644
--- a/clang/test/Driver/aarch64-hbc.c
+++ b/clang/test/Driver/aarch64-hbc.c
@@ -1,6 +1,12 @@
 // Test that target feature hbc is implemented and available correctly
-// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.8-a+hbc %s 
2>&1 | FileCheck %s
-// CHECK: "-target-feature" "+hbc"
-
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.7-a+hbc   %s 
2>&1 | FileCheck %s
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.8-a   %s 
2>&1 | FileCheck %s
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.8-a+hbc   %s 
2>&1 | FileCheck %s
 // RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.8-a+nohbc %s 
2>&1 | FileCheck %s --check-prefix=NO_HBC
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv9.2-a+hbc   %s 
2>&1 | FileCheck %s
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv9.3-a   %s 
2>&1 | FileCheck %s
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv9.3-a+hbc   %s 
2>&1 | FileCheck %s
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv9.3-a+nohbc %s 
2>&1 | FileCheck %s --check-prefix=NO_HBC
+
+// CHECK: "-target-feature" "+hbc"
 // NO_HBC: "-target-feature" "-hbc"

diff  --git a/clang/test/Driver/aarch64-mops.c 
b/clang/test/Driver/aarch64-mops.c
index 4cd48143033d6..8ce3c21d9ddb3 100644
--- a/clang/test/Driver/aarch64-mops.c
+++ b/clang/test/Driver/aarch64-mops.c
@@ -1,6 +1,12 @@
 // Test that target feature mops is implemented and available correctly
-// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.8-a+mops %s 
2>&1 | FileCheck %s
-// CHECK: "-target-feature" "+mops"
-
+// RUN:

[clang] 9a015ee - [AArch64] Avoid scanning feature list for target parsing

2022-04-02 Thread via cfe-commits

Author: tyb0807
Date: 2022-04-02T14:51:23+01:00
New Revision: 9a015ee1f948755d69dc2ff52e7655229e2eed47

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

LOG: [AArch64] Avoid scanning feature list for target parsing

As discussed in https://reviews.llvm.org/D120111, this patch proposes an
alternative implementation to avoid scanning feature list for
architecture version over and over again. The insertion position for
default extensions is also captured during this single scan of the
feature list.

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

Added: 


Modified: 
clang/lib/Driver/ToolChains/Arch/AArch64.cpp
clang/test/Driver/aarch64-cpus-2.c
clang/test/Preprocessor/aarch64-target-features.c

Removed: 




diff  --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp 
b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
index 1691b7faf668a..d82198ec678bf 100644
--- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
@@ -347,28 +347,85 @@ void aarch64::getAArch64TargetFeatures(const Driver &D,
   Features.push_back("-crc");
   }
 
+  int V8Version = -1;
+  int V9Version = -1;
+  bool HasNoSM4 = false;
+  bool HasNoSHA3 = false;
+  bool HasNoSHA2 = false;
+  bool HasNoAES = false;
+  bool HasSM4 = false;
+  bool HasSHA3 = false;
+  bool HasSHA2 = false;
+  bool HasAES = false;
+  bool HasCrypto = false;
+  bool HasNoCrypto = false;
+  int FullFP16Pos = -1;
+  int NoFullFP16Pos = -1;
+  int FP16FMLPos = -1;
+  int NoFP16FMLPos = -1;
+  int ArchFeatPos = -1;
+
+  for (auto I = Features.begin(), E = Features.end(); I != E; I++) {
+if (*I == "+v8a")   V8Version = 0;
+else if (*I == "+v8.1a") V8Version = 1;
+else if (*I == "+v8.2a") V8Version = 2;
+else if (*I == "+v8.3a") V8Version = 3;
+else if (*I == "+v8.4a") V8Version = 4;
+else if (*I == "+v8.5a") V8Version = 5;
+else if (*I == "+v8.6a") V8Version = 6;
+else if (*I == "+v8.7a") V8Version = 7;
+else if (*I == "+v8.8a") V8Version = 8;
+else if (*I == "+v8.9a") V8Version = 9;
+else if (*I == "+v9a")   V9Version = 0;
+else if (*I == "+v9.1a") V9Version = 1;
+else if (*I == "+v9.2a") V9Version = 2;
+else if (*I == "+v9.3a") V9Version = 3;
+else if (*I == "+v9.4a") V9Version = 4;
+else if (*I == "+sm4")  HasSM4 = true;
+else if (*I == "+sha3") HasSHA3 = true;
+else if (*I == "+sha2") HasSHA2 = true;
+else if (*I == "+aes")  HasAES = true;
+else if (*I == "-sm4")  HasNoSM4 = true;
+else if (*I == "-sha3") HasNoSHA3 = true;
+else if (*I == "-sha2") HasNoSHA2 = true;
+else if (*I == "-aes")  HasNoAES = true;
+else if (*I == "+fp16fml")  FP16FMLPos = I - Features.begin();
+else if (*I == "-fp16fml")  NoFP16FMLPos = I - Features.begin();
+else if (*I == "-fullfp16") NoFullFP16Pos = I - Features.begin();
+else if (*I == "+fullfp16") FullFP16Pos = I - Features.begin();
+// Whichever option comes after (right-most option) will win
+else if (*I == "+crypto") {
+  HasCrypto = true;
+  HasNoCrypto = false;
+} else if (*I == "-crypto") {
+  HasCrypto = false;
+  HasNoCrypto = true;
+}
+// Register the iterator position if this is an architecture feature
+if (ArchFeatPos == -1 && (V8Version != -1 || V9Version != -1))
+  ArchFeatPos = I - Features.begin();
+  }
+
   // Handle (arch-dependent) fp16fml/fullfp16 relationship.
   // FIXME: this fp16fml option handling will be reimplemented after the
   // TargetParser rewrite.
-  const auto ItRNoFullFP16 = std::find(Features.rbegin(), Features.rend(), 
"-fullfp16");
-  const auto ItRFP16FML = std::find(Features.rbegin(), Features.rend(), 
"+fp16fml");
-  if (llvm::is_contained(Features, "+v8.4a")) {
-const auto ItRFullFP16  = std::find(Features.rbegin(), Features.rend(), 
"+fullfp16");
-if (ItRFullFP16 < ItRNoFullFP16 && ItRFullFP16 < ItRFP16FML) {
+  if (V8Version >= 4) {
+// "-fullfp16" "+fullfp16" && "+fp16fml" "+fullfp16" && no "+fullfp16" 
"-fp16fml" = "+fp16fml"
+if (FullFP16Pos > NoFullFP16Pos && FullFP16Pos > FP16FMLPos && FullFP16Pos 
> NoFP16FMLPos)
   // Only entangled feature that can be to the right of this +fullfp16 is 
-fp16fml.
   // Only append the +fp16fml if there is no -fp16fml after the +fullfp16.
-  if (std::find(Features.rbegin(), ItRFullFP16, "-fp16fml") == ItRFullFP16)
-Features.push_back("+fp16fml");
-}
+  Features.push_back("+fp16fml");
 else
   goto fp16_fml_fallthrough;
   } else {
 fp16_fml_fallthrough:
 // In both of these cases, putting the 'other' feature on the end of the 
vector will
 // result in the same effect as placing it immediately after the current 
feature.
-if (ItRNoFullFP16 < ItRFP16FML)

[PATCH] D120111: [AArch64] Default HBC/MOPS features in clang

2022-04-02 Thread Son Tuan Vu via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb93893e60f0c: [AArch64] Default HBC/MOPS features in clang 
(authored by tyb0807).
Herald added a subscriber: MaskRay.
Herald added a project: All.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D120111/new/

https://reviews.llvm.org/D120111

Files:
  clang/lib/Basic/Targets/AArch64.cpp
  clang/lib/Driver/ToolChains/Arch/AArch64.cpp
  clang/test/Driver/aarch64-hbc.c
  clang/test/Driver/aarch64-mops.c
  clang/test/Preprocessor/aarch64-target-features.c

Index: clang/test/Preprocessor/aarch64-target-features.c
===
--- clang/test/Preprocessor/aarch64-target-features.c
+++ clang/test/Preprocessor/aarch64-target-features.c
@@ -524,14 +524,18 @@
 // CHECK-LSE: __ARM_FEATURE_ATOMICS 1
 
 // == Check Armv8.8-A/Armv9.3-A memcpy and memset acceleration instructions (MOPS)
-// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.7-a  -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-NOMOPS %s
-// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.7-a+mops -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-MOPS   %s
-// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.8-a  -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-MOPS   %s
-// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.8-a+mops -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-MOPS   %s
-// RUN: %clang -target aarch64-arm-none-eabi -march=armv9.2-a  -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-NOMOPS %s
-// RUN: %clang -target aarch64-arm-none-eabi -march=armv9.2-a+mops -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-MOPS   %s
-// RUN: %clang -target aarch64-arm-none-eabi -march=armv9.3-a  -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-MOPS   %s
-// RUN: %clang -target aarch64-arm-none-eabi -march=armv9.3-a+mops -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-MOPS   %s
+// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.7-a -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-NOMOPS %s
+// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.7-a+mops-x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-MOPS   %s
+// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.8-a -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-MOPS   %s
+// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.8-a+nomops  -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-NOMOPS %s
+// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.8-a+nomops+mops -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-MOPS   %s
+// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.8-a+mops-x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-MOPS   %s
+// RUN: %clang -target aarch64-arm-none-eabi -march=armv8.8-a+mops+nomops -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-NOMOPS %s
+// RUN: %clang -target aarch64-arm-none-eabi -march=armv9.2-a -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-NOMOPS %s
+// RUN: %clang -target aarch64-arm-none-eabi -march=armv9.2-a+mops-x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-MOPS   %s
+// RUN: %clang -target aarch64-arm-none-eabi -march=armv9.3-a -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-MOPS   %s
+// RUN: %clang -target aarch64-arm-none-eabi -march=armv9.3-a+nomops  -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-NOMOPS %s
+// RUN: %clang -target aarch64-arm-none-eabi -march=armv9.3-a+mops-x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-MOPS   %s
 // CHECK-MOPS: __ARM_FEATURE_MOPS 1
 // CHECK-NOMOPS-NOT: __ARM_FEATURE_MOPS 1
 
Index: clang/test/Driver/aarch64-mops.c
===
--- clang/test/Driver/aarch64-mops.c
+++ clang/test/Driver/aarch64-mops.c
@@ -1,6 +1,12 @@
 // Test that target feature mops is implemented and available correctly
-// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.8-a+mops %s 2>&1 | FileCheck %s
-// CHECK: "-target-feature" "+mops"
-
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.7-a+mops   %s 2>&1 | FileCheck %s
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.8-a%s 2>&1 | FileCheck %s
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.8-a+mops   %s 2>&1 | FileCheck %s
 // RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.8-a+nomops %s 2>&1 | FileCheck %s --check-prefix=NO_MOPS
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv9.2-a+mops   %s 2>&1 | FileCheck %s
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv9.3-a%s 2>&1 | FileCheck %s
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv9.3-a+mops   %s 2>&1 | FileCheck %s
+// RUN: %clang -### -target aarch64-none

[PATCH] D120864: [AArch64] Avoid scanning feature list for target parsing

2022-04-02 Thread Son Tuan Vu via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG9a015ee1f948: [AArch64] Avoid scanning feature list for 
target parsing (authored by tyb0807).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D120864/new/

https://reviews.llvm.org/D120864

Files:
  clang/lib/Driver/ToolChains/Arch/AArch64.cpp
  clang/test/Driver/aarch64-cpus-2.c
  clang/test/Preprocessor/aarch64-target-features.c

Index: clang/test/Preprocessor/aarch64-target-features.c
===
--- clang/test/Preprocessor/aarch64-target-features.c
+++ clang/test/Preprocessor/aarch64-target-features.c
@@ -294,7 +294,7 @@
 // CHECK-MCPU-CARMEL: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.2a" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+fullfp16" "-target-feature" "+ras" "-target-feature" "+lse" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+aes"
 
 // 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" "+v8.5a" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+dotprod" "-target-feature" "+fp16fml" "-target-feature" "+ras" "-target-feature" "+lse" "-target-feature" "+rdm" "-target-feature" "+rcpc" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+fullfp16" "-target-feature" "+sm4" "-target-feature" "+sha3" "-target-feature" "+sha2" "-target-feature" "+aes"
+// CHECK-ARCH-ARM64: "-target-cpu" "apple-m1" "-target-feature" "+v8.5a" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+dotprod" "-target-feature" "+fullfp16" "-target-feature" "+ras" "-target-feature" "+lse" "-target-feature" "+rdm" "-target-feature" "+rcpc" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+fp16fml" "-target-feature" "+sm4" "-target-feature" "+sha3" "-target-feature" "+sha2" "-target-feature" "+aes"
 
 // RUN: %clang -target x86_64-apple-macosx -arch arm64_32 -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-ARCH-ARM64_32 %s
 // CHECK-ARCH-ARM64_32: "-target-cpu" "apple-s4" "-target-feature" "+v8.3a" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+fullfp16" "-target-feature" "+ras" "-target-feature" "+lse" "-target-feature" "+rdm" "-target-feature" "+rcpc" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+sha2" "-target-feature" "+aes"
Index: clang/test/Driver/aarch64-cpus-2.c
===
--- clang/test/Driver/aarch64-cpus-2.c
+++ clang/test/Driver/aarch64-cpus-2.c
@@ -193,6 +193,122 @@
 // RUN: %clang -target aarch64 -march=armv8.4-a+nofp16+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-NO-FP16-FP16FML %s
 // GENERICV84A-NO-FP16-FP16FML: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
 
+// RUN: %clang -target aarch64 -march=armv8.5a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-NO-FP16FML %s
+// RUN: %clang -target aarch64 -march=armv8.5-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-NO-FP16FML %s
+// GENERICV85A-NO-FP16FML-NOT: "-target-feature" "{{[+-]}}fp16fml"
+// GENERICV85A-NO-FP16FML-NOT: "-target-feature" "{{[+-]}}fullfp16"
+
+// RUN: %clang -target aarch64 -march=armv8.5a+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-FP16 %s
+// RUN: %clang -target aarch64 -march=armv8.5-a+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-FP16 %s
+// GENERICV85A-FP16: "-target-feature" "+fullfp16" "-target-feature" "+fp16fml"
+
+// RUN: %clang -target aarch64 -march=armv8.5a+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-FP16FML %s
+// RUN: %clang -target aarch64 -march=armv8.5-a+fp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-FP16FML %s
+// GENERICV85A-FP16FML: "-target-feature" "+fp16fml" "-target-feature" "+fullfp16"
+
+// RUN: %clang -target aarch64 -march=armv8.5a+fp16+nofp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-FP16-NO-FP16FML %s
+// RUN: %clang -target aarch64 -march=armv8.5-a+fp16+nofp16fml -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-FP16-NO-FP16FML %s
+// GENERICV85A-FP16-NO-FP16FML: "-target-feature" "+fullfp16" "-target-feature" "-fp16fml"
+
+// RUN: %clang -target aarch64 -march=armv8.5a+nofp16fml+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-NO-FP16FML-FP16 %s
+// RUN: %clang -target aarch64 -march=armv8.5-a+nofp16fml+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV85A-NO-FP16FML-FP16 %s
+// GENERICV85A-NO-FP16FML-FP16: "-target-feature" "+

[PATCH] D122768: [Clang][C++20] Support capturing structured bindings in lambdas

2022-04-02 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin updated this revision to Diff 419980.
cor3ntin added a comment.

Rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122768/new/

https://reviews.llvm.org/D122768

Files:
  clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/AST/LambdaCapture.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/ScopeInfo.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/DeclCXX.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/Analysis/AnalysisDeclContext.cpp
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/Sema/ScopeInfo.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp
  clang/test/CodeGenCXX/cxx20-decomposition.cpp
  clang/test/SemaCXX/cxx1z-decomposition.cpp
  clang/test/SemaCXX/cxx20-decomposition.cpp
  clang/test/SemaCXX/decomposition-blocks.cpp
  clang/test/SemaCXX/decomposition-openmp.cpp
  clang/tools/libclang/CIndex.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1144,7 +1144,7 @@
 
   Structured binding extensions
   https://wg21.link/p1091r3";>P1091R3
-  Partial
+  Clang 15
 
   
 https://wg21.link/p1381r1";>P1381R1
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -3350,9 +3350,11 @@
C != CEnd; ++C) {
 if (!C->capturesVariable())
   continue;
-
-if (Visit(MakeCursorVariableRef(C->getCapturedVar(), C->getLocation(),
-TU)))
+// TODO: hamdle structured bindings here ?
+if (!isa(C->getCapturedVar()))
+  continue;
+if (Visit(MakeCursorVariableRef(cast(C->getCapturedVar()),
+C->getLocation(), TU)))
   return true;
   }
   // Visit init captures
Index: clang/test/SemaCXX/decomposition-openmp.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/decomposition-openmp.cpp
@@ -0,0 +1,13 @@
+
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 -fopenmp %s
+
+// FIXME: OpenMP should support capturing structured bindings
+auto f() {
+  int i[2] = {};
+  auto [a, b] = i; // expected-note 2{{declared here}}
+  return [=, &a] {
+// expected-error@-1 {{capturing a structured binding is not yet supported in OpenMP}}
+return a + b;
+// expected-error@-1 {{capturing a structured binding is not yet supported in OpenMP}}
+  };
+}
Index: clang/test/SemaCXX/decomposition-blocks.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/decomposition-blocks.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s -fblocks
+
+struct S {
+  int i : 1;
+  int j;
+};
+
+void run(void (^)());
+void test() {
+  auto [i, j] = S{1, 42}; // expected-note {{'i' declared here}}
+  run(^{
+(void)i; // expected-error {{reference to local binding 'i' declared in enclosing function 'test'}}
+  });
+}
Index: clang/test/SemaCXX/cxx20-decomposition.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/cxx20-decomposition.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
+// expected-no-diagnostics
+
+template 
+constexpr bool is_same = false;
+template 
+constexpr bool is_same = true;
+
+struct S {
+  int i;
+  int &j;
+};
+
+void check_category() {
+  int a = 42;
+  {
+auto [v, r] = S{1, a};
+(void)[ v, r ] {
+  static_assert(is_same);
+  static_assert(is_same);
+};
+  }
+  {
+auto [v, r] = S{1, a};
+(void)[&v, &r ] {
+  static_assert(is_same);
+  static_assert(is_same);
+};
+  }
+  {
+S s{1, a};
+const auto &[v, r] = s;
+(void)[ v, r ] {
+  static_assert(is_same);
+  static_assert(is_same);
+};
+  }
+  {
+S s{1, a};
+const auto &[v, r] = s;
+(void)[&v,

[PATCH] D122768: [Clang][C++20] Support capturing structured bindings in lambdas

2022-04-02 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin updated this revision to Diff 419988.
cor3ntin added a comment.

Better codegen test


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122768/new/

https://reviews.llvm.org/D122768

Files:
  clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/AST/LambdaCapture.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/ScopeInfo.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/DeclCXX.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/Analysis/AnalysisDeclContext.cpp
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/Sema/ScopeInfo.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp
  clang/test/CodeGenCXX/cxx20-decomposition.cpp
  clang/test/SemaCXX/cxx1z-decomposition.cpp
  clang/test/SemaCXX/cxx20-decomposition.cpp
  clang/test/SemaCXX/decomposition-blocks.cpp
  clang/test/SemaCXX/decomposition-openmp.cpp
  clang/tools/libclang/CIndex.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1144,7 +1144,7 @@
 
   Structured binding extensions
   https://wg21.link/p1091r3";>P1091R3
-  Partial
+  Clang 15
 
   
 https://wg21.link/p1381r1";>P1381R1
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -3350,9 +3350,11 @@
C != CEnd; ++C) {
 if (!C->capturesVariable())
   continue;
-
-if (Visit(MakeCursorVariableRef(C->getCapturedVar(), C->getLocation(),
-TU)))
+// TODO: hamdle structured bindings here ?
+if (!isa(C->getCapturedVar()))
+  continue;
+if (Visit(MakeCursorVariableRef(cast(C->getCapturedVar()),
+C->getLocation(), TU)))
   return true;
   }
   // Visit init captures
Index: clang/test/SemaCXX/decomposition-openmp.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/decomposition-openmp.cpp
@@ -0,0 +1,13 @@
+
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 -fopenmp %s
+
+// FIXME: OpenMP should support capturing structured bindings
+auto f() {
+  int i[2] = {};
+  auto [a, b] = i; // expected-note 2{{declared here}}
+  return [=, &a] {
+// expected-error@-1 {{capturing a structured binding is not yet supported in OpenMP}}
+return a + b;
+// expected-error@-1 {{capturing a structured binding is not yet supported in OpenMP}}
+  };
+}
Index: clang/test/SemaCXX/decomposition-blocks.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/decomposition-blocks.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s -fblocks
+
+struct S {
+  int i : 1;
+  int j;
+};
+
+void run(void (^)());
+void test() {
+  auto [i, j] = S{1, 42}; // expected-note {{'i' declared here}}
+  run(^{
+(void)i; // expected-error {{reference to local binding 'i' declared in enclosing function 'test'}}
+  });
+}
Index: clang/test/SemaCXX/cxx20-decomposition.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/cxx20-decomposition.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
+// expected-no-diagnostics
+
+template 
+constexpr bool is_same = false;
+template 
+constexpr bool is_same = true;
+
+struct S {
+  int i;
+  int &j;
+};
+
+void check_category() {
+  int a = 42;
+  {
+auto [v, r] = S{1, a};
+(void)[ v, r ] {
+  static_assert(is_same);
+  static_assert(is_same);
+};
+  }
+  {
+auto [v, r] = S{1, a};
+(void)[&v, &r ] {
+  static_assert(is_same);
+  static_assert(is_same);
+};
+  }
+  {
+S s{1, a};
+const auto &[v, r] = s;
+(void)[ v, r ] {
+  static_assert(is_same);
+  static_assert(is_same);
+};
+  }
+  {
+S s{1, a};
+const auto &[v, r] = s;
+ 

[PATCH] D72742: Don't assume promotable integers are zero/sign-extended already in x86-64 ABI.

2022-04-02 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri added a comment.
Herald added subscribers: StephenFan, sstefan1.
Herald added a project: All.

Passing-by remark: i'm not sure it was noted already,
but i believe that the function linkage should be differentiated here,
the ABI mismatch can only exist if the function can actually be called
from the external code, which isn't always the case.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72742/new/

https://reviews.llvm.org/D72742

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


[PATCH] D122981: [Clang] Diagnose incomplete return/param types only when function is not deleted

2022-04-02 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao created this revision.
rZhBoYao added reviewers: ChuanqiXu, rsmith.
rZhBoYao added a project: clang.
Herald added a project: All.
rZhBoYao requested review of this revision.
Herald added a subscriber: cfe-commits.

According to dcl.fct.def.general p2 
 and this 
,
 deleted functions with incomplete return types and parameter types are 
well-formed.

  struct Incomplete;   // expected-note{{forward declaration of 
'Incomplete'}}
  Incomplete f() = delete; // well-formed
  Incomplete g(Incomplete a) = delete; // well-formed
  Incomplete h() {}// expected-error{{incomplete result 
type 'Incomplete' in function definition}}

Inspired by this tweet 
.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122981

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.cpp

Index: clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.cpp
===
--- /dev/null
+++ clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct Incomplete;   // expected-note{{forward declaration of 'Incomplete'}}
+Incomplete f() = delete; // well-formed
+Incomplete g(Incomplete a) = delete; // well-formed
+Incomplete h() {}// expected-error{{incomplete result type 'Incomplete' in function definition}}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -14169,7 +14169,7 @@
 Decl *
 Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D,
   MultiTemplateParamsArg TemplateParameterLists,
-  SkipBodyInfo *SkipBody) {
+  SkipBodyInfo *SkipBody, bool FnDeleted) {
   assert(getCurFunctionDecl() == nullptr && "Function parsing confused");
   assert(D.isFunctionDeclarator() && "Not a function declarator!");
   Scope *ParentScope = FnBodyScope->getParent();
@@ -14188,7 +14188,7 @@
 
   D.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
   Decl *DP = HandleDeclarator(ParentScope, D, TemplateParameterLists);
-  Decl *Dcl = ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody);
+  Decl *Dcl = ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody, FnDeleted);
 
   if (!Bases.empty())
 ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Dcl, Bases);
@@ -14364,7 +14364,7 @@
 }
 
 Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
-SkipBodyInfo *SkipBody) {
+SkipBodyInfo *SkipBody, bool FnDeleted) {
   if (!D) {
 // Parsing the function declaration failed in some way. Push on a fake scope
 // anyway so we can try to parse the function body.
@@ -14454,10 +14454,11 @@
   }
 
   // The return type of a function definition must be complete
-  // (C99 6.9.1p3, C++ [dcl.fct]p6).
+  // unless the function is deleted
+  // (C99 6.9.1p3, C++ [dcl.fct.def.general]p2).
   QualType ResultType = FD->getReturnType();
   if (!ResultType->isDependentType() && !ResultType->isVoidType() &&
-  !FD->isInvalidDecl() &&
+  !FD->isInvalidDecl() && !FnDeleted &&
   RequireCompleteType(FD->getLocation(), ResultType,
   diag::err_func_def_incomplete_result))
 FD->setInvalidDecl();
@@ -14465,9 +14466,10 @@
   if (FnBodyScope)
 PushDeclContext(FnBodyScope, FD);
 
-  // Check the validity of our function parameters
-  CheckParmsForFunctionDef(FD->parameters(),
-   /*CheckParameterNames=*/true);
+  if (!FnDeleted)
+// Check the validity of our function parameters
+CheckParmsForFunctionDef(FD->parameters(),
+ /*CheckParameterNames=*/true);
 
   // Add non-parameter declarations already in the function to the current
   // scope.
Index: clang/lib/Parse/Parser.cpp
===
--- clang/lib/Parse/Parser.cpp
+++ clang/lib/Parse/Parser.cpp
@@ -1302,11 +1302,15 @@
   // Tell the actions module that we have entered a function definition with the
   // specified Declarator for the function.
   Sema::SkipBodyInfo SkipBody;
+  bool FnDeleted = GetLookAheadToken(0).getKind() == tok::equal &&
+   GetLookAheadToken(1).getKind() == tok::kw_delete
+   ? true
+   : false;
   Decl *Res = Actions.ActOnStartOfFunctionDef(getCurScope(), D,
   T

[PATCH] D122865: [HLSL][clang][Driver] Support target profile command line option.

2022-04-02 Thread Xiang Li via Phabricator via cfe-commits
python3kgae updated this revision to Diff 419991.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122865/new/

https://reviews.llvm.org/D122865

Files:
  clang/include/clang/Basic/DiagnosticDriverKinds.td
  clang/include/clang/Driver/Driver.h
  clang/include/clang/Driver/Options.h
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/CMakeLists.txt
  clang/lib/Driver/Driver.cpp
  clang/lib/Driver/ToolChain.cpp
  clang/lib/Driver/ToolChains/HLSL.cpp
  clang/lib/Driver/ToolChains/HLSL.h
  clang/lib/Driver/Types.cpp
  clang/test/lit.cfg.py
  clang/unittests/Driver/ToolChainTest.cpp

Index: clang/unittests/Driver/ToolChainTest.cpp
===
--- clang/unittests/Driver/ToolChainTest.cpp
+++ clang/unittests/Driver/ToolChainTest.cpp
@@ -300,6 +300,12 @@
   EXPECT_TRUE(Res.ModeSuffix == "clang-cl");
   EXPECT_STREQ(Res.DriverMode, "--driver-mode=cl");
   EXPECT_FALSE(Res.TargetIsValid);
+
+  Res = ToolChain::getTargetAndModeFromProgramName("clang-dxc");
+  EXPECT_TRUE(Res.TargetPrefix.empty());
+  EXPECT_TRUE(Res.ModeSuffix == "clang-dxc");
+  EXPECT_STREQ(Res.DriverMode, "--driver-mode=dxc");
+  EXPECT_FALSE(Res.TargetIsValid);
 }
 
 TEST(ToolChainTest, CommandOutput) {
@@ -361,4 +367,141 @@
   EXPECT_EQ(getDriverMode(Args[0], llvm::makeArrayRef(Args).slice(1)), "bar");
 }
 
+TEST(DxcModeTest, TargetProfileValidation) {
+  IntrusiveRefCntPtr DiagID(new DiagnosticIDs());
+  struct SimpleDiagnosticConsumer : public DiagnosticConsumer {
+void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+  const Diagnostic &Info) override {
+  if (DiagLevel == DiagnosticsEngine::Level::Error) {
+Errors.emplace_back();
+Info.FormatDiagnostic(Errors.back());
+  } else {
+Msgs.emplace_back();
+Info.FormatDiagnostic(Msgs.back());
+  }
+}
+void clear() override {
+  Msgs.clear();
+  Errors.clear();
+  DiagnosticConsumer::clear();
+}
+std::vector> Msgs;
+std::vector> Errors;
+  };
+
+  IntrusiveRefCntPtr InMemoryFileSystem(
+  new llvm::vfs::InMemoryFileSystem);
+
+  InMemoryFileSystem->addFile("foo.hlsl", 0,
+  llvm::MemoryBuffer::getMemBuffer("\n"));
+
+  auto *DiagConsumer = new SimpleDiagnosticConsumer;
+  IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions();
+  DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagConsumer);
+  Driver TheDriver("/bin/clang", "", Diags, "", InMemoryFileSystem);
+  std::unique_ptr C(
+  TheDriver.BuildCompilation({"clang", "--driver-mode=dxc", "foo.hlsl"}));
+  EXPECT_TRUE(C);
+  EXPECT_TRUE(!C->containsError());
+
+  auto &TC = C->getDefaultToolChain();
+  bool ContainsError = false;
+  auto Args = TheDriver.ParseArgStrings({"-Tvs_6_0"}, false, ContainsError);
+  EXPECT_FALSE(ContainsError);
+  auto Triple = TC.ComputeEffectiveClangTriple(Args);
+  EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.0-vertex");
+  EXPECT_EQ(Diags.getNumErrors(), 0);
+
+  Args = TheDriver.ParseArgStrings({"-Ths_6_1"}, false, ContainsError);
+  EXPECT_FALSE(ContainsError);
+  Triple = TC.ComputeEffectiveClangTriple(Args);
+  EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.1-hull");
+  EXPECT_EQ(Diags.getNumErrors(), 0);
+
+  Args = TheDriver.ParseArgStrings({"-Tds_6_2"}, false, ContainsError);
+  EXPECT_FALSE(ContainsError);
+  Triple = TC.ComputeEffectiveClangTriple(Args);
+  EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.2-domain");
+  EXPECT_EQ(Diags.getNumErrors(), 0);
+
+  Args = TheDriver.ParseArgStrings({"-Tds_6_2"}, false, ContainsError);
+  EXPECT_FALSE(ContainsError);
+  Triple = TC.ComputeEffectiveClangTriple(Args);
+  EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.2-domain");
+  EXPECT_EQ(Diags.getNumErrors(), 0);
+
+  Args = TheDriver.ParseArgStrings({"-Tgs_6_3"}, false, ContainsError);
+  EXPECT_FALSE(ContainsError);
+  Triple = TC.ComputeEffectiveClangTriple(Args);
+  EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.3-geometry");
+  EXPECT_EQ(Diags.getNumErrors(), 0);
+
+  Args = TheDriver.ParseArgStrings({"-Tps_6_4"}, false, ContainsError);
+  EXPECT_FALSE(ContainsError);
+  Triple = TC.ComputeEffectiveClangTriple(Args);
+  EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.4-pixel");
+  EXPECT_EQ(Diags.getNumErrors(), 0);
+
+  Args = TheDriver.ParseArgStrings({"-Tcs_6_5"}, false, ContainsError);
+  EXPECT_FALSE(ContainsError);
+  Triple = TC.ComputeEffectiveClangTriple(Args);
+  EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.5-compute");
+  EXPECT_EQ(Diags.getNumErrors(), 0);
+
+  Args = TheDriver.ParseArgStrings({"-Tms_6_6"}, false, ContainsError);
+  EXPECT_FALSE(ContainsError);
+  Triple = TC.ComputeEffectiveClangTriple(Args);
+  EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.6-mesh");
+  EXPECT_EQ(Diags.getNumErrors(), 0);
+
+  Args = TheDriver.ParseArgStrings({"-Tas_6_7"}, false, ContainsError);
+  EXPECT_FALSE(ContainsError);
+  Triple = TC.Comput

[PATCH] D122983: [C11/C2x] Change the behavior of the implicit function declaration warning

2022-04-02 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman created this revision.
aaron.ballman added reviewers: jyknight, eli.friedman, rjmccall, erichkeane, 
clang-language-wg.
Herald added subscribers: usaxena95, pengfei, kadircet, arphaman.
Herald added a project: All.
aaron.ballman requested review of this revision.
Herald added projects: clang, clang-tools-extra.

C89 had a questionable feature where the compiler would implicitly declare a 
function that the user called but was never previously declared. The resulting 
function would be globally declared as `extern int func();` -- a function 
without a prototype which accepts zero or more arguments.

C99 removed support for this questionable feature due to severe security 
concerns. However, there was no deprecation period; C89 had the feature, C99 
didn't. So Clang (and GCC) both supported the functionality as an extension in 
C99 and later modes.

C2x no longer supports that function signature as it now requires all functions 
to have a prototype, and given the known security issues with the feature, 
continuing to support it as an extension is not tenable.

This patch changes the diagnostic behavior for the 
`-Wimplicit-function-declaration` warning group depending on the language mode 
in effect. We continue to warn by default in C89 mode (due to the feature being 
dangerous to use), and we continue to warn by default as an extension in C99 
mode (due to the lack of a deprecation period). However, because this feature 
will not be supported in C2x mode, the security concerns with the feature, and 
the trivial workaround for users (declare the function), we now default the 
extension warning to an error in C11 and C17 mode. This still gives users an 
easy workaround if they are extensively using the extension in those modes 
(they can disable the warning or use `-Wno-error` to downgrade the error), but 
the new diagnostic makes it more clear that this feature is not supported in 
C2x and should be avoided. In C2x mode, we no longer allow an implicit function 
to be defined and treat the situation the same as any other lookup failure.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122983

Files:
  clang-tools-extra/clangd/IncludeFixer.cpp
  clang-tools-extra/clangd/ParsedAST.cpp
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/ARCMT/objcmt-arc-cf-annotations.m
  clang/test/ARCMT/objcmt-arc-cf-annotations.m.result
  clang/test/Analysis/OSAtomic_mac.c
  clang/test/Analysis/ObjCProperties.m
  clang/test/Analysis/PR49642.c
  clang/test/Analysis/diagnostics/no-store-func-path-notes.c
  clang/test/Analysis/misc-ps-region-store.m
  clang/test/Analysis/novoidtypecrash.c
  clang/test/Analysis/plist-macros-with-expansion.c
  clang/test/CodeGen/2002-07-14-MiscTests3.c
  clang/test/CodeGen/2002-07-31-SubregFailure.c
  clang/test/CodeGen/2003-08-18-SigSetJmp.c
  clang/test/CodeGen/2004-11-27-StaticFunctionRedeclare.c
  clang/test/CodeGen/2005-01-02-ConstantInits.c
  clang/test/CodeGen/2005-01-02-VAArgError-ICE.c
  clang/test/CodeGen/2006-01-13-StackSave.c
  clang/test/CodeGen/2006-03-03-MissingInitializer.c
  clang/test/CodeGen/2008-05-12-TempUsedBeforeDef.c
  clang/test/CodeGen/2008-07-30-redef-of-bitcasted-decl.c
  clang/test/CodeGen/2008-08-19-cast-of-typedef.c
  clang/test/CodeGen/2008-10-13-FrontendCrash.c
  clang/test/CodeGen/X86/bmi2-builtins.c
  clang/test/CodeGen/aarch64-mops.c
  clang/test/CodeGen/attribute_constructor.c
  clang/test/CodeGen/cast-emit.c
  clang/test/CodeGen/debug-info-block-vars.c
  clang/test/CodeGen/debug-info-crash.c
  clang/test/CodeGen/decl.c
  clang/test/CodeGen/init-with-member-expr.c
  clang/test/CodeGen/misaligned-param.c
  clang/test/CodeGen/struct-comma.c
  clang/test/CodeGen/variable-array.c
  clang/test/Frontend/warning-mapping-2.c
  clang/test/Headers/arm-cmse-header-ns.c
  clang/test/Import/objc-arc/test-cleanup-object.m
  clang/test/Modules/config_macros.m
  clang/test/Modules/modulemap-locations.m
  clang/test/OpenMP/declare_mapper_messages.c
  clang/test/PCH/chain-macro-override.c
  clang/test/Rewriter/rewrite-foreach-2.m
  clang/test/Rewriter/rewrite-try-catch.m
  clang/test/Sema/__try.c
  clang/test/Sema/aarch64-tme-errors.c
  clang/test/Sema/bitfield.c
  clang/test/Sema/builtin-setjmp.c
  clang/test/Sema/builtins.c
  clang/test/Sema/cxx-as-c.c
  clang/test/Sema/implicit-builtin-decl.c
  clang/test/Sema/implicit-decl.c
  clang/test/Sema/implicit-ms-builtin-decl.c
  clang/test/Sema/typo-correction.c
  clang/test/Sema/vla.c
  clang/test/Sema/warn-strict-prototypes.c
  clang/test/VFS/module_missing_vfs.m

Index: clang/test/VFS/module_missing_vfs.m
===
--- clang/test/VFS/module_missing_vfs.m
+++ clang/test/VFS/module_missing_vfs.m
@@ -1,12 +1,12 @@
 // RUN: rm -rf %t && mkdir -p %t
 // RUN: echo "void funcA(void);" >> %t/a.h
 
-// RUN: not %clang_cc1 -fmodules -fimplicit-module

[PATCH] D122983: [C11/C2x] Change the behavior of the implicit function declaration warning

2022-04-02 Thread Dávid Bolvanský via Phabricator via cfe-commits
xbolva00 added inline comments.



Comment at: clang/docs/ReleaseNotes.rst:114
+- The ``-Wimplicit-function-declaration`` warning diagnostic now defaults to
+  emitting an error (which can be downgraded with ``-Wno-error``) in C11 and
+  C17 mode. This is because the feature was removed in C99 and cannot be

I would mention explicitly  -Wno-error= implicit-function-declaration as 
-Wno-error is a big hammer.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122983/new/

https://reviews.llvm.org/D122983

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


[PATCH] D122952: [clang] NFC: Extend comdat validation in target multiversion function tests.

2022-04-02 Thread Tom Honermann via Phabricator via cfe-commits
tahonermann created this revision.
tahonermann added reviewers: erichkeane, aaron.ballman.
Herald added a project: All.
tahonermann added inline comments.
tahonermann published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.



Comment at: clang/test/CodeGen/attr-target-mv.c:95-111
+// WINDOWS: $foo_used = comdat any
+// WINDOWS: $foo_used2.avx_sse4.2 = comdat any
+// WINDOWS: $pr50025.resolver = comdat any
+// WINDOWS: $pr50025c.resolver = comdat any
+// WINDOWS: $foo_inline.sse4.2 = comdat any
+// WINDOWS: $foo_inline.arch_ivybridge = comdat any
+// WINDOWS: $foo_inline = comdat any

The non-inline non-resolver cases here are surprising to me; they aren't COMDAT 
on Linux. Is this intentional?



Comment at: clang/test/CodeGen/attr-target-mv.c:369-380
+// LINUX: call void @pr50025b.ifunc()
+// WINDOWS: define linkonce_odr dso_local void @pr50025c() #{{[0-9]*}} comdat
+// WINDOWS: call void @pr50025b.resolver()
+
+// LINUX: define weak_odr void ()* @pr50025b.resolver() comdat
+// LINUX: ret void ()* @pr50025b
 // LINUX: define linkonce void @pr50025b()

These additions add validation that was previously missing.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122952

Files:
  clang/test/CodeGen/attr-target-mv.c


Index: clang/test/CodeGen/attr-target-mv.c
===
--- clang/test/CodeGen/attr-target-mv.c
+++ clang/test/CodeGen/attr-target-mv.c
@@ -76,9 +76,45 @@
 inline __attribute__((target("default"))) void pr50025c(void) { pr50025b(); }
 void calls_pr50025c(void) { pr50025c(); }
 
+// LINUX: $foo.resolver = comdat any
+// LINUX: $foo_inline.resolver = comdat any
+// LINUX: $foo_decls.resolver = comdat any
+// LINUX: $foo_multi.resolver = comdat any
+// LINUX: $fwd_decl_default.resolver = comdat any
+// LINUX: $fwd_decl_avx.resolver = comdat any
+// LINUX: $pr50025.resolver = comdat any
+// LINUX: $pr50025c.resolver = comdat any
+// LINUX: $pr50025b.resolver = comdat any
+
+// WINDOWS: $foo.resolver = comdat any
+// WINDOWS: $foo_inline.resolver = comdat any
+// WINDOWS: $foo_decls.resolver = comdat any
+// WINDOWS: $foo_multi.resolver = comdat any
+// WINDOWS: $fwd_decl_default.resolver = comdat any
+// WINDOWS: $fwd_decl_avx.resolver = comdat any
+// WINDOWS: $foo_used = comdat any
+// WINDOWS: $foo_used2.avx_sse4.2 = comdat any
+// WINDOWS: $pr50025.resolver = comdat any
+// WINDOWS: $pr50025c.resolver = comdat any
+// WINDOWS: $foo_inline.sse4.2 = comdat any
+// WINDOWS: $foo_inline.arch_ivybridge = comdat any
+// WINDOWS: $foo_inline = comdat any
+// WINDOWS: $foo_decls = comdat any
+// WINDOWS: $foo_decls.sse4.2 = comdat any
+// WINDOWS: $foo_multi = comdat any
+// WINDOWS: $foo_multi.avx_sse4.2 = comdat any
+// WINDOWS: $foo_multi.fma4_sse4.2 = comdat any
+// WINDOWS: $foo_multi.arch_ivybridge_fma4_sse4.2 = comdat any
+// WINDOWS: $pr50025 = comdat any
+// WINDOWS: $pr50025c = comdat any
+// WINDOWS: $pr50025b.resolver = comdat any
+// WINDOWS: $pr50025b = comdat any
+
+
 // LINUX: @llvm.compiler.used = appending global [2 x i8*] [i8* bitcast (void 
(i32, double)* @foo_used to i8*), i8* bitcast (void (i32, double)* 
@foo_used2.avx_sse4.2 to i8*)], section "llvm.metadata"
 // WINDOWS: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32, 
double)* @foo_used to i8*), i8* bitcast (void (i32, double)* 
@foo_used2.avx_sse4.2 to i8*)], section "llvm.metadata"
 
+
 // LINUX: @foo.ifunc = weak_odr ifunc i32 (), i32 ()* ()* @foo.resolver
 // LINUX: @foo_inline.ifunc = weak_odr ifunc i32 (), i32 ()* ()* 
@foo_inline.resolver
 // LINUX: @foo_decls.ifunc = weak_odr ifunc void (), void ()* ()* 
@foo_decls.resolver
@@ -325,11 +361,20 @@
 // LINUX: define linkonce void @pr50025()
 // LINUX: call void @must_be_emitted
 // LINUX: define internal void @must_be_emitted()
-// WINDOWS: define linkonce_odr dso_local void @pr50025()
+// WINDOWS: define linkonce_odr dso_local void @pr50025() #{{[0-9]*}} comdat
 // WINDOWS: call void @must_be_emitted
 // WINDOWS: define internal void @must_be_emitted()
 
 // LINUX: define linkonce void @pr50025c()
+// LINUX: call void @pr50025b.ifunc()
+// WINDOWS: define linkonce_odr dso_local void @pr50025c() #{{[0-9]*}} comdat
+// WINDOWS: call void @pr50025b.resolver()
+
+// LINUX: define weak_odr void ()* @pr50025b.resolver() comdat
+// LINUX: ret void ()* @pr50025b
 // LINUX: define linkonce void @pr50025b()
-// WINDOWS: define linkonce_odr dso_local void @pr50025c()
-// WINDOWS: define linkonce_odr dso_local void @pr50025b()
+// LINUX: call void @must_be_emitted()
+// WINDOWS: define weak_odr dso_local void @pr50025b.resolver() comdat
+// WINDOWS: musttail call void @pr50025b()
+// WINDOWS: define linkonce_odr dso_local void @pr50025b() #{{[0-9]*}} comdat
+// WINDOWS: call void @must_be_emitted()


Index: clang/test/CodeGen/attr-target-mv.c
===

[PATCH] D122953: [clang] Emit target_clones resolver functions as COMDAT.

2022-04-02 Thread Tom Honermann via Phabricator via cfe-commits
tahonermann created this revision.
tahonermann added reviewers: erichkeane, aaron.ballman.
Herald added a project: All.
tahonermann published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Previously, resolver functions synthesized for target_clones multiversion
functions were not emitted as COMDAT. Now fixed.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122953

Files:
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGen/attr-target-clones.c

Index: clang/test/CodeGen/attr-target-clones.c
===
--- clang/test/CodeGen/attr-target-clones.c
+++ clang/test/CodeGen/attr-target-clones.c
@@ -1,6 +1,18 @@
 // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=LINUX,CHECK
 // RUN: %clang_cc1 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefixes=WINDOWS,CHECK
 
+// LINUX: $foo.resolver = comdat any
+// LINUX: $foo_dupes.resolver = comdat any
+// LINUX: $unused.resolver = comdat any
+// LINUX: $foo_inline.resolver = comdat any
+// LINUX: $foo_inline2.resolver = comdat any
+
+// WINDOWS: $foo = comdat any
+// WINDOWS: $foo_dupes = comdat any
+// WINDOWS: $unused = comdat any
+// WINDOWS: $foo_inline = comdat any
+// WINDOWS: $foo_inline2 = comdat any
+
 // LINUX: @foo.ifunc = weak_odr ifunc i32 (), i32 ()* ()* @foo.resolver
 // LINUX: @foo_dupes.ifunc = weak_odr ifunc void (), void ()* ()* @foo_dupes.resolver
 // LINUX: @unused.ifunc = weak_odr ifunc void (), void ()* ()* @unused.resolver
@@ -10,26 +22,26 @@
 int __attribute__((target_clones("sse4.2, default"))) foo(void) { return 0; }
 // LINUX: define {{.*}}i32 @foo.sse4.2.0()
 // LINUX: define {{.*}}i32 @foo.default.1()
-// LINUX: define i32 ()* @foo.resolver()
+// LINUX: define i32 ()* @foo.resolver() comdat
 // LINUX: ret i32 ()* @foo.sse4.2.0
 // LINUX: ret i32 ()* @foo.default.1
 
 // WINDOWS: define dso_local i32 @foo.sse4.2.0()
 // WINDOWS: define dso_local i32 @foo.default.1()
-// WINDOWS: define dso_local i32 @foo()
+// WINDOWS: define dso_local i32 @foo() comdat
 // WINDOWS: musttail call i32 @foo.sse4.2.0
 // WINDOWS: musttail call i32 @foo.default.1
 
 __attribute__((target_clones("default,default ,sse4.2"))) void foo_dupes(void) {}
 // LINUX: define {{.*}}void @foo_dupes.default.1()
 // LINUX: define {{.*}}void @foo_dupes.sse4.2.0()
-// LINUX: define void ()* @foo_dupes.resolver()
+// LINUX: define void ()* @foo_dupes.resolver() comdat
 // LINUX: ret void ()* @foo_dupes.sse4.2.0
 // LINUX: ret void ()* @foo_dupes.default.1
 
 // WINDOWS: define dso_local void @foo_dupes.default.1()
 // WINDOWS: define dso_local void @foo_dupes.sse4.2.0()
-// WINDOWS: define dso_local void @foo_dupes()
+// WINDOWS: define dso_local void @foo_dupes() comdat
 // WINDOWS: musttail call void @foo_dupes.sse4.2.0
 // WINDOWS: musttail call void @foo_dupes.default.1
 
@@ -52,13 +64,13 @@
 void __attribute__((target_clones("default, arch=ivybridge"))) unused(void) {}
 // LINUX: define {{.*}}void @unused.default.1()
 // LINUX: define {{.*}}void @unused.arch_ivybridge.0()
-// LINUX: define void ()* @unused.resolver()
+// LINUX: define void ()* @unused.resolver() comdat
 // LINUX: ret void ()* @unused.arch_ivybridge.0
 // LINUX: ret void ()* @unused.default.1
 
 // WINDOWS: define dso_local void @unused.default.1()
 // WINDOWS: define dso_local void @unused.arch_ivybridge.0()
-// WINDOWS: define dso_local void @unused()
+// WINDOWS: define dso_local void @unused() comdat
 // WINDOWS: musttail call void @unused.arch_ivybridge.0
 // WINDOWS: musttail call void @unused.default.1
 
@@ -79,12 +91,12 @@
 }
 
 // Deferred emission of foo_inline, which got delayed because it is inline.
-// LINUX: define i32 ()* @foo_inline.resolver()
+// LINUX: define i32 ()* @foo_inline.resolver() comdat
 // LINUX: ret i32 ()* @foo_inline.arch_sandybridge.0
 // LINUX: ret i32 ()* @foo_inline.sse4.2.1
 // LINUX: ret i32 ()* @foo_inline.default.2
 
-// WINDOWS: define dso_local i32 @foo_inline()
+// WINDOWS: define dso_local i32 @foo_inline() comdat
 // WINDOWS: musttail call i32 @foo_inline.arch_sandybridge.0
 // WINDOWS: musttail call i32 @foo_inline.sse4.2.1
 // WINDOWS: musttail call i32 @foo_inline.default.2
@@ -92,13 +104,13 @@
 inline int __attribute__((target_clones("arch=sandybridge,default,sse4.2")))
 foo_inline2(void){ return 0; }
 // LINUX: define linkonce i32 @foo_inline2.arch_sandybridge.0() #[[SB:[0-9]+]]
-// LINUX: define i32 ()* @foo_inline2.resolver()
+// LINUX: define i32 ()* @foo_inline2.resolver() comdat
 // LINUX: ret i32 ()* @foo_inline2.arch_sandybridge.0
 // LINUX: ret i32 ()* @foo_inline2.sse4.2.1
 // LINUX: ret i32 ()* @foo_inline2.default.2
 
 // WINDOWS: define linkonce_odr dso_local i32 @foo_inline2.arch_sandybridge.0() #[[SB:[0-9]+]]
-// WINDOWS: define dso_local i32 @foo_inline2()
+// WINDOWS: define dso_local i32 @foo_inline2() comdat
 // WINDOWS: musttail call i32 @foo_inl

[PATCH] D122954: [clang] Extend target_clones tests to exercise declarations that are not definitions.

2022-04-02 Thread Tom Honermann via Phabricator via cfe-commits
tahonermann created this revision.
tahonermann added reviewers: erichkeane, aaron.ballman.
Herald added a project: All.
tahonermann added inline comments.
tahonermann published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.



Comment at: clang/test/CodeGen/attr-target-clones.c:3
 // RUN: %clang_cc1 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s 
--check-prefixes=WINDOWS,CHECK
+// XFAIL: *
 

The code changes needed for the test to again pass are in D122958.



Comment at: clang/test/CodeGen/attr-target-clones.c:134-138
+// LINUX: declare i32 @foo_used_no_defn.default.1()
+// LINUX: declare i32 ()* @foo_used_no_defn.resolver()
+
+// WINDOWS: declare dso_local i32 @foo_used_no_defn.default.1()
+// WINDOWS: declare dso_local i32 @foo_used_no_defn()

These checks illustrate the problem that causes the test to fail; resolver 
declarations are emitted, but definitions are not.


This change expands the existing code generation test for the 'target_clones'
attribute to cover uses of multiversion function declarations that lack
definitions. The newly added tests trigger a failure in LLVM IR verification
and the test is therefore marked as an expected failure pending a fix. Adding
'-disable-llvm-verifier' to the RUN lines of the test suffices for the test to
pass with the added annotations. The annotations for the new tests demonstrate
an additional deficiency; that a definition for the resolver function is not
emitted if a definition of the 'target_clones' function is not present.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122954

Files:
  clang/test/CodeGen/attr-target-clones.c


Index: clang/test/CodeGen/attr-target-clones.c
===
--- clang/test/CodeGen/attr-target-clones.c
+++ clang/test/CodeGen/attr-target-clones.c
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s 
--check-prefixes=LINUX,CHECK
 // RUN: %clang_cc1 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s 
--check-prefixes=WINDOWS,CHECK
+// XFAIL: *
 
 // LINUX: $foo.resolver = comdat any
 // LINUX: $foo_dupes.resolver = comdat any
@@ -18,6 +19,7 @@
 // LINUX: @unused.ifunc = weak_odr ifunc void (), void ()* ()* @unused.resolver
 // LINUX: @foo_inline.ifunc = weak_odr ifunc i32 (), i32 ()* ()* 
@foo_inline.resolver
 // LINUX: @foo_inline2.ifunc = weak_odr ifunc i32 (), i32 ()* ()* 
@foo_inline2.resolver
+// LINUX: @foo_used_no_defn.ifunc = weak_odr ifunc i32 (), i32 ()* ()* 
@foo_used_no_defn.resolver
 
 int __attribute__((target_clones("sse4.2, default"))) foo(void) { return 0; }
 // LINUX: define {{.*}}i32 @foo.sse4.2.0()
@@ -115,6 +117,28 @@
 // WINDOWS: musttail call i32 @foo_inline2.sse4.2.1
 // WINDOWS: musttail call i32 @foo_inline2.default.2
 
+
+int __attribute__((target_clones("default", "sse4.2")))
+foo_unused_no_defn(void);
+
+int __attribute__((target_clones("default", "sse4.2")))
+foo_used_no_defn(void);
+
+int test_foo_used_no_defn(void) {
+  // LINUX: define {{.*}}i32 @test_foo_used_no_defn()
+  // WINDOWS: define dso_local i32 @test_foo_used_no_defn()
+  return foo_used_no_defn();
+  // LINUX: call i32 @foo_used_no_defn.ifunc()
+  // WINDOWS: call i32 @foo_used_no_defn()
+}
+// LINUX: declare i32 @foo_used_no_defn.default.1()
+// LINUX: declare i32 ()* @foo_used_no_defn.resolver()
+
+// WINDOWS: declare dso_local i32 @foo_used_no_defn.default.1()
+// WINDOWS: declare dso_local i32 @foo_used_no_defn()
+
+
+// Deferred emission of inline definitions.
 // LINUX: define linkonce i32 @foo_inline.arch_sandybridge.0() #[[SB]]
 // LINUX: define linkonce i32 @foo_inline.default.2() #[[DEF]]
 // LINUX: define linkonce i32 @foo_inline.sse4.2.1() #[[SSE42:[0-9]+]]
@@ -130,6 +154,7 @@
 // WINDOWS: define linkonce_odr dso_local i32 @foo_inline2.default.2() #[[DEF]]
 // WINDOWS: define linkonce_odr dso_local i32 @foo_inline2.sse4.2.1() 
#[[SSE42]]
 
+
 // CHECK: attributes #[[SSE42]] =
 // CHECK-SAME: 
"target-features"="+crc32,+cx8,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"
 // CHECK: attributes #[[DEF]] =


Index: clang/test/CodeGen/attr-target-clones.c
===
--- clang/test/CodeGen/attr-target-clones.c
+++ clang/test/CodeGen/attr-target-clones.c
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=LINUX,CHECK
 // RUN: %clang_cc1 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefixes=WINDOWS,CHECK
+// XFAIL: *
 
 // LINUX: $foo.resolver = comdat any
 // LINUX: $foo_dupes.resolver = comdat any
@@ -18,6 +19,7 @@
 // LINUX: @unused.ifunc = weak_odr ifunc void (), void ()* ()* @unused.resolver
 // LINUX: @foo_inline.ifunc = weak_odr ifunc i32 (), i32 ()* ()* @foo_inline.resolver
 // LINUX: @foo_inline2.ifunc = weak_odr ifunc i32 (), i

[PATCH] D122955: [clang] NFC: Enhance comments in CodeGen for multiversion function support.

2022-04-02 Thread Tom Honermann via Phabricator via cfe-commits
tahonermann created this revision.
tahonermann added reviewers: erichkeane, aaron.ballman.
Herald added a project: All.
tahonermann added inline comments.
tahonermann published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.



Comment at: clang/lib/CodeGen/CodeGenModule.cpp:3771
 if (FD->isMultiVersion()) {
-UpdateMultiVersionNames(GD, FD, MangledName);
   if (!IsForDefinition)

This is a drive-by indentation fix.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122955

Files:
  clang/include/clang/Basic/Attr.td
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/CodeGenModule.h


Index: clang/lib/CodeGen/CodeGenModule.h
===
--- clang/lib/CodeGen/CodeGenModule.h
+++ clang/lib/CodeGen/CodeGenModule.h
@@ -348,8 +348,9 @@
   /// is defined once we get to the end of the of the translation unit.
   std::vector Aliases;
 
-  /// List of multiversion functions that have to be emitted.  Used to make 
sure
-  /// we properly emit the iFunc.
+  /// List of multiversion functions to be emitted. This list is processed in
+  /// conjunction with other deferred symbols and is used to ensure that
+  /// multiversion function resolvers and ifuncs are defined and emitted.
   std::vector MultiVersionFuncs;
 
   typedef llvm::StringMap > ReplacementsTy;
@@ -1466,9 +1467,20 @@
   llvm::AttributeList ExtraAttrs = llvm::AttributeList(),
   ForDefinition_t IsForDefinition = NotForDefinition);
 
+  // References to multiversion functions are resolved through an implicitly
+  // defined resolver function. This function is responsible for creating
+  // the resolver symbol for the provided declaration. The value returned
+  // will be for an ifunc (llvm::GlobalIFunc) if the current target supports
+  // that feature and for a regular function (llvm::GlobalValue) otherwise.
   llvm::Constant *GetOrCreateMultiVersionResolver(GlobalDecl GD,
   llvm::Type *DeclTy,
   const FunctionDecl *FD);
+
+  // In scenarios where a function is not known to be a multiversion function
+  // until a later declaration, it is sometimes necessary to change the
+  // previously created mangled name to align with requirements of whatever
+  // multiversion function kind the function is now known to be. This function
+  // is responsible for performing such mangled name updates.
   void UpdateMultiVersionNames(GlobalDecl GD, const FunctionDecl *FD,
StringRef &CurName);
 
@@ -1561,6 +1573,7 @@
   // registered by the atexit subroutine using unatexit.
   void unregisterGlobalDtorsWithUnAtExit();
 
+  /// Emit deferred multiversion function resolvers and associated variants.
   void emitMultiVersionFunctions();
 
   /// Emit any vtables which we deferred and still have a use for.
Index: clang/lib/CodeGen/CodeGenModule.cpp
===
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -3768,7 +3768,7 @@
 }
 
 if (FD->isMultiVersion()) {
-UpdateMultiVersionNames(GD, FD, MangledName);
+  UpdateMultiVersionNames(GD, FD, MangledName);
   if (!IsForDefinition)
 return GetOrCreateMultiVersionResolver(GD, Ty, FD);
 }
Index: clang/include/clang/Basic/Attr.td
===
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -2723,8 +2723,13 @@
 StringRef getFeatureStr(unsigned Index) const {
   return *(featuresStrs_begin() + Index);
 }
-// 'default' is always moved to the end, so it isn't considered
-// when mangling the index.
+// Given an index into the 'featuresStrs' sequence, compute a unique
+// ID to be used with function name mangling for the associated variant.
+// This mapping is necessary due to a requirement that the mangling ID
+// used for the "default" variant be the largest mangling ID in the
+// variant set. Note that, if duplicate variants are present in
+// 'featuresStrs', that each instance will be assigned its own unique
+// ID (the mapping is bijective).
 unsigned getMangledIndex(unsigned Index) const {
   if (getFeatureStr(Index) == "default")
 return std::count_if(featuresStrs_begin(), featuresStrs_end(),
@@ -2734,9 +2739,10 @@
[](StringRef S) { return S != "default"; });
 }
 
-// True if this is the first of this version to appear in the config 
string.
-// This is used to make sure we don't try to emit this function multiple
-// times.
+// Given an index into the 'featuresStrs' sequence, determine if the
+// index corresponds to the first instance of the named variant. This
+// is used to skip over duplicate 

[PATCH] D122956: [clang] NFC: Simplify the interface to CodeGenModule::GetOrCreateMultiVersionResolver().

2022-04-02 Thread Tom Honermann via Phabricator via cfe-commits
tahonermann created this revision.
tahonermann added reviewers: erichkeane, aaron.ballman.
Herald added a project: All.
tahonermann added inline comments.
tahonermann published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.



Comment at: clang/lib/CodeGen/CodeGenModule.cpp:3539-3540
 
-  if (const auto *CXXFD = dyn_cast(FD)) {
-const CGFunctionInfo &FInfo = 
getTypes().arrangeCXXMethodDeclaration(CXXFD);
-DeclTy = getTypes().GetFunctionType(FInfo);
-  }
+  const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(GD);
+  llvm::FunctionType *DeclTy = getTypes().GetFunctionType(FI);
 

This is a drive by cleanup. `arrangeGlobalDeclaration()` handles the 
`CXXMethodDecl` special case (as well as other special cases). We rely on such 
calls elsewhere; see `CodeGenModule::emitMultiVersionFunctions()` for example.


Previously, GetOrCreateMultiVersionResolver() required the caller to provide
a GlobalDecl along with an llvm::type and FunctionDecl. The latter two can be
cheaply obtained from the first, and the llvm::type parameter is not always
used, so requiring the caller to provide them was unnecessary and created the
possibility that callers would pass an inconsistent set. This change simplifies
the interface to only require the GlobalDecl value.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122956

Files:
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/CodeGenModule.h

Index: clang/lib/CodeGen/CodeGenModule.h
===
--- clang/lib/CodeGen/CodeGenModule.h
+++ clang/lib/CodeGen/CodeGenModule.h
@@ -1472,9 +1472,7 @@
   // the resolver symbol for the provided declaration. The value returned
   // will be for an ifunc (llvm::GlobalIFunc) if the current target supports
   // that feature and for a regular function (llvm::GlobalValue) otherwise.
-  llvm::Constant *GetOrCreateMultiVersionResolver(GlobalDecl GD,
-  llvm::Type *DeclTy,
-  const FunctionDecl *FD);
+  llvm::Constant *GetOrCreateMultiVersionResolver(GlobalDecl GD);
 
   // In scenarios where a function is not known to be a multiversion function
   // until a later declaration, it is sometimes necessary to change the
Index: clang/lib/CodeGen/CodeGenModule.cpp
===
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -3414,22 +3414,12 @@
   const auto *TC = FD->getAttr();
   assert(TC && "Not a target_clones Function?");
 
-  QualType CanonTy = Context.getCanonicalType(FD->getType());
-  llvm::Type *DeclTy = getTypes().ConvertType(CanonTy);
-
-  if (const auto *CXXFD = dyn_cast(FD)) {
-const CGFunctionInfo &FInfo = getTypes().arrangeCXXMethodDeclaration(CXXFD);
-DeclTy = getTypes().GetFunctionType(FInfo);
-  }
-
   llvm::Function *ResolverFunc;
   if (getTarget().supportsIFunc()) {
-auto *IFunc = cast(
-GetOrCreateMultiVersionResolver(GD, DeclTy, FD));
+auto *IFunc = cast(GetOrCreateMultiVersionResolver(GD));
 ResolverFunc = cast(IFunc->getResolver());
   } else
-ResolverFunc =
-cast(GetOrCreateMultiVersionResolver(GD, DeclTy, FD));
+ResolverFunc = cast(GetOrCreateMultiVersionResolver(GD));
 
   SmallVector Options;
   for (unsigned VersionIndex = 0; VersionIndex < TC->featuresStrs_size();
@@ -3545,12 +3535,9 @@
   assert(FD->isCPUDispatchMultiVersion() && "Not a multiversion function?");
   const auto *DD = FD->getAttr();
   assert(DD && "Not a cpu_dispatch Function?");
-  llvm::Type *DeclTy = getTypes().ConvertType(FD->getType());
 
-  if (const auto *CXXFD = dyn_cast(FD)) {
-const CGFunctionInfo &FInfo = getTypes().arrangeCXXMethodDeclaration(CXXFD);
-DeclTy = getTypes().GetFunctionType(FInfo);
-  }
+  const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(GD);
+  llvm::FunctionType *DeclTy = getTypes().GetFunctionType(FI);
 
   StringRef ResolverName = getMangledName(GD);
   UpdateMultiVersionNames(GD, FD, ResolverName);
@@ -3640,8 +3627,7 @@
 
   if (getTarget().supportsIFunc()) {
 llvm::GlobalValue::LinkageTypes Linkage = getMultiversionLinkage(*this, GD);
-auto *IFunc = cast(
-GetOrCreateMultiVersionResolver(GD, DeclTy, FD));
+auto *IFunc = cast(GetOrCreateMultiVersionResolver(GD));
 
 // Fix up function declarations that were created for cpu_specific before
 // cpu_dispatch was known
@@ -3668,8 +3654,10 @@
 
 /// If a dispatcher for the specified mangled name is not in the module, create
 /// and return an llvm Function with the specified type.
-llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(
-GlobalDecl GD, llvm::Type *DeclTy, const FunctionDecl *FD) {
+llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) {
+  const auto *FD = cast(GD.getDecl());
+ 

[PATCH] D122957: [clang] NFC: Preparation for merging code to emit target and target_clones resolvers.

2022-04-02 Thread Tom Honermann via Phabricator via cfe-commits
tahonermann created this revision.
tahonermann added reviewers: erichkeane, aaron.ballman.
Herald added a project: All.
tahonermann published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This change modifies CodeGenModule::emitMultiVersionFunctions() in preparation
for a change that will merge support for emitting target_clones resolvers into
this function. This change mostly serves to isolate indentation changes from
later behavior modifying changes.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122957

Files:
  clang/lib/CodeGen/CodeGenModule.cpp


Index: clang/lib/CodeGen/CodeGenModule.cpp
===
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -3463,35 +3463,42 @@
   std::vector MVFuncsToEmit;
   MultiVersionFuncs.swap(MVFuncsToEmit);
   for (GlobalDecl GD : MVFuncsToEmit) {
+const auto *FD = cast(GD.getDecl());
+assert(FD && "Expected a FunctionDecl");
+
 SmallVector Options;
-const FunctionDecl *FD = cast(GD.getDecl());
-getContext().forEachMultiversionedFunctionVersion(
-FD, [this, &GD, &Options](const FunctionDecl *CurFD) {
-  GlobalDecl CurGD{
-  (CurFD->isDefined() ? CurFD->getDefinition() : CurFD)};
-  StringRef MangledName = getMangledName(CurGD);
-  llvm::Constant *Func = GetGlobalValue(MangledName);
-  if (!Func) {
-if (CurFD->isDefined()) {
-  EmitGlobalFunctionDefinition(CurGD, nullptr);
-  Func = GetGlobalValue(MangledName);
-} else {
-  const CGFunctionInfo &FI =
-  getTypes().arrangeGlobalDeclaration(GD);
-  llvm::FunctionType *Ty = getTypes().GetFunctionType(FI);
-  Func = GetAddrOfFunction(CurGD, Ty, /*ForVTable=*/false,
-   /*DontDefer=*/false, ForDefinition);
+if (FD->isTargetMultiVersion()) {
+  getContext().forEachMultiversionedFunctionVersion(
+  FD, [this, &GD, &Options](const FunctionDecl *CurFD) {
+GlobalDecl CurGD{
+(CurFD->isDefined() ? CurFD->getDefinition() : CurFD)};
+StringRef MangledName = getMangledName(CurGD);
+llvm::Constant *Func = GetGlobalValue(MangledName);
+if (!Func) {
+  if (CurFD->isDefined()) {
+EmitGlobalFunctionDefinition(CurGD, nullptr);
+Func = GetGlobalValue(MangledName);
+  } else {
+const CGFunctionInfo &FI =
+getTypes().arrangeGlobalDeclaration(GD);
+llvm::FunctionType *Ty = getTypes().GetFunctionType(FI);
+Func = GetAddrOfFunction(CurGD, Ty, /*ForVTable=*/false,
+ /*DontDefer=*/false, ForDefinition);
+  }
+  assert(Func && "This should have just been created");
 }
-assert(Func && "This should have just been created");
-  }
 
-  const auto *TA = CurFD->getAttr();
-  llvm::SmallVector Feats;
-  TA->getAddedFeatures(Feats);
+const auto *TA = CurFD->getAttr();
+llvm::SmallVector Feats;
+TA->getAddedFeatures(Feats);
 
-  Options.emplace_back(cast(Func),
-   TA->getArchitecture(), Feats);
-});
+Options.emplace_back(cast(Func),
+ TA->getArchitecture(), Feats);
+  });
+} else {
+  assert(0 && "Expected a target multiversion function");
+  continue;
+}
 
 llvm::Function *ResolverFunc;
 const TargetInfo &TI = getTarget();


Index: clang/lib/CodeGen/CodeGenModule.cpp
===
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -3463,35 +3463,42 @@
   std::vector MVFuncsToEmit;
   MultiVersionFuncs.swap(MVFuncsToEmit);
   for (GlobalDecl GD : MVFuncsToEmit) {
+const auto *FD = cast(GD.getDecl());
+assert(FD && "Expected a FunctionDecl");
+
 SmallVector Options;
-const FunctionDecl *FD = cast(GD.getDecl());
-getContext().forEachMultiversionedFunctionVersion(
-FD, [this, &GD, &Options](const FunctionDecl *CurFD) {
-  GlobalDecl CurGD{
-  (CurFD->isDefined() ? CurFD->getDefinition() : CurFD)};
-  StringRef MangledName = getMangledName(CurGD);
-  llvm::Constant *Func = GetGlobalValue(MangledName);
-  if (!Func) {
-if (CurFD->isDefined()) {
-  EmitGlobalFunctionDefinition(CurGD, nullptr);
-  Func = GetGlobalValue(MangledName);
-} else {
-  const CGFunctionInfo &FI =
-  getTypes().arrangeGlobalDeclaration(GD);
-  llvm::FunctionType *Ty = getTypes().GetFunctionType(FI);
-

[PATCH] D122958: [clang] Corrections for target_clones multiversion functions.

2022-04-02 Thread Tom Honermann via Phabricator via cfe-commits
tahonermann created this revision.
tahonermann added reviewers: erichkeane, aaron.ballman.
Herald added a subscriber: kristof.beyls.
Herald added a project: All.
tahonermann updated this revision to Diff 419919.
tahonermann added a comment.
tahonermann updated this revision to Diff 420008.
tahonermann published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Removed the in-class declaration of CodeGenModule::EmitTargetClonesResolver().


tahonermann added a comment.

Simplified code to select a resolver function.




Comment at: clang/lib/CodeGen/CodeGenModule.cpp:3492
 
-if (TI.supportsIFunc() || FD->isTargetMultiVersion()) {
-  ResolverFunc = cast(
-  GetGlobalValue((getMangledName(GD) + ".resolver").str()));
-  ResolverFunc->setLinkage(getMultiversionLinkage(*this, GD));
-} else {
-  ResolverFunc = cast(GetGlobalValue(getMangledName(GD)));
-}
+ResolverFunc->setLinkage(getMultiversionLinkage(*this, GD));
 

`setLinkage()` was previously only called in the ifunc case. I don't know why 
that would be, so I "fixed" it here.



Comment at: clang/lib/CodeGen/CodeGenModule.cpp:3323
   EmitGlobalFunctionDefinition(GD.getWithMultiVersionIndex(I), nullptr);
-// Requires multiple emits.
   } else if (FD->isTargetClonesMultiVersion()) {

This comment seemed oddly placed and didn't seem to convey used information, so 
I gave it the boot.



Comment at: clang/lib/CodeGen/CodeGenModule.cpp:3411-3461
-void CodeGenModule::EmitTargetClonesResolver(GlobalDecl GD) {
-  const auto *FD = cast(GD.getDecl());
-  assert(FD && "Not a FunctionDecl?");
-  const auto *TC = FD->getAttr();
-  assert(TC && "Not a target_clones Function?");
-
-  llvm::Function *ResolverFunc;

This functionality was all merged into 
`CodeGenModule::emitMultiVersionFunctions()` where much of it was already 
present.



Comment at: clang/lib/CodeGen/CodeGenModule.cpp:3488-3493
+if (getTarget().supportsIFunc()) {
+  auto *IFunc =
+  cast(GetOrCreateMultiVersionResolver(GD));
+  ResolverFunc = cast(IFunc->getResolver());
+} else
+  ResolverFunc = cast(GetOrCreateMultiVersionResolver(GD));

Use of `GetOrCreateMultiVersionResolver()` here avoids duplication of code to 
determine how resolver functions are named for each multiversion function kind.



Comment at: clang/lib/CodeGen/CodeGenModule.cpp:3670-3673
+  // The resolver needs to be created. For target and target_clones, defer
+  // creation until the end of the TU.
+  if (FD->isTargetMultiVersion() || FD->isTargetClonesMultiVersion())
 MultiVersionFuncs.push_back(GD);

This is the change that effectively ensures that a `target_clones` function 
resolver is emitted.



Comment at: clang/test/CodeGen/attr-target-clones.c:26
 // LINUX: define {{.*}}i32 @foo.default.1()
-// LINUX: define i32 ()* @foo.resolver() comdat
+// LINUX: define weak_odr i32 ()* @foo.resolver() comdat
 // LINUX: ret i32 ()* @foo.sse4.2.0

`target_clones` resolvers are now emitted consistently with `target` resolvers.



Comment at: clang/test/CodeGen/attr-target-clones.c:152-156
+// LINUX: define linkonce i32 @foo_inline2.arch_sandybridge.0() #[[SB]]
 // LINUX: define linkonce i32 @foo_inline2.default.2() #[[DEF]]
 // LINUX: define linkonce i32 @foo_inline2.sse4.2.1() #[[SSE42]]
 
+// WINDOWS: define linkonce_odr dso_local i32 
@foo_inline2.arch_sandybridge.0() #[[SB]]

Some checks were simply missing previously.



Comment at: clang/test/CodeGen/attr-target-clones.c:161-165
+// LINUX: declare i32 @foo_used_no_defn.default.1()
+// LINUX: declare i32 @foo_used_no_defn.sse4.2.0()
+
+// WINDOWS: declare dso_local i32 @foo_used_no_defn.default.1()
+// WINDOWS: declare dso_local i32 @foo_used_no_defn.sse4.2.0()

Declarations emitted cause the function is no defined!


This change merges code for emit of target and target_clones multiversion
resolver functions and, in doing so, corrects handling of target_clones
functions that are declared but not defined. Previously, a use of such
a target_clones function would result in an attempted emit of an ifunc
that referenced an undefined resolver function. Ifunc references to
undefined resolver functions are not allowed and, when the LLVM verifier
is not disabled (via '-disable-llvm-verifier'), resulted in the verifier
issuing a "IFunc resolver must be a definition" error and aborting the
compilation. With this change, ifuncs and resolver function definitions
are always emitted for used target_clones functions regardless of whether
the target_clones function is defined (if the function is defined, then
the ifunc and resolver are emitted regardless of whether the function is
used).

This change has the side effect of causin