[clang] 022b3c2 - [Clang][RISCV] Recognize unsupport target feature by supporting isValidFeatureName (#106495)

2024-09-09 Thread via cfe-commits

Author: Piyou Chen
Date: 2024-09-09T15:07:39+08:00
New Revision: 022b3c27e27832f27c61683095899227c26e0cca

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

LOG: [Clang][RISCV] Recognize unsupport target feature by supporting 
isValidFeatureName (#106495)

This patch makes unsupported target attributes emit a warning and ignore
the target attribute during semantic checks. The changes include:

1. Adding the RISCVTargetInfo::isValidFeatureName function.
2. Rejecting non-full-arch strings in the handleFullArchString function.
3. Adding test cases to demonstrate the warning behavior.

Added: 


Modified: 
clang/lib/Basic/Targets/RISCV.cpp
clang/lib/Basic/Targets/RISCV.h
clang/lib/Sema/SemaDeclAttr.cpp
clang/test/Sema/attr-target-riscv.c

Removed: 




diff  --git a/clang/lib/Basic/Targets/RISCV.cpp 
b/clang/lib/Basic/Targets/RISCV.cpp
index b89109e7725d44..6f9d050fc71a90 100644
--- a/clang/lib/Basic/Targets/RISCV.cpp
+++ b/clang/lib/Basic/Targets/RISCV.cpp
@@ -388,7 +388,7 @@ static void handleFullArchString(StringRef FullArchStr,
   FullArchStr, /* EnableExperimentalExtension */ true);
   if (llvm::errorToBool(RII.takeError())) {
 // Forward the invalid FullArchStr.
-Features.push_back("+" + FullArchStr.str());
+Features.push_back(FullArchStr.str());
   } else {
 // Append a full list of features, including any negative extensions so 
that
 // we override the CPU's features.
@@ -478,3 +478,7 @@ bool RISCVTargetInfo::validateCpuSupports(StringRef 
Feature) const {
   // __riscv_feature_bits structure.
   return -1 != llvm::RISCVISAInfo::getRISCVFeaturesBitsInfo(Feature).second;
 }
+
+bool RISCVTargetInfo::isValidFeatureName(StringRef Name) const {
+  return llvm::RISCVISAInfo::isSupportedExtensionFeature(Name);
+}

diff  --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h
index 626274b8fc437c..b808ccc8e9cfe9 100644
--- a/clang/lib/Basic/Targets/RISCV.h
+++ b/clang/lib/Basic/Targets/RISCV.h
@@ -130,6 +130,7 @@ class RISCVTargetInfo : public TargetInfo {
   bool supportsCpuSupports() const override { return getTriple().isOSLinux(); }
   bool supportsCpuInit() const override { return getTriple().isOSLinux(); }
   bool validateCpuSupports(StringRef Feature) const override;
+  bool isValidFeatureName(StringRef Name) const override;
 };
 class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
 public:

diff  --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index d068cb6a78f266..72d82b424c26c8 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -2993,10 +2993,17 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc, 
StringRef AttrStr) {
 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
<< Unknown << Tune << ParsedAttrs.Tune << Target;
 
-  if (Context.getTargetInfo().getTriple().isRISCV() &&
-  ParsedAttrs.Duplicate != "")
-return Diag(LiteralLoc, diag::err_duplicate_target_attribute)
-   << Duplicate << None << ParsedAttrs.Duplicate << Target;
+  if (Context.getTargetInfo().getTriple().isRISCV()) {
+if (ParsedAttrs.Duplicate != "")
+  return Diag(LiteralLoc, diag::err_duplicate_target_attribute)
+ << Duplicate << None << ParsedAttrs.Duplicate << Target;
+for (const auto &Feature : ParsedAttrs.Features) {
+  StringRef CurFeature = Feature;
+  if (!CurFeature.starts_with('+') && !CurFeature.starts_with('-'))
+return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
+   << Unsupported << None << AttrStr << Target;
+}
+  }
 
   if (ParsedAttrs.Duplicate != "")
 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)

diff  --git a/clang/test/Sema/attr-target-riscv.c 
b/clang/test/Sema/attr-target-riscv.c
index ed4e2915d6c6ef..35e2ec3986ada3 100644
--- a/clang/test/Sema/attr-target-riscv.c
+++ b/clang/test/Sema/attr-target-riscv.c
@@ -4,3 +4,15 @@
 int __attribute__((target("arch=rv64g"))) foo(void) { return 0; }
 //expected-error@+1 {{redefinition of 'foo'}}
 int __attribute__((target("arch=rv64gc"))) foo(void) { return 0; }
+
+//expected-warning@+1 {{unsupported 'notafeature' in the 'target' attribute 
string; 'target' attribute ignored}}
+int __attribute__((target("arch=+notafeature"))) UnsupportFeature(void) { 
return 0; }
+
+//expected-warning@+1 {{unsupported 'notafeature' in the 'target' attribute 
string; 'target' attribute ignored}}
+int __attribute__((target("arch=-notafeature"))) 
UnsupportNegativeFeature(void) { return 0; }
+
+//expected-warning@+1 {{unsupported 'arch=+zba,zbb' in the 'target' attribute 
string; 'target' attribute ignored}}
+int __attribute__((target("arch=+zba,zbb"))) WithoutPlus(void) { return 0; }
+
+/

[clang] [Clang][RISCV] Recognize unsupport target feature by supporting isValidFeatureName (PR #106495)

2024-09-09 Thread Piyou Chen via cfe-commits

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


[clang] [Clang] Don't assert non-empty packs for FunctionParmPackExprs (PR #107561)

2024-09-09 Thread Younan Zhang via cfe-commits

zyn0217 wrote:

It's been ~3 days and I'm merging it - feel free to do post-commit reviews.

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


[clang] 8549b32 - [Clang] Don't assert non-empty packs for FunctionParmPackExprs (#107561)

2024-09-09 Thread via cfe-commits

Author: Younan Zhang
Date: 2024-09-09T15:09:43+08:00
New Revision: 8549b324bc1f450f4477f46f18db67439dbf6d75

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

LOG: [Clang] Don't assert non-empty packs for FunctionParmPackExprs (#107561)

`FunctionParmPackExpr`s are peculiar in that they have to be of
unexpanded dependency while they don't introduce any unexpanded packs.
So this patch rules them out in the non-empty pack assertion in
`DiagnoseUnexpandedParameterPack()`.

There was a fix #69224, but that turned out to be insufficient.

I also moved the separate tests to a pre-existing file.

Fixes https://github.com/llvm/llvm-project/issues/86361

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaTemplateVariadic.cpp
clang/test/SemaCXX/lambda-pack-expansion.cpp

Removed: 
clang/test/SemaCXX/pr61460.cpp



diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a300829cf0e32c..07f3544e2324e3 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -379,8 +379,8 @@ Bug Fixes to C++ Support
 - Fixed a bug in the substitution of empty pack indexing types. (#GH105903)
 - Clang no longer tries to capture non-odr used default arguments of template 
parameters of generic lambdas (#GH107048)
 - Fixed a bug where defaulted comparison operators would remove ``const`` from 
base classes. (#GH102588)
-
 - Fix a crash when using ``source_location`` in the trailing return type of a 
lambda expression. (#GH67134)
+- A follow-up fix was added for (#GH61460), as the previous fix was not 
entirely correct. (#GH86361)
 
 Bug Fixes to AST Handling
 ^

diff  --git a/clang/lib/Sema/SemaTemplateVariadic.cpp 
b/clang/lib/Sema/SemaTemplateVariadic.cpp
index bcd31c98871e22..40522a07f6339c 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -39,6 +39,10 @@ namespace {
 bool InLambda = false;
 unsigned DepthLimit = (unsigned)-1;
 
+#ifndef NDEBUG
+bool ContainsFunctionParmPackExpr = false;
+#endif
+
 void addUnexpanded(NamedDecl *ND, SourceLocation Loc = SourceLocation()) {
   if (auto *VD = dyn_cast(ND)) {
 // For now, the only problematic case is a generic lambda's templated
@@ -280,6 +284,17 @@ namespace {
 
   return inherited::TraverseLambdaCapture(Lambda, C, Init);
 }
+
+#ifndef NDEBUG
+bool TraverseFunctionParmPackExpr(FunctionParmPackExpr *) {
+  ContainsFunctionParmPackExpr = true;
+  return true;
+}
+
+bool containsFunctionParmPackExpr() const {
+  return ContainsFunctionParmPackExpr;
+}
+#endif
   };
 }
 
@@ -414,16 +429,21 @@ bool Sema::DiagnoseUnexpandedParameterPack(Expr *E,
   if (!E->containsUnexpandedParameterPack())
 return false;
 
-  // CollectUnexpandedParameterPacksVisitor does not expect to see a
-  // FunctionParmPackExpr, but diagnosing unexpected parameter packs may still
-  // see such an expression in a lambda body.
-  // We'll bail out early in this case to avoid triggering an assertion.
-  if (isa(E) && getEnclosingLambda())
-return false;
-
+  // FunctionParmPackExprs are special:
+  //
+  // 1) they're used to model DeclRefExprs to packs that have been expanded but
+  // had that expansion held off in the process of transformation.
+  //
+  // 2) they always have the unexpanded dependencies but don't introduce new
+  // unexpanded packs.
+  //
+  // We might encounter a FunctionParmPackExpr being a full expression, which a
+  // larger CXXFoldExpr would expand.
   SmallVector Unexpanded;
-  CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E);
-  assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
+  CollectUnexpandedParameterPacksVisitor Visitor(Unexpanded);
+  Visitor.TraverseStmt(E);
+  assert((!Unexpanded.empty() || Visitor.containsFunctionParmPackExpr()) &&
+ "Unable to find unexpanded parameter packs");
   return DiagnoseUnexpandedParameterPacks(E->getBeginLoc(), UPPC, Unexpanded);
 }
 

diff  --git a/clang/test/SemaCXX/lambda-pack-expansion.cpp 
b/clang/test/SemaCXX/lambda-pack-expansion.cpp
index 77b2e244753a94..0e60ecd8756600 100644
--- a/clang/test/SemaCXX/lambda-pack-expansion.cpp
+++ b/clang/test/SemaCXX/lambda-pack-expansion.cpp
@@ -68,3 +68,29 @@ void f() {
 }
 
 }
+
+namespace GH61460 {
+
+template
+void f1(Ts... ts);
+
+template  void g(Ts... p1s) {
+  (void)[&](auto... p2s) {
+(
+[&] {
+  p1s;
+  f1(p1s);
+  sizeof(p1s);
+  p2s;
+},
+...);
+  };
+}
+
+template  void g2(Ts... p1s) {
+  (void)[&](auto... p2s) { [&] { p1s; p2s; }; }; // expected-error 
{{unexpanded parameter pack 'p2s'}}
+}
+
+void f1() { g(); }
+
+} // namespace GH61460

diff  --gi

[clang] [Clang] Don't assert non-empty packs for FunctionParmPackExprs (PR #107561)

2024-09-09 Thread Younan Zhang via cfe-commits

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


[clang] [llvm] [LLVM][Coroutines] Transform "coro_elide_safe" calls to switch ABI coroutines to the `noalloc` variant (PR #99285)

2024-09-09 Thread LLVM Continuous Integration via cfe-commits

llvm-ci wrote:

LLVM Buildbot has detected a new failure on builder 
`llvm-clang-x86_64-expensive-checks-debian` running on `gribozavr4` while 
building `llvm` at step 6 "test-build-unified-tree-check-all".

Full details are available at: 
https://lab.llvm.org/buildbot/#/builders/16/builds/4972


Here is the relevant piece of the build log for the reference

```
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
 TEST 'LLVM :: 
Transforms/Coroutines/coro-transform-must-elide.ll' FAILED 
Exit Code: 2

Command Output (stderr):
--
RUN: at line 2: /b/1/llvm-clang-x86_64-expensive-checks-debian/build/bin/opt < 
/b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/llvm/test/Transforms/Coroutines/coro-transform-must-elide.ll
 -S -passes='cgscc(coro-annotation-elide)' | 
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/bin/FileCheck 
/b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/llvm/test/Transforms/Coroutines/coro-transform-must-elide.ll
+ /b/1/llvm-clang-x86_64-expensive-checks-debian/build/bin/opt -S 
'-passes=cgscc(coro-annotation-elide)'
opt: 
/b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/llvm/lib/Analysis/CGSCCPassManager.cpp:982:
 LazyCallGraph::SCC &updateCGAndAnalysisManagerForPass(llvm::LazyCallGraph &, 
LazyCallGraph::SCC &, LazyCallGraph::Node &, llvm::CGSCCAnalysisManager &, 
llvm::CGSCCUpdateResult &, llvm::FunctionAnalysisManager &, bool): Assertion 
`(RC == &TargetRC || RC->isAncestorOf(TargetRC)) && "New call edge is not 
trivial!"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and 
include the crash backtrace.
Stack dump:
0.  Program arguments: 
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/bin/opt -S 
-passes=cgscc(coro-annotation-elide)
1.  Running pass "cgscc(coro-annotation-elide)" on module ""
+ /b/1/llvm-clang-x86_64-expensive-checks-debian/build/bin/FileCheck 
/b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/llvm/test/Transforms/Coroutines/coro-transform-must-elide.ll
 #0 0x0450b697 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) 
(/b/1/llvm-clang-x86_64-expensive-checks-debian/build/bin/opt+0x450b697)
 #1 0x0450914e llvm::sys::RunSignalHandlers() 
(/b/1/llvm-clang-x86_64-expensive-checks-debian/build/bin/opt+0x450914e)
 #2 0x0450bd6f SignalHandler(int) Signals.cpp:0:0
 #3 0x7fbc6d006140 __restore_rt 
(/lib/x86_64-linux-gnu/libpthread.so.0+0x13140)
 #4 0x7fbc6cb1ad51 raise (/lib/x86_64-linux-gnu/libc.so.6+0x38d51)
 #5 0x7fbc6cb04537 abort (/lib/x86_64-linux-gnu/libc.so.6+0x22537)
 #6 0x7fbc6cb0440f (/lib/x86_64-linux-gnu/libc.so.6+0x2240f)
 #7 0x7fbc6cb136d2 (/lib/x86_64-linux-gnu/libc.so.6+0x316d2)
 #8 0x03a60a07 updateCGAndAnalysisManagerForPass(llvm::LazyCallGraph&, 
llvm::LazyCallGraph::SCC&, llvm::LazyCallGraph::Node&, 
llvm::AnalysisManager&, 
llvm::CGSCCUpdateResult&, llvm::AnalysisManager&, bool) 
CGSCCPassManager.cpp:0:0
 #9 0x03a60bcd 
llvm::updateCGAndAnalysisManagerForCGSCCPass(llvm::LazyCallGraph&, 
llvm::LazyCallGraph::SCC&, llvm::LazyCallGraph::Node&, 
llvm::AnalysisManager&, 
llvm::CGSCCUpdateResult&, llvm::AnalysisManager&) 
(/b/1/llvm-clang-x86_64-expensive-checks-debian/build/bin/opt+0x3a60bcd)
#10 0x02d6939e 
llvm::CoroAnnotationElidePass::run(llvm::LazyCallGraph::SCC&, 
llvm::AnalysisManager&, 
llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) 
(/b/1/llvm-clang-x86_64-expensive-checks-debian/build/bin/opt+0x2d6939e)
#11 0x0276364d llvm::detail::PassModel, llvm::LazyCallGraph&, 
llvm::CGSCCUpdateResult&>::run(llvm::LazyCallGraph::SCC&, 
llvm::AnalysisManager&, 
llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) crtstuff.c:0:0
#12 0x03a587a0 llvm::PassManager, 
llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>::run(llvm::LazyCallGraph::SCC&, 
llvm::AnalysisManager&, 
llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) 
(/b/1/llvm-clang-x86_64-expensive-checks-debian/build/bin/opt+0x3a587a0)
#13 0x02756a4d llvm::detail::PassModel, 
llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>, 
llvm::AnalysisManager, 
llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>::run(llvm::LazyCallGraph::SCC&, 
llvm::AnalysisManager&, 
llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) crtstuff.c:0:0
#14 0x03a59e9c 
llvm::ModuleToPostOrderCGSCCPassAdaptor::run(llvm::Module&, 
llvm::AnalysisManager&) 
(/b/1/llvm-clang-x86_64-expensive-checks-debian/build/bin/opt+0x3a59e9c)
#15 0x02756ced llvm::detail::PassModel>::run(llvm::Module&, 
llvm::AnalysisManager&) crtstuff.c:0:0
#16 0x0433a0d7 llvm::PassManager>::run(llvm::Module&, 
llvm::AnalysisManager&) 
(/b/1/llvm-clang-x86_64-expensive-checks-debian/build/bin/opt+0x433a0d7)
#17 0x0084dbf0 llvm::runPassPipeline(llvm::StringRef, llvm::Module&, 
llvm::TargetMachine*, llvm::TargetLibraryInfoImpl*, llvm::ToolOutputFile*, 
llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::StringRef, 
llvm:

[clang] [Clang] Fix crash due to invalid source location in __is_trivially_equality_comparable (PR #107815)

2024-09-09 Thread Nikolas Klauser via cfe-commits

https://github.com/philnik777 created 
https://github.com/llvm/llvm-project/pull/107815

Fixes #10


>From 0059de326ef8dd01e24f45cb18d9035957e77873 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser 
Date: Mon, 9 Sep 2024 09:15:39 +0200
Subject: [PATCH] [Clang] Fix crash due to invalid source location in
 __is_trivially_equality_comparable

---
 clang/lib/Sema/SemaExprCXX.cpp |  3 ++-
 clang/test/SemaCXX/type-traits.cpp | 18 ++
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index e086c601107041..5f7f4eee632bf1 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5168,7 +5168,8 @@ static bool HasNonDeletedDefaultedEqualityComparison(Sema 
&S,
 
 // const ClassT& obj;
 OpaqueValueExpr Operand(
-{}, Decl->getTypeForDecl()->getCanonicalTypeUnqualified().withConst(),
+KeyLoc,
+Decl->getTypeForDecl()->getCanonicalTypeUnqualified().withConst(),
 ExprValueKind::VK_LValue);
 UnresolvedSet<16> Functions;
 // obj == obj;
diff --git a/clang/test/SemaCXX/type-traits.cpp 
b/clang/test/SemaCXX/type-traits.cpp
index b8a9db103782c3..91ef7786f11bb9 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -4147,6 +4147,24 @@ class Template {};
 // Make sure we don't crash when instantiating a type
 static_assert(!__is_trivially_equality_comparable(Template>));
 
+
+struct S operator==(S, S);
+
+template  struct basic_string_view {};
+
+struct basic_string {
+  operator basic_string_view() const;
+};
+
+template 
+const bool is_trivially_equality_comparable = 
__is_trivially_equality_comparable(T);
+
+template  >
+void find();
+
+void func() { find(); }
+
+
 namespace hidden_friend {
 
 struct TriviallyEqualityComparable {

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


[clang] [Clang] Fix crash due to invalid source location in __is_trivially_equality_comparable (PR #107815)

2024-09-09 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Nikolas Klauser (philnik777)


Changes

Fixes #10


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


2 Files Affected:

- (modified) clang/lib/Sema/SemaExprCXX.cpp (+2-1) 
- (modified) clang/test/SemaCXX/type-traits.cpp (+18) 


``diff
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index e086c601107041..5f7f4eee632bf1 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5168,7 +5168,8 @@ static bool HasNonDeletedDefaultedEqualityComparison(Sema 
&S,
 
 // const ClassT& obj;
 OpaqueValueExpr Operand(
-{}, Decl->getTypeForDecl()->getCanonicalTypeUnqualified().withConst(),
+KeyLoc,
+Decl->getTypeForDecl()->getCanonicalTypeUnqualified().withConst(),
 ExprValueKind::VK_LValue);
 UnresolvedSet<16> Functions;
 // obj == obj;
diff --git a/clang/test/SemaCXX/type-traits.cpp 
b/clang/test/SemaCXX/type-traits.cpp
index b8a9db103782c3..91ef7786f11bb9 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -4147,6 +4147,24 @@ class Template {};
 // Make sure we don't crash when instantiating a type
 static_assert(!__is_trivially_equality_comparable(Template>));
 
+
+struct S operator==(S, S);
+
+template  struct basic_string_view {};
+
+struct basic_string {
+  operator basic_string_view() const;
+};
+
+template 
+const bool is_trivially_equality_comparable = 
__is_trivially_equality_comparable(T);
+
+template  >
+void find();
+
+void func() { find(); }
+
+
 namespace hidden_friend {
 
 struct TriviallyEqualityComparable {

``




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


[clang] [RISCV] Add testcase for -mcmodel= (PR #107816)

2024-09-09 Thread Jim Lin via cfe-commits

https://github.com/tclin914 created 
https://github.com/llvm/llvm-project/pull/107816

None

>From f6da0096e4dcf3f7b5c8da4e8e170e88b7ebb471 Mon Sep 17 00:00:00 2001
From: Jim Lin 
Date: Mon, 9 Sep 2024 12:59:30 +0800
Subject: [PATCH] [RISCV] Add testcase for -mcmodel=

---
 clang/test/Driver/riscv-mcmodel.c | 14 ++
 1 file changed, 14 insertions(+)
 create mode 100644 clang/test/Driver/riscv-mcmodel.c

diff --git a/clang/test/Driver/riscv-mcmodel.c 
b/clang/test/Driver/riscv-mcmodel.c
new file mode 100644
index 00..4f5fa95f59b666
--- /dev/null
+++ b/clang/test/Driver/riscv-mcmodel.c
@@ -0,0 +1,14 @@
+// RUN: %clang --target=riscv32 -### -c -mcmodel=small %s 2>&1 | FileCheck 
--check-prefix=SMALL %s
+// RUN: %clang --target=riscv64 -### -c -mcmodel=small %s 2>&1 | FileCheck 
--check-prefix=SMALL %s
+
+// RUN: %clang --target=riscv32 -### -c -mcmodel=medlow %s 2>&1 | FileCheck 
--check-prefix=SMALL %s
+// RUN: %clang --target=riscv64 -### -c -mcmodel=medlow %s 2>&1 | FileCheck 
--check-prefix=SMALL %s
+
+// RUN: %clang --target=riscv32 -### -c -mcmodel=medium %s 2>&1 | FileCheck 
--check-prefix=MEDIUM %s
+// RUN: %clang --target=riscv64 -### -c -mcmodel=medium %s 2>&1 | FileCheck 
--check-prefix=MEDIUM %s
+
+// RUN: %clang --target=riscv32 -### -c -mcmodel=medany %s 2>&1 | FileCheck 
--check-prefix=MEDIUM %s
+// RUN: %clang --target=riscv64 -### -c -mcmodel=medany %s 2>&1 | FileCheck 
--check-prefix=MEDIUM %s
+
+// SMALL: "-mcmodel=small"
+// MEDIUM: "-mcmodel=medium"

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


[clang] [RISCV] Add testcase for -mcmodel= (PR #107816)

2024-09-09 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-backend-risc-v

Author: Jim Lin (tclin914)


Changes



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


1 Files Affected:

- (added) clang/test/Driver/riscv-mcmodel.c (+14) 


``diff
diff --git a/clang/test/Driver/riscv-mcmodel.c 
b/clang/test/Driver/riscv-mcmodel.c
new file mode 100644
index 00..4f5fa95f59b666
--- /dev/null
+++ b/clang/test/Driver/riscv-mcmodel.c
@@ -0,0 +1,14 @@
+// RUN: %clang --target=riscv32 -### -c -mcmodel=small %s 2>&1 | FileCheck 
--check-prefix=SMALL %s
+// RUN: %clang --target=riscv64 -### -c -mcmodel=small %s 2>&1 | FileCheck 
--check-prefix=SMALL %s
+
+// RUN: %clang --target=riscv32 -### -c -mcmodel=medlow %s 2>&1 | FileCheck 
--check-prefix=SMALL %s
+// RUN: %clang --target=riscv64 -### -c -mcmodel=medlow %s 2>&1 | FileCheck 
--check-prefix=SMALL %s
+
+// RUN: %clang --target=riscv32 -### -c -mcmodel=medium %s 2>&1 | FileCheck 
--check-prefix=MEDIUM %s
+// RUN: %clang --target=riscv64 -### -c -mcmodel=medium %s 2>&1 | FileCheck 
--check-prefix=MEDIUM %s
+
+// RUN: %clang --target=riscv32 -### -c -mcmodel=medany %s 2>&1 | FileCheck 
--check-prefix=MEDIUM %s
+// RUN: %clang --target=riscv64 -### -c -mcmodel=medany %s 2>&1 | FileCheck 
--check-prefix=MEDIUM %s
+
+// SMALL: "-mcmodel=small"
+// MEDIUM: "-mcmodel=medium"

``




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


[clang] [RISCV] Add testcase for -mcmodel= (PR #107816)

2024-09-09 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Jim Lin (tclin914)


Changes



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


1 Files Affected:

- (added) clang/test/Driver/riscv-mcmodel.c (+14) 


``diff
diff --git a/clang/test/Driver/riscv-mcmodel.c 
b/clang/test/Driver/riscv-mcmodel.c
new file mode 100644
index 00..4f5fa95f59b666
--- /dev/null
+++ b/clang/test/Driver/riscv-mcmodel.c
@@ -0,0 +1,14 @@
+// RUN: %clang --target=riscv32 -### -c -mcmodel=small %s 2>&1 | FileCheck 
--check-prefix=SMALL %s
+// RUN: %clang --target=riscv64 -### -c -mcmodel=small %s 2>&1 | FileCheck 
--check-prefix=SMALL %s
+
+// RUN: %clang --target=riscv32 -### -c -mcmodel=medlow %s 2>&1 | FileCheck 
--check-prefix=SMALL %s
+// RUN: %clang --target=riscv64 -### -c -mcmodel=medlow %s 2>&1 | FileCheck 
--check-prefix=SMALL %s
+
+// RUN: %clang --target=riscv32 -### -c -mcmodel=medium %s 2>&1 | FileCheck 
--check-prefix=MEDIUM %s
+// RUN: %clang --target=riscv64 -### -c -mcmodel=medium %s 2>&1 | FileCheck 
--check-prefix=MEDIUM %s
+
+// RUN: %clang --target=riscv32 -### -c -mcmodel=medany %s 2>&1 | FileCheck 
--check-prefix=MEDIUM %s
+// RUN: %clang --target=riscv64 -### -c -mcmodel=medany %s 2>&1 | FileCheck 
--check-prefix=MEDIUM %s
+
+// SMALL: "-mcmodel=small"
+// MEDIUM: "-mcmodel=medium"

``




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


[clang] [RISCV] Allow -mcmodel= to accept large for RV64 (PR #107817)

2024-09-09 Thread Jim Lin via cfe-commits

https://github.com/tclin914 created 
https://github.com/llvm/llvm-project/pull/107817

None

>From f6da0096e4dcf3f7b5c8da4e8e170e88b7ebb471 Mon Sep 17 00:00:00 2001
From: Jim Lin 
Date: Mon, 9 Sep 2024 12:59:30 +0800
Subject: [PATCH 1/2] [RISCV] Add testcase for -mcmodel=

---
 clang/test/Driver/riscv-mcmodel.c | 14 ++
 1 file changed, 14 insertions(+)
 create mode 100644 clang/test/Driver/riscv-mcmodel.c

diff --git a/clang/test/Driver/riscv-mcmodel.c 
b/clang/test/Driver/riscv-mcmodel.c
new file mode 100644
index 00..4f5fa95f59b666
--- /dev/null
+++ b/clang/test/Driver/riscv-mcmodel.c
@@ -0,0 +1,14 @@
+// RUN: %clang --target=riscv32 -### -c -mcmodel=small %s 2>&1 | FileCheck 
--check-prefix=SMALL %s
+// RUN: %clang --target=riscv64 -### -c -mcmodel=small %s 2>&1 | FileCheck 
--check-prefix=SMALL %s
+
+// RUN: %clang --target=riscv32 -### -c -mcmodel=medlow %s 2>&1 | FileCheck 
--check-prefix=SMALL %s
+// RUN: %clang --target=riscv64 -### -c -mcmodel=medlow %s 2>&1 | FileCheck 
--check-prefix=SMALL %s
+
+// RUN: %clang --target=riscv32 -### -c -mcmodel=medium %s 2>&1 | FileCheck 
--check-prefix=MEDIUM %s
+// RUN: %clang --target=riscv64 -### -c -mcmodel=medium %s 2>&1 | FileCheck 
--check-prefix=MEDIUM %s
+
+// RUN: %clang --target=riscv32 -### -c -mcmodel=medany %s 2>&1 | FileCheck 
--check-prefix=MEDIUM %s
+// RUN: %clang --target=riscv64 -### -c -mcmodel=medany %s 2>&1 | FileCheck 
--check-prefix=MEDIUM %s
+
+// SMALL: "-mcmodel=small"
+// MEDIUM: "-mcmodel=medium"

>From 7bc57f0b8db381fb6223056c6e18a7aeddf7788e Mon Sep 17 00:00:00 2001
From: Jim Lin 
Date: Mon, 9 Sep 2024 13:09:23 +0800
Subject: [PATCH 2/2] [RISCV] Allow -mcmodel= to accept large for RV64

---
 clang/lib/Driver/ToolChains/CommonArgs.cpp | 3 ++-
 clang/test/Driver/riscv-mcmodel.c  | 6 ++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp 
b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 0601016c3b14b8..f0e1b59076c738 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -2906,7 +2906,8 @@ void tools::addMCModel(const Driver &D, const 
llvm::opt::ArgList &Args,
 CM = "small";
   else if (CM == "medany")
 CM = "medium";
-  Ok = CM == "small" || CM == "medium";
+  Ok = CM == "small" || CM == "medium" ||
+   (CM == "large" && Triple.isRISCV64());
 } else if (Triple.getArch() == llvm::Triple::x86_64) {
   Ok = llvm::is_contained({"small", "kernel", "medium", "large", "tiny"},
   CM);
diff --git a/clang/test/Driver/riscv-mcmodel.c 
b/clang/test/Driver/riscv-mcmodel.c
index 4f5fa95f59b666..2482672d625fe3 100644
--- a/clang/test/Driver/riscv-mcmodel.c
+++ b/clang/test/Driver/riscv-mcmodel.c
@@ -10,5 +10,11 @@
 // RUN: %clang --target=riscv32 -### -c -mcmodel=medany %s 2>&1 | FileCheck 
--check-prefix=MEDIUM %s
 // RUN: %clang --target=riscv64 -### -c -mcmodel=medany %s 2>&1 | FileCheck 
--check-prefix=MEDIUM %s
 
+// RUN: not %clang --target=riscv32 -### -c -mcmodel=large %s 2>&1 | FileCheck 
--check-prefix=ERR-LARGE %s
+// RUN: %clang --target=riscv64 -### -c -mcmodel=large %s 2>&1 | FileCheck 
--check-prefix=LARGE %s
+
 // SMALL: "-mcmodel=small"
 // MEDIUM: "-mcmodel=medium"
+// LARGE: "-mcmodel=large"
+
+// ERR-LARGE:  error: unsupported argument 'large' to option '-mcmodel=' for 
target 'riscv32'

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


[clang] [RISCV] Allow -mcmodel= to accept large for RV64 (PR #107817)

2024-09-09 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-driver

Author: Jim Lin (tclin914)


Changes



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


2 Files Affected:

- (modified) clang/lib/Driver/ToolChains/CommonArgs.cpp (+2-1) 
- (added) clang/test/Driver/riscv-mcmodel.c (+20) 


``diff
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp 
b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 0601016c3b14b8..f0e1b59076c738 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -2906,7 +2906,8 @@ void tools::addMCModel(const Driver &D, const 
llvm::opt::ArgList &Args,
 CM = "small";
   else if (CM == "medany")
 CM = "medium";
-  Ok = CM == "small" || CM == "medium";
+  Ok = CM == "small" || CM == "medium" ||
+   (CM == "large" && Triple.isRISCV64());
 } else if (Triple.getArch() == llvm::Triple::x86_64) {
   Ok = llvm::is_contained({"small", "kernel", "medium", "large", "tiny"},
   CM);
diff --git a/clang/test/Driver/riscv-mcmodel.c 
b/clang/test/Driver/riscv-mcmodel.c
new file mode 100644
index 00..2482672d625fe3
--- /dev/null
+++ b/clang/test/Driver/riscv-mcmodel.c
@@ -0,0 +1,20 @@
+// RUN: %clang --target=riscv32 -### -c -mcmodel=small %s 2>&1 | FileCheck 
--check-prefix=SMALL %s
+// RUN: %clang --target=riscv64 -### -c -mcmodel=small %s 2>&1 | FileCheck 
--check-prefix=SMALL %s
+
+// RUN: %clang --target=riscv32 -### -c -mcmodel=medlow %s 2>&1 | FileCheck 
--check-prefix=SMALL %s
+// RUN: %clang --target=riscv64 -### -c -mcmodel=medlow %s 2>&1 | FileCheck 
--check-prefix=SMALL %s
+
+// RUN: %clang --target=riscv32 -### -c -mcmodel=medium %s 2>&1 | FileCheck 
--check-prefix=MEDIUM %s
+// RUN: %clang --target=riscv64 -### -c -mcmodel=medium %s 2>&1 | FileCheck 
--check-prefix=MEDIUM %s
+
+// RUN: %clang --target=riscv32 -### -c -mcmodel=medany %s 2>&1 | FileCheck 
--check-prefix=MEDIUM %s
+// RUN: %clang --target=riscv64 -### -c -mcmodel=medany %s 2>&1 | FileCheck 
--check-prefix=MEDIUM %s
+
+// RUN: not %clang --target=riscv32 -### -c -mcmodel=large %s 2>&1 | FileCheck 
--check-prefix=ERR-LARGE %s
+// RUN: %clang --target=riscv64 -### -c -mcmodel=large %s 2>&1 | FileCheck 
--check-prefix=LARGE %s
+
+// SMALL: "-mcmodel=small"
+// MEDIUM: "-mcmodel=medium"
+// LARGE: "-mcmodel=large"
+
+// ERR-LARGE:  error: unsupported argument 'large' to option '-mcmodel=' for 
target 'riscv32'

``




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


[clang] [RISCV] Add testcase for -mcmodel= (PR #107816)

2024-09-09 Thread Jim Lin via cfe-commits

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


[clang] [analyzer] Remove overzealous "No dispatcher registered" assertion (PR #107294)

2024-09-09 Thread Donát Nagy via cfe-commits

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

Looks good to me :)

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


[clang] [-Wunsafe-buffer-usage] Warning Libc functions (PR #101583)

2024-09-09 Thread Mikael Holmén via cfe-commits

mikaelholmen wrote:

> > Btw a question about the new warning: So with 
> > -Wunsafe-buffer-usage-in-libc-call clang now warns on the following?
> > ```
> > #include 
> > 
> > void foo(void) {
> >   char q[10];
> >   snprintf(q, 10, "%s", "hello");
> > }
> > ```
> > 
> > 
> > 
> >   
> > 
> > 
> >   
> > 
> > 
> > 
> >   
> > It says
> > ```
> > foo.c:5:3: warning: function 'snprintf' is unsafe 
> > [-Wunsafe-buffer-usage-in-libc-call]
> > 5 |   snprintf(q, 10, "%s", "hello");
> >   |   ^~
> > foo.c:5:12: note:  buffer pointer and size may not match
> > 5 |   snprintf(q, 10, "%s", "hello");
> >   |^
> > 1 warning generated.
> > ```
> > 
> > 
> > 
> >   
> > 
> > 
> >   
> > 
> > 
> > 
> >   
> > Is that as expected? If so, how should snprintf be used to avoid the 
> > warning?
> 
> Yes, this is expected. According to the C++ Safe Buffers programming model, 
> buffer pointers should be changed to `std::span`. Then `snprintf(span.data(), 
> span.size(), ...)` is considered safe and will not be warned. We may also 
> allow the use of the form `snprintf(span.first(10).data(), 10, ...)` later.

But as @bjope said, we get the warning also for C code, even if I explicitly 
say e.g. "-std=c11".
So 
```clang -Weverything foo.c -c -std=c11```
now yields the new warning.


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


[clang] [llvm] [LLVM][Coroutines] Transform "coro_elide_safe" calls to switch ABI coroutines to the `noalloc` variant (PR #99285)

2024-09-09 Thread LLVM Continuous Integration via cfe-commits

llvm-ci wrote:

LLVM Buildbot has detected a new failure on builder 
`llvm-clang-x86_64-expensive-checks-ubuntu` running on `as-builder-4` while 
building `llvm` at step 6 "test-build-unified-tree-check-all".

Full details are available at: 
https://lab.llvm.org/buildbot/#/builders/187/builds/1028


Here is the relevant piece of the build log for the reference

```
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
 TEST 'LLVM :: 
Transforms/Coroutines/coro-transform-must-elide.ll' FAILED 
Exit Code: 2

Command Output (stderr):
--
RUN: at line 2: 
/home/buildbot/worker/as-builder-4/ramdisk/expensive-checks/build/bin/opt < 
/home/buildbot/worker/as-builder-4/ramdisk/expensive-checks/llvm-project/llvm/test/Transforms/Coroutines/coro-transform-must-elide.ll
 -S -passes='cgscc(coro-annotation-elide)' | 
/home/buildbot/worker/as-builder-4/ramdisk/expensive-checks/build/bin/FileCheck 
/home/buildbot/worker/as-builder-4/ramdisk/expensive-checks/llvm-project/llvm/test/Transforms/Coroutines/coro-transform-must-elide.ll
+ /home/buildbot/worker/as-builder-4/ramdisk/expensive-checks/build/bin/opt -S 
'-passes=cgscc(coro-annotation-elide)'
+ 
/home/buildbot/worker/as-builder-4/ramdisk/expensive-checks/build/bin/FileCheck 
/home/buildbot/worker/as-builder-4/ramdisk/expensive-checks/llvm-project/llvm/test/Transforms/Coroutines/coro-transform-must-elide.ll
opt: 
/home/buildbot/worker/as-builder-4/ramdisk/expensive-checks/llvm-project/llvm/lib/Analysis/CGSCCPassManager.cpp:981:
 llvm::LazyCallGraph::SCC& 
updateCGAndAnalysisManagerForPass(llvm::LazyCallGraph&, 
llvm::LazyCallGraph::SCC&, llvm::LazyCallGraph::Node&, 
llvm::CGSCCAnalysisManager&, llvm::CGSCCUpdateResult&, 
llvm::FunctionAnalysisManager&, bool): Assertion `(RC == &TargetRC || 
RC->isAncestorOf(TargetRC)) && "New call edge is not trivial!"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and 
include the crash backtrace.
Stack dump:
0.  Program arguments: 
/home/buildbot/worker/as-builder-4/ramdisk/expensive-checks/build/bin/opt -S 
-passes=cgscc(coro-annotation-elide)
1.  Running pass "cgscc(coro-annotation-elide)" on module ""
 #0 0x556e681d93c4 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) 
/home/buildbot/worker/as-builder-4/ramdisk/expensive-checks/llvm-project/llvm/lib/Support/Unix/Signals.inc:723:22
 #1 0x556e681d97e5 PrintStackTraceSignalHandler(void*) 
/home/buildbot/worker/as-builder-4/ramdisk/expensive-checks/llvm-project/llvm/lib/Support/Unix/Signals.inc:798:1
 #2 0x556e681d6c35 llvm::sys::RunSignalHandlers() 
/home/buildbot/worker/as-builder-4/ramdisk/expensive-checks/llvm-project/llvm/lib/Support/Signals.cpp:105:20
 #3 0x556e681d8c5c SignalHandler(int) 
/home/buildbot/worker/as-builder-4/ramdisk/expensive-checks/llvm-project/llvm/lib/Support/Unix/Signals.inc:413:1
 #4 0x7fa3a73cd520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #5 0x7fa3a74219fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
 #6 0x7fa3a73cd476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
 #7 0x7fa3a73b37f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
 #8 0x7fa3a73b371b (/lib/x86_64-linux-gnu/libc.so.6+0x2871b)
 #9 0x7fa3a73c4e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
#10 0x556e66fb765b updateCGAndAnalysisManagerForPass(llvm::LazyCallGraph&, 
llvm::LazyCallGraph::SCC&, llvm::LazyCallGraph::Node&, 
llvm::AnalysisManager&, 
llvm::CGSCCUpdateResult&, llvm::AnalysisManager&, bool) 
/home/buildbot/worker/as-builder-4/ramdisk/expensive-checks/llvm-project/llvm/lib/Analysis/CGSCCPassManager.cpp:986:29
#11 0x556e66fb85b6 
llvm::updateCGAndAnalysisManagerForCGSCCPass(llvm::LazyCallGraph&, 
llvm::LazyCallGraph::SCC&, llvm::LazyCallGraph::Node&, 
llvm::AnalysisManager&, 
llvm::CGSCCUpdateResult&, llvm::AnalysisManager&) 
/home/buildbot/worker/as-builder-4/ramdisk/expensive-checks/llvm-project/llvm/lib/Analysis/CGSCCPassManager.cpp:1189:43
#12 0x556e65b7df6b 
llvm::CoroAnnotationElidePass::run(llvm::LazyCallGraph::SCC&, 
llvm::AnalysisManager&, 
llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) 
/home/buildbot/worker/as-builder-4/ramdisk/expensive-checks/llvm-project/llvm/lib/Transforms/Coroutines/CoroAnnotationElide.cpp:134:5
#13 0x556e651dc829 llvm::detail::PassModel, llvm::LazyCallGraph&, 
llvm::CGSCCUpdateResult&>::run(llvm::LazyCallGraph::SCC&, 
llvm::AnalysisManager&, 
llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) 
/home/buildbot/worker/as-builder-4/ramdisk/expensive-checks/llvm-project/llvm/include/llvm/IR/PassManagerInternal.h:91:3
#14 0x556e66fb3dab llvm::PassManager, 
llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>::run(llvm::LazyCallGraph::SCC&, 
llvm::AnalysisManager&, 
llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) 
/home/buildbot/worker/as-builder-4/ramdisk/expensive-checks/llvm-project/llvm/lib/Analysis/CGSCCPassManager.cpp:90:12
#15 0x556e651e3193 llvm::detail::PassModel, 
llvm::LazyCallGraph&,

[clang] [clang][analyzer] Fix #embed crash (PR #107764)

2024-09-09 Thread Donát Nagy via cfe-commits

https://github.com/NagyDonat commented:

LGTM, there is no reason to crash on `#embed`.

I think it would be nice to have a few testcases that show the behavior of the 
analyzer around `#embed`:
- Can we produce bug reports if there is an (unrelated) `#embed` expression on 
the execution path? Or do we abort the analysis there?
- If the analysis is not aborted, then how do we represent the contents of a 
memory region that's initialized by `#embed`? Is it `UnknownVal`? Or 
`UndefinedVal` (that may be problematic)?

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


[clang] [Clang] Fix crash due to invalid source location in __is_trivially_equality_comparable (PR #107815)

2024-09-09 Thread Dimitry Andric via cfe-commits

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

Seems reasonable, and it fixes both my minimized test case, and the full 
original test case.

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


[clang] [FMV][Clang][CodeGen] Resolves corresponding callee for multi-versioning callers (PR #107822)

2024-09-09 Thread Yingwei Zheng via cfe-commits

https://github.com/dtcxzyw created 
https://github.com/llvm/llvm-project/pull/107822

Closes #94949.


>From 110eea45aaaca6508f41032641a083df1c43092f Mon Sep 17 00:00:00 2001
From: Yingwei Zheng 
Date: Mon, 9 Sep 2024 15:53:05 +0800
Subject: [PATCH 1/2] [FMV][Clang][CodeGen] Add pre-commit tests. NFC.

---
 .../test/CodeGen/attr-target-clones-inline.c  | 295 ++
 1 file changed, 295 insertions(+)
 create mode 100644 clang/test/CodeGen/attr-target-clones-inline.c

diff --git a/clang/test/CodeGen/attr-target-clones-inline.c 
b/clang/test/CodeGen/attr-target-clones-inline.c
new file mode 100644
index 00..cc9e8dc762e483
--- /dev/null
+++ b/clang/test/CodeGen/attr-target-clones-inline.c
@@ -0,0 +1,295 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --check-attributes --check-globals all --include-generated-funcs 
--version 5
+// RUN: %clang_cc1 -O1 -disable-llvm-passes -triple x86_64-linux-gnu 
-emit-llvm %s -o - | FileCheck %s
+
+__attribute__((target_clones("default,sse4.2,avx2")))
+int callee(void) { return 1; }
+
+__attribute__((target_clones("default,avx2,sse4.2")))
+int caller(void) { return callee(); }
+
+__attribute__((target_clones("default,sse4.2,avx2")))
+int callee_decl(void);
+
+__attribute__((target_clones("default,avx2,sse4.2")))
+int caller_decl(void) { return callee_decl(); }
+
+__attribute__((target_clones("default,sse4.2,avx2")))
+int callee_deferred_def(void);
+
+__attribute__((target_clones("default,avx2,sse4.2")))
+int caller_deferred_def(void) { return callee_deferred_def(); }
+
+__attribute__((target_clones("default,sse4.2,avx2")))
+int callee_deferred_def(void) { return 1; }
+//.
+// CHECK: @__cpu_model = external dso_local global { i32, i32, i32, [1 x i32] }
+// CHECK: @__cpu_features2 = external dso_local global [3 x i32]
+// CHECK: @callee.ifunc = weak_odr alias i32 (), ptr @callee
+// CHECK: @caller.ifunc = weak_odr alias i32 (), ptr @caller
+// CHECK: @callee_decl.ifunc = weak_odr alias i32 (), ptr @callee_decl
+// CHECK: @caller_decl.ifunc = weak_odr alias i32 (), ptr @caller_decl
+// CHECK: @callee_deferred_def.ifunc = weak_odr alias i32 (), ptr 
@callee_deferred_def
+// CHECK: @caller_deferred_def.ifunc = weak_odr alias i32 (), ptr 
@caller_deferred_def
+// CHECK: @callee = weak_odr ifunc i32 (), ptr @callee.resolver
+// CHECK: @caller = weak_odr ifunc i32 (), ptr @caller.resolver
+// CHECK: @callee_decl = weak_odr ifunc i32 (), ptr @callee_decl.resolver
+// CHECK: @caller_decl = weak_odr ifunc i32 (), ptr @caller_decl.resolver
+// CHECK: @callee_deferred_def = weak_odr ifunc i32 (), ptr 
@callee_deferred_def.resolver
+// CHECK: @caller_deferred_def = weak_odr ifunc i32 (), ptr 
@caller_deferred_def.resolver
+//.
+// CHECK: Function Attrs: nounwind
+// CHECK-LABEL: define dso_local i32 @callee.default.2(
+// CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:ret i32 1
+//
+//
+// CHECK: Function Attrs: nounwind
+// CHECK-LABEL: define dso_local i32 @callee.sse4.2.0(
+// CHECK-SAME: ) #[[ATTR1:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:ret i32 1
+//
+//
+// CHECK: Function Attrs: nounwind
+// CHECK-LABEL: define dso_local i32 @callee.avx2.1(
+// CHECK-SAME: ) #[[ATTR2:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:ret i32 1
+//
+//
+// CHECK-LABEL: define weak_odr ptr @callee.resolver() comdat {
+// CHECK-NEXT:  [[RESOLVER_ENTRY:.*:]]
+// CHECK-NEXT:call void @__cpu_indicator_init()
+// CHECK-NEXT:[[TMP0:%.*]] = load i32, ptr getelementptr inbounds ({ i32, 
i32, i32, [1 x i32] }, ptr @__cpu_model, i32 0, i32 3, i32 0), align 4
+// CHECK-NEXT:[[TMP1:%.*]] = and i32 [[TMP0]], 1024
+// CHECK-NEXT:[[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1024
+// CHECK-NEXT:[[TMP3:%.*]] = and i1 true, [[TMP2]]
+// CHECK-NEXT:br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label 
%[[RESOLVER_ELSE:.*]]
+// CHECK:   [[RESOLVER_RETURN]]:
+// CHECK-NEXT:ret ptr @callee.avx2.1
+// CHECK:   [[RESOLVER_ELSE]]:
+// CHECK-NEXT:[[TMP4:%.*]] = load i32, ptr getelementptr inbounds ({ i32, 
i32, i32, [1 x i32] }, ptr @__cpu_model, i32 0, i32 3, i32 0), align 4
+// CHECK-NEXT:[[TMP5:%.*]] = and i32 [[TMP4]], 256
+// CHECK-NEXT:[[TMP6:%.*]] = icmp eq i32 [[TMP5]], 256
+// CHECK-NEXT:[[TMP7:%.*]] = and i1 true, [[TMP6]]
+// CHECK-NEXT:br i1 [[TMP7]], label %[[RESOLVER_RETURN1:.*]], label 
%[[RESOLVER_ELSE2:.*]]
+// CHECK:   [[RESOLVER_RETURN1]]:
+// CHECK-NEXT:ret ptr @callee.sse4.2.0
+// CHECK:   [[RESOLVER_ELSE2]]:
+// CHECK-NEXT:ret ptr @callee.default.2
+//
+//
+// CHECK: Function Attrs: nounwind
+// CHECK-LABEL: define dso_local i32 @caller.default.2(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[CALL:%.*]] = call i32 @callee()
+// CHECK-NEXT:ret i32 [[CALL]]
+//
+//
+// CHECK: Function Attrs: nounwind
+// CHECK-LABEL: define dso_local i32 @caller.avx2.0(
+// CHECK-SAME:

[clang] [analyzer] fix crash on binding to symbolic region with `void *` type (PR #107572)

2024-09-09 Thread Donát Nagy via cfe-commits

NagyDonat wrote:

To me this solution seems to be a bit hacky -- I don't like that we need to 
scatter "handle `void *` as if it was `char *`" special cases in various parts 
of the analyzer (I vaguely recall that I have also seen similar hacks 
elsewhere).

I'd prefer solutions that are as generic as possible and ensure that `void *` 
is consistently handled like `char *` if that's what we want. (By the way, will 
the analyzer be able to use this `UnknownVal` bound to the `void *` pointer? If 
not, then just avoid the binding.)

These are not blocking issues, feel free to merge this commit to fix the crash 
(instead of waiting for a theoretically better solution).

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


[clang] da11ede - [analyzer] Remove overzealous "No dispatcher registered" assertion (#107294)

2024-09-09 Thread via cfe-commits

Author: vabridgers
Date: 2024-09-09T03:47:39-05:00
New Revision: da11ede57d034767a6f5d5e211c06c1c3089d7fd

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

LOG: [analyzer] Remove overzealous "No dispatcher registered" assertion 
(#107294)

Random testing revealed it's possible to crash the analyzer with the
command line invocation:

clang -cc1 -analyze -analyzer-checker=nullability empty.c

where the source file, empty.c is an empty source file.

```
clang: /clang/lib/StaticAnalyzer/Core/CheckerManager.cpp:56:
   void clang::ento::CheckerManager::finishedCheckerRegistration():
 Assertion `Event.second.HasDispatcher && "No dispatcher registered for an 
event"' failed.

PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/

Stack dump:
0.  Program arguments: clang -cc1 -analyze -analyzer-checker=nullability 
nullability-nocrash.c
 #0 ...
 ...
 #7  clang::ento::CheckerManager::finishedCheckerRegistration()
 #8  clang::ento::CheckerManager::CheckerManager(clang::ASTContext&,
 clang::AnalyzerOptions&, clang::Preprocessor const&,
 llvm::ArrayRef,
 std::allocator>>, llvm::ArrayRef>)
```

This commit removes the assertion which failed here, because it was
logically incorrect: it required that if an Event is handled by some
(enabled) checker, then there must be an **enabled** checker which can
emit that kind of Event. It should be OK to disable the event-producing
checkers but enable an event-consuming checker which has different
responsibilities in addition to handling the events.
 
Note that this assertion was in an `#ifndef NDEBUG` block, so this
change does not impact the non-debug builds.

Co-authored-by: Vince Bridgers 

Added: 
clang/test/Analysis/nullability-nocrash.c

Modified: 
clang/include/clang/StaticAnalyzer/Core/CheckerManager.h
clang/lib/StaticAnalyzer/Core/CheckerManager.cpp
clang/lib/StaticAnalyzer/Frontend/CreateCheckerManager.cpp

Removed: 




diff  --git a/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h 
b/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h
index ad25d18f280700..24c5b66fd58220 100644
--- a/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h
+++ b/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -164,8 +164,6 @@ class CheckerManager {
 
   bool hasPathSensitiveCheckers() const;
 
-  void finishedCheckerRegistration();
-
   const LangOptions &getLangOpts() const { return LangOpts; }
   const AnalyzerOptions &getAnalyzerOptions() const { return AOptions; }
   const Preprocessor &getPreprocessor() const {

diff  --git a/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp 
b/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp
index 6fc16223ea8287..524a4c43abf243 100644
--- a/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp
@@ -48,16 +48,6 @@ bool CheckerManager::hasPathSensitiveCheckers() const {
   EvalCallCheckers, EndOfTranslationUnitCheckers);
 }
 
-void CheckerManager::finishedCheckerRegistration() {
-#ifndef NDEBUG
-  // Make sure that for every event that has listeners, there is at least
-  // one dispatcher registered for it.
-  for (const auto &Event : Events)
-assert(Event.second.HasDispatcher &&
-   "No dispatcher registered for an event");
-#endif
-}
-
 void CheckerManager::reportInvalidCheckerOptionValue(
 const CheckerBase *C, StringRef OptionName,
 StringRef ExpectedValueDesc) const {

diff  --git a/clang/lib/StaticAnalyzer/Frontend/CreateCheckerManager.cpp 
b/clang/lib/StaticAnalyzer/Frontend/CreateCheckerManager.cpp
index 21a60785eb5253..f60221ad7587e4 100644
--- a/clang/lib/StaticAnalyzer/Frontend/CreateCheckerManager.cpp
+++ b/clang/lib/StaticAnalyzer/Frontend/CreateCheckerManager.cpp
@@ -28,7 +28,6 @@ CheckerManager::CheckerManager(
AOptions, checkerRegistrationFns);
   Registry.initializeRegistry(*this);
   Registry.initializeManager(*this);
-  finishedCheckerRegistration();
 }
 
 CheckerManager::CheckerManager(AnalyzerOptions &AOptions,

diff  --git a/clang/test/Analysis/nullability-nocrash.c 
b/clang/test/Analysis/nullability-nocrash.c
new file mode 100644
index 00..209b7708250676
--- /dev/null
+++ b/clang/test/Analysis/nullability-nocrash.c
@@ -0,0 +1,13 @@
+// RUN: %clang_analyze_cc1 -w -analyzer-checker=nullability \
+// RUN:   -analyzer-output=text -verify %s
+//
+// expected-no-diagnostics
+//
+// Previously there was an assertion requiring that if an Event is handled by
+// some enabled checker, then there must be at least one enabled checker which
+// can emit that kind of Event.
+// This assertion failed when NullabilityChecker (which is a subclass of
+// check::Event) was enabled, but the c

[clang] [analyzer] Remove overzealous "No dispatcher registered" assertion (PR #107294)

2024-09-09 Thread via cfe-commits

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


[clang] [lld] [llvm] [clang][MIPS] Add support for mipsel-windows-* targets (PR #107744)

2024-09-09 Thread Martin Storsjö via cfe-commits


@@ -40,6 +40,7 @@ static const auto ARM64EC = 
llvm::COFF::IMAGE_FILE_MACHINE_ARM64EC;
 static const auto ARM64X = llvm::COFF::IMAGE_FILE_MACHINE_ARM64X;
 static const auto ARMNT = llvm::COFF::IMAGE_FILE_MACHINE_ARMNT;
 static const auto I386 = llvm::COFF::IMAGE_FILE_MACHINE_I386;
+static const auto MIPS = llvm::COFF::IMAGE_FILE_MACHINE_R4000;

mstorsjo wrote:

This part (adding a yet-unused shorthand in lld/COFF/Config.h) of this commit 
(primarily llvm/lib/Object stuff) seems unrelated and should be moved to a 
later commit.

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


[clang] [lld] [llvm] [clang][MIPS] Add support for mipsel-windows-* targets (PR #107744)

2024-09-09 Thread Martin Storsjö via cfe-commits

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


[clang] [lld] [llvm] [clang][MIPS] Add support for mipsel-windows-* targets (PR #107744)

2024-09-09 Thread Martin Storsjö via cfe-commits

https://github.com/mstorsjo commented:

I browsed through the first couple commits and added a couple pointers. Overall 
it looks reasonable, but things can probably be split up into even smaller 
commits for atomicity, which also would make it clearer where we'd want more 
test coverage.

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


[clang] [lld] [llvm] [clang][MIPS] Add support for mipsel-windows-* targets (PR #107744)

2024-09-09 Thread Martin Storsjö via cfe-commits


@@ -51,3 +51,25 @@ MipsELFMCAsmInfo::MipsELFMCAsmInfo(const Triple &TheTriple,
   DwarfRegNumForCFI = true;
   HasMipsExpressions = true;
 }
+
+void MipsCOFFMCAsmInfoMicrosoft::anchor() { }
+
+MipsCOFFMCAsmInfoMicrosoft::MipsCOFFMCAsmInfoMicrosoft() {
+  WinEHEncodingType = WinEH::EncodingType::Itanium;
+  CommentString = ";";

mstorsjo wrote:

In general, I would recommend against using `;` as comment string here.

While this is the asm dialect for Microsoft variants, this still is within the 
scope of GNU assembler style, produced and consumed by clang and `llvm-mc` and 
similar tools.

For the full standalone Microsoft style assembly, on x86 we have the separate 
`llvm-ml` tool. And on aarch64, we've changed `CommentString` to use `//` for 
the microsoft variant, just like for the GNU/ELF variants, in order to be able 
to build e.g. compiler-rt assembly sources for the microsoft variants too - see 
71c29b4cf3fb2b5610991bfbc12b8bda97d60005.

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


[clang] [lld] [llvm] [clang][MIPS] Add support for mipsel-windows-* targets (PR #107744)

2024-09-09 Thread Martin Storsjö via cfe-commits


@@ -1132,6 +1132,8 @@ StringRef COFFObjectFile::getFileFormatName() const {
 return "COFF-ARM64EC";
   case COFF::IMAGE_FILE_MACHINE_ARM64X:
 return "COFF-ARM64X";
+  case COFF::IMAGE_FILE_MACHINE_R4000:
+return "COFF-R4000";

mstorsjo wrote:

Hmm, do we want to label this as `COFF-R4000`, or would just `COFF-MIPS` be 
more easily accessible?

I see that there are a couple other `IMAGE_FILE_MACHINE_*` constants for MIPS 
variants - how relevant are they?

If the R4000 is the only one that actually is being used, I'd almost go with 
labelling this just `COFF-MIPS`.

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


[clang] [lld] [llvm] [clang][MIPS] Add support for mipsel-windows-* targets (PR #107744)

2024-09-09 Thread Martin Storsjö via cfe-commits


@@ -28,6 +28,8 @@ COFF::MachineTypes llvm::getMachineType(StringRef S) {
   .Case("arm64", COFF::IMAGE_FILE_MACHINE_ARM64)
   .Case("arm64ec", COFF::IMAGE_FILE_MACHINE_ARM64EC)
   .Case("arm64x", COFF::IMAGE_FILE_MACHINE_ARM64X)
+  .Case("mips", COFF::IMAGE_FILE_MACHINE_R4000) // also handle mips 
(big-endian) because we want to support '/machine:MIPS'
+  .Case("mipsel", COFF::IMAGE_FILE_MACHINE_R4000)

mstorsjo wrote:

I don't think we should accept `mipsel` here, and the comment about big-endian 
above feels confusing/misleading.

This switch is only for mapping arch names from the MS tool `/machine:` flags, 
to the corresponding `COFF::IMAGE_FILE_MACHINE_*` values. I presume that no MS 
tool ever accepted `/machine:mipsel` right? Then we don't need that value here. 
And as all Windows/COFF MIPS was little-endian (I presume) we don't need claim 
anything to be big endian.

It's just that arch names in different namespaces can mean different things. In 
MS tools, `/machine:mips` unambiguously means little endian mips, while the 
corresponding thing in a triple is `mipsel-*`.

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


[clang] [lld] [llvm] [clang][MIPS] Add support for mipsel-windows-* targets (PR #107744)

2024-09-09 Thread Martin Storsjö via cfe-commits


@@ -45,6 +47,8 @@ StringRef llvm::machineToStr(COFF::MachineTypes MT) {
 return "x64";
   case COFF::IMAGE_FILE_MACHINE_I386:
 return "x86";
+  case COFF::IMAGE_FILE_MACHINE_R4000:
+return "mipsel";

mstorsjo wrote:

This seems wrong - this should return the canonical name for the `/machine:` 
flag for this machine type, which I presume is `mips`.

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


[clang] [lld] [llvm] [clang][MIPS] Add support for mipsel-windows-* targets (PR #107744)

2024-09-09 Thread Martin Storsjö via cfe-commits


@@ -39,3 +39,7 @@ Sections:
 
 # BSS: Contents of section .bss:
 # BSS-NEXT: 
+
+# RUN: yaml2obj %p/Inputs/COFF/mipsel.yaml | llvm-objdump -s - | FileCheck %s 
--check-prefix=COFF-R4000

mstorsjo wrote:

This new test seems quite misplaced within this test file. Also I wonder if 
it'd be better to place this test perhaps in the `llvm/test/tools/yaml2obj` 
directory, and include a couple of the newly added relocations in the object 
file too, to have the test actually cover more of what's being added in this 
commit.

The handling of the `/machine:` flag values seems a bit unrelated to this 
commit, perhaps that can be split to another one? Or is it needed by some of 
the objdump aspects?

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


[clang] [lld] [llvm] [clang][MIPS] Add support for mipsel-windows-* targets (PR #107744)

2024-09-09 Thread Martin Storsjö via cfe-commits


@@ -0,0 +1,43 @@
+; RUN: llc -mtriple mipsel-windows-msvc -filetype=obj < %s | obj2yaml | 
FileCheck %s
+; RUN: llc -mtriple mipsel-windows-gnu -filetype=obj < %s | obj2yaml | 
FileCheck %s

mstorsjo wrote:

It feels to me like this test skips a couple steps.

It would be better to separate things out entirely; in `test/CodeGen/Mips`, 
you'd have a test that takes `.ll` and generates assembly, where you check the 
related aspects. (They're probably quite unspectacular at this point, that's 
fine. And if that's irrelevant at this point, perhaps that test can be skipped 
or deferred to a later patch?) Then in `test/MC/Mips`, you'd have a test that 
takes `.s` assembly input and verifies the output aspects of it. Such tests 
more often would use e.g. `objdump -d -r` rather than `obj2yaml` for inspecting 
the output object file too.

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


[clang] [llvm] [SPIR-V] Add SPIR-V structurizer (PR #107408)

2024-09-09 Thread Nathan Gauër via cfe-commits


@@ -0,0 +1,1410 @@
+//===-- SPIRVStructurizer.cpp --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//===--===//
+
+#include "Analysis/SPIRVConvergenceRegionAnalysis.h"
+#include "SPIRV.h"
+#include "SPIRVSubtarget.h"
+#include "SPIRVTargetMachine.h"
+#include "SPIRVUtils.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/CodeGen/IntrinsicLowering.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicsSPIRV.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Transforms/Utils/LoopSimplify.h"
+#include "llvm/Transforms/Utils/LowerMemIntrinsics.h"
+#include 
+#include 
+
+using namespace llvm;
+using namespace SPIRV;
+
+namespace llvm {
+
+void initializeSPIRVStructurizerPass(PassRegistry &);
+
+namespace {
+
+using BlockSet = std::unordered_set;
+using Edge = std::pair;
+
+// This class implements a partial ordering visitor, which visits a cyclic 
graph
+// in natural topological-like ordering. Topological ordering is not defined 
for
+// directed graphs with cycles, so this assumes cycles are a single node, and
+// ignores back-edges. The cycle is visited from the entry in the same
+// topological-like ordering.
+//
+// This means once we visit a node, we know all the possible ancestors have 
been
+// visited.
+//
+// clang-format off
+//
+// Given this graph:
+//
+// ,-> B -\
+// A -++---> D > E -> F -> G -> H
+// `-> C -/  ^ |
+//   +-+
+//
+// Visit order is:
+//  A, [B, C in any order], D, E, F, G, H
+//
+// clang-format on
+//
+// Changing the function CFG between the construction of the visitor and
+// visiting is undefined. The visitor can be reused, but if the CFG is updated,
+// the visitor must be rebuilt.
+class PartialOrderingVisitor {
+  DomTreeBuilder::BBDomTree DT;
+  LoopInfo LI;
+  BlockSet Visited;
+  std::unordered_map B2R;
+  std::vector> Order;
+
+  // Get all basic-blocks reachable from Start.
+  BlockSet getReachableFrom(BasicBlock *Start) {
+std::queue ToVisit;
+ToVisit.push(Start);
+
+BlockSet Output;
+while (ToVisit.size() != 0) {
+  BasicBlock *BB = ToVisit.front();
+  ToVisit.pop();
+
+  if (Output.count(BB) != 0)
+continue;
+  Output.insert(BB);
+
+  for (BasicBlock *Successor : successors(BB)) {
+if (DT.dominates(Successor, BB))
+  continue;
+ToVisit.push(Successor);
+  }
+}
+
+return Output;
+  }
+
+  size_t visit(BasicBlock *BB, size_t Rank) {
+if (Visited.count(BB) != 0)
+  return Rank;
+
+Loop *L = LI.getLoopFor(BB);
+const bool isLoopHeader = LI.isLoopHeader(BB);
+
+if (B2R.count(BB) == 0) {
+  B2R.emplace(BB, Rank);
+} else {
+  B2R[BB] = std::max(B2R[BB], Rank);
+}
+
+for (BasicBlock *Predecessor : predecessors(BB)) {
+  if (isLoopHeader && L->contains(Predecessor)) {
+continue;
+  }
+
+  if (B2R.count(Predecessor) == 0) {
+return Rank;
+  }
+}
+
+Visited.insert(BB);
+
+SmallVector OtherSuccessors;
+BasicBlock *LoopSuccessor = nullptr;
+
+for (BasicBlock *Successor : successors(BB)) {
+  // Ignoring back-edges.
+  if (DT.dominates(Successor, BB))
+continue;
+
+  if (isLoopHeader && L->contains(Successor)) {
+assert(LoopSuccessor == nullptr);
+LoopSuccessor = Successor;
+  } else
+OtherSuccessors.push_back(Successor);
+}
+
+if (LoopSuccessor)
+  Rank = visit(LoopSuccessor, Rank + 1);
+
+size_t OutputRank = Rank;
+for (BasicBlock *Item : OtherSuccessors)
+  OutputRank = std::max(OutputRank, visit(Item, Rank + 1));
+return OutputRank;
+  };
+
+public:
+  // Build the visitor to operate on the function F.
+  PartialOrderingVisitor(Function &F) {
+DT.recalculate(F);
+LI = LoopInfo(DT);
+
+visit(&*F.begin(), 0);
+
+for (auto &[BB, Rank] : B2R)
+  Order.emplace_back(BB, Rank);
+
+std::sort(Order.begin(), Order.end(), [](const auto &LHS, const auto &RHS) 
{
+  return LHS.second < RHS.second;
+});
+
+for (size_t i = 0; i < Order.size(); i++)
+  B2R[Order[i].first] = i;
+  }
+
+  // Visit the function starting from the basic block |Start|, and calling |Op|
+  // on each visited BB. This traversal ignores back-edges, meaning this won't
+  // visit a node to which |Start| is not an ancestor.
+  void partialOrder

[clang] [clang][analyzer] Fix #embed crash (PR #107764)

2024-09-09 Thread Balazs Benics via cfe-commits

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

LGTM. I knew about this issue, thanks for the fix!
There is more for a proper fix but it's better than crashing.

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


[clang] [clang][analyzer] Fix #embed crash (PR #107764)

2024-09-09 Thread Balazs Benics via cfe-commits

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


[clang] [clang][analyzer] Fix #embed crash (PR #107764)

2024-09-09 Thread Balazs Benics via cfe-commits


@@ -0,0 +1,9 @@
+// RUN: %clang_analyze_cc1 -std=c23 
-analyzer-checker=core,debug.ExprInspection -verify %s
+
+// expected-no-diagnostics
+
+int main() {
+const unsigned char SelfBytes[] = {
+#embed "embed.c"
+};
+}

steakhal wrote:

```suggestion
// RUN: %clang_analyze_cc1 -std=c23 -analyzer-checker=core,debug.ExprInspection 
-verify %s

void clang_analyzer_dump_ptr(const unsigned char *ptr);
void clang_analyzer_dump(unsigned char val);

int main() {
const unsigned char SelfBytes[] = {
#embed "embed.c"
};
clang_analyzer_dump_ptr(SelfBytes); // expected-warning 
{{&Element{SelfBytes,0 S64b,unsigned char}}}
clang_analyzer_dump(SelfBytes[0]); // expected-warning {{Unknown}} FIXME: 
This should be the `/` character.
}
```

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


[clang] [clang][analyzer] Fix #embed crash (PR #107764)

2024-09-09 Thread Balazs Benics via cfe-commits

https://github.com/steakhal updated 
https://github.com/llvm/llvm-project/pull/107764

>From a43b9b74ac253c0072498007cf56ed57d8255143 Mon Sep 17 00:00:00 2001
From: Nicolas van Kempen 
Date: Sun, 8 Sep 2024 11:52:28 -0400
Subject: [PATCH 1/2] [clang][analyzer] Fix #embed crash

Fix #107724.
---
 clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 5 +
 clang/test/Analysis/embed.c  | 9 +
 2 files changed, 10 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/Analysis/embed.c

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 315d85319a85a9..fdabba46992b08 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1938,6 +1938,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
 case Stmt::CXXRewrittenBinaryOperatorClass:
 case Stmt::RequiresExprClass:
 case Expr::CXXParenListInitExprClass:
+case Stmt::EmbedExprClass:
   // Fall through.
 
 // Cases we intentionally don't evaluate, since they don't need
@@ -2440,10 +2441,6 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
   Bldr.addNodes(Dst);
   break;
 }
-
-case Stmt::EmbedExprClass:
-  llvm::report_fatal_error("Support for EmbedExpr is not implemented.");
-  break;
   }
 }
 
diff --git a/clang/test/Analysis/embed.c b/clang/test/Analysis/embed.c
new file mode 100644
index 00..7201bb30386fb7
--- /dev/null
+++ b/clang/test/Analysis/embed.c
@@ -0,0 +1,9 @@
+// RUN: %clang_analyze_cc1 -std=c23 
-analyzer-checker=core,debug.ExprInspection -verify %s
+
+// expected-no-diagnostics
+
+int main() {
+const unsigned char SelfBytes[] = {
+#embed "embed.c"
+};
+}

>From 21b1ed8c9f6680540c3520c06efc04917b74611f Mon Sep 17 00:00:00 2001
From: Balazs Benics 
Date: Mon, 9 Sep 2024 11:12:04 +0200
Subject: [PATCH 2/2] Update clang/test/Analysis/embed.c

---
 clang/test/Analysis/embed.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/clang/test/Analysis/embed.c b/clang/test/Analysis/embed.c
index 7201bb30386fb7..32f6c130325740 100644
--- a/clang/test/Analysis/embed.c
+++ b/clang/test/Analysis/embed.c
@@ -1,9 +1,12 @@
 // RUN: %clang_analyze_cc1 -std=c23 
-analyzer-checker=core,debug.ExprInspection -verify %s
 
-// expected-no-diagnostics
+void clang_analyzer_dump_ptr(const unsigned char *ptr);
+void clang_analyzer_dump(unsigned char val);
 
 int main() {
 const unsigned char SelfBytes[] = {
 #embed "embed.c"
 };
+clang_analyzer_dump_ptr(SelfBytes); // expected-warning 
{{&Element{SelfBytes,0 S64b,unsigned char}}}
+clang_analyzer_dump(SelfBytes[0]); // expected-warning {{Unknown}} FIXME: 
This should be the `/` character.
 }

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


[clang] [llvm] [SPIR-V] Add SPIR-V structurizer (PR #107408)

2024-09-09 Thread Nathan Gauër via cfe-commits


@@ -0,0 +1,1410 @@
+//===-- SPIRVStructurizer.cpp --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//===--===//
+
+#include "Analysis/SPIRVConvergenceRegionAnalysis.h"
+#include "SPIRV.h"
+#include "SPIRVSubtarget.h"
+#include "SPIRVTargetMachine.h"
+#include "SPIRVUtils.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/CodeGen/IntrinsicLowering.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicsSPIRV.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Transforms/Utils/LoopSimplify.h"
+#include "llvm/Transforms/Utils/LowerMemIntrinsics.h"
+#include 
+#include 
+
+using namespace llvm;
+using namespace SPIRV;
+
+namespace llvm {
+
+void initializeSPIRVStructurizerPass(PassRegistry &);
+
+namespace {
+
+using BlockSet = std::unordered_set;
+using Edge = std::pair;
+
+// This class implements a partial ordering visitor, which visits a cyclic 
graph
+// in natural topological-like ordering. Topological ordering is not defined 
for
+// directed graphs with cycles, so this assumes cycles are a single node, and
+// ignores back-edges. The cycle is visited from the entry in the same
+// topological-like ordering.
+//
+// This means once we visit a node, we know all the possible ancestors have 
been
+// visited.
+//
+// clang-format off
+//
+// Given this graph:
+//
+// ,-> B -\
+// A -++---> D > E -> F -> G -> H
+// `-> C -/  ^ |
+//   +-+
+//
+// Visit order is:
+//  A, [B, C in any order], D, E, F, G, H
+//
+// clang-format on
+//
+// Changing the function CFG between the construction of the visitor and
+// visiting is undefined. The visitor can be reused, but if the CFG is updated,
+// the visitor must be rebuilt.
+class PartialOrderingVisitor {
+  DomTreeBuilder::BBDomTree DT;
+  LoopInfo LI;
+  BlockSet Visited;
+  std::unordered_map B2R;
+  std::vector> Order;
+
+  // Get all basic-blocks reachable from Start.
+  BlockSet getReachableFrom(BasicBlock *Start) {
+std::queue ToVisit;
+ToVisit.push(Start);
+
+BlockSet Output;
+while (ToVisit.size() != 0) {
+  BasicBlock *BB = ToVisit.front();
+  ToVisit.pop();
+
+  if (Output.count(BB) != 0)
+continue;
+  Output.insert(BB);
+
+  for (BasicBlock *Successor : successors(BB)) {
+if (DT.dominates(Successor, BB))
+  continue;
+ToVisit.push(Successor);
+  }
+}
+
+return Output;
+  }
+
+  size_t visit(BasicBlock *BB, size_t Rank) {
+if (Visited.count(BB) != 0)
+  return Rank;
+
+Loop *L = LI.getLoopFor(BB);
+const bool isLoopHeader = LI.isLoopHeader(BB);
+
+if (B2R.count(BB) == 0) {
+  B2R.emplace(BB, Rank);
+} else {
+  B2R[BB] = std::max(B2R[BB], Rank);
+}
+
+for (BasicBlock *Predecessor : predecessors(BB)) {
+  if (isLoopHeader && L->contains(Predecessor)) {
+continue;
+  }
+
+  if (B2R.count(Predecessor) == 0) {
+return Rank;
+  }
+}
+
+Visited.insert(BB);
+
+SmallVector OtherSuccessors;
+BasicBlock *LoopSuccessor = nullptr;
+
+for (BasicBlock *Successor : successors(BB)) {
+  // Ignoring back-edges.
+  if (DT.dominates(Successor, BB))
+continue;
+
+  if (isLoopHeader && L->contains(Successor)) {
+assert(LoopSuccessor == nullptr);
+LoopSuccessor = Successor;
+  } else
+OtherSuccessors.push_back(Successor);
+}
+
+if (LoopSuccessor)
+  Rank = visit(LoopSuccessor, Rank + 1);
+
+size_t OutputRank = Rank;
+for (BasicBlock *Item : OtherSuccessors)
+  OutputRank = std::max(OutputRank, visit(Item, Rank + 1));
+return OutputRank;
+  };
+
+public:
+  // Build the visitor to operate on the function F.
+  PartialOrderingVisitor(Function &F) {
+DT.recalculate(F);
+LI = LoopInfo(DT);
+
+visit(&*F.begin(), 0);
+
+for (auto &[BB, Rank] : B2R)
+  Order.emplace_back(BB, Rank);
+
+std::sort(Order.begin(), Order.end(), [](const auto &LHS, const auto &RHS) 
{
+  return LHS.second < RHS.second;
+});
+
+for (size_t i = 0; i < Order.size(); i++)
+  B2R[Order[i].first] = i;
+  }
+
+  // Visit the function starting from the basic block |Start|, and calling |Op|
+  // on each visited BB. This traversal ignores back-edges, meaning this won't
+  // visit a node to which |Start| is not an ancestor.
+  void partialOrder

[clang] [llvm] [SPIR-V] Add SPIR-V structurizer (PR #107408)

2024-09-09 Thread Nathan Gauër via cfe-commits


@@ -0,0 +1,1410 @@
+//===-- SPIRVStructurizer.cpp --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//===--===//
+
+#include "Analysis/SPIRVConvergenceRegionAnalysis.h"
+#include "SPIRV.h"
+#include "SPIRVSubtarget.h"
+#include "SPIRVTargetMachine.h"
+#include "SPIRVUtils.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/CodeGen/IntrinsicLowering.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicsSPIRV.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Transforms/Utils/LoopSimplify.h"
+#include "llvm/Transforms/Utils/LowerMemIntrinsics.h"
+#include 
+#include 
+
+using namespace llvm;
+using namespace SPIRV;
+
+namespace llvm {
+
+void initializeSPIRVStructurizerPass(PassRegistry &);
+
+namespace {
+
+using BlockSet = std::unordered_set;
+using Edge = std::pair;
+
+// This class implements a partial ordering visitor, which visits a cyclic 
graph
+// in natural topological-like ordering. Topological ordering is not defined 
for
+// directed graphs with cycles, so this assumes cycles are a single node, and
+// ignores back-edges. The cycle is visited from the entry in the same
+// topological-like ordering.
+//
+// This means once we visit a node, we know all the possible ancestors have 
been
+// visited.
+//
+// clang-format off
+//
+// Given this graph:
+//
+// ,-> B -\
+// A -++---> D > E -> F -> G -> H
+// `-> C -/  ^ |
+//   +-+
+//
+// Visit order is:
+//  A, [B, C in any order], D, E, F, G, H
+//
+// clang-format on
+//
+// Changing the function CFG between the construction of the visitor and
+// visiting is undefined. The visitor can be reused, but if the CFG is updated,
+// the visitor must be rebuilt.
+class PartialOrderingVisitor {
+  DomTreeBuilder::BBDomTree DT;
+  LoopInfo LI;
+  BlockSet Visited;
+  std::unordered_map B2R;
+  std::vector> Order;
+
+  // Get all basic-blocks reachable from Start.
+  BlockSet getReachableFrom(BasicBlock *Start) {
+std::queue ToVisit;
+ToVisit.push(Start);
+
+BlockSet Output;
+while (ToVisit.size() != 0) {
+  BasicBlock *BB = ToVisit.front();
+  ToVisit.pop();
+
+  if (Output.count(BB) != 0)
+continue;
+  Output.insert(BB);
+
+  for (BasicBlock *Successor : successors(BB)) {
+if (DT.dominates(Successor, BB))
+  continue;
+ToVisit.push(Successor);
+  }
+}
+
+return Output;
+  }
+
+  size_t visit(BasicBlock *BB, size_t Rank) {
+if (Visited.count(BB) != 0)
+  return Rank;
+
+Loop *L = LI.getLoopFor(BB);
+const bool isLoopHeader = LI.isLoopHeader(BB);
+
+if (B2R.count(BB) == 0) {
+  B2R.emplace(BB, Rank);
+} else {
+  B2R[BB] = std::max(B2R[BB], Rank);
+}
+
+for (BasicBlock *Predecessor : predecessors(BB)) {
+  if (isLoopHeader && L->contains(Predecessor)) {
+continue;
+  }
+
+  if (B2R.count(Predecessor) == 0) {
+return Rank;
+  }
+}
+
+Visited.insert(BB);
+
+SmallVector OtherSuccessors;
+BasicBlock *LoopSuccessor = nullptr;
+
+for (BasicBlock *Successor : successors(BB)) {
+  // Ignoring back-edges.
+  if (DT.dominates(Successor, BB))
+continue;
+
+  if (isLoopHeader && L->contains(Successor)) {
+assert(LoopSuccessor == nullptr);
+LoopSuccessor = Successor;
+  } else
+OtherSuccessors.push_back(Successor);
+}
+
+if (LoopSuccessor)
+  Rank = visit(LoopSuccessor, Rank + 1);
+
+size_t OutputRank = Rank;
+for (BasicBlock *Item : OtherSuccessors)
+  OutputRank = std::max(OutputRank, visit(Item, Rank + 1));
+return OutputRank;
+  };
+
+public:
+  // Build the visitor to operate on the function F.
+  PartialOrderingVisitor(Function &F) {
+DT.recalculate(F);
+LI = LoopInfo(DT);
+
+visit(&*F.begin(), 0);
+
+for (auto &[BB, Rank] : B2R)
+  Order.emplace_back(BB, Rank);
+
+std::sort(Order.begin(), Order.end(), [](const auto &LHS, const auto &RHS) 
{
+  return LHS.second < RHS.second;
+});
+
+for (size_t i = 0; i < Order.size(); i++)
+  B2R[Order[i].first] = i;
+  }
+
+  // Visit the function starting from the basic block |Start|, and calling |Op|
+  // on each visited BB. This traversal ignores back-edges, meaning this won't
+  // visit a node to which |Start| is not an ancestor.
+  void partialOrder

[clang] [RISCV] Add testcase for -mcmodel= (PR #107816)

2024-09-09 Thread Sam Elliott via cfe-commits

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


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


[clang] [llvm] [SPIR-V] Add SPIR-V structurizer (PR #107408)

2024-09-09 Thread Nathan Gauër via cfe-commits


@@ -0,0 +1,1410 @@
+//===-- SPIRVStructurizer.cpp --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//===--===//
+
+#include "Analysis/SPIRVConvergenceRegionAnalysis.h"
+#include "SPIRV.h"
+#include "SPIRVSubtarget.h"
+#include "SPIRVTargetMachine.h"
+#include "SPIRVUtils.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/CodeGen/IntrinsicLowering.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicsSPIRV.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Transforms/Utils/LoopSimplify.h"
+#include "llvm/Transforms/Utils/LowerMemIntrinsics.h"
+#include 
+#include 
+
+using namespace llvm;
+using namespace SPIRV;
+
+namespace llvm {
+
+void initializeSPIRVStructurizerPass(PassRegistry &);
+
+namespace {
+
+using BlockSet = std::unordered_set;
+using Edge = std::pair;
+
+// This class implements a partial ordering visitor, which visits a cyclic 
graph
+// in natural topological-like ordering. Topological ordering is not defined 
for
+// directed graphs with cycles, so this assumes cycles are a single node, and
+// ignores back-edges. The cycle is visited from the entry in the same
+// topological-like ordering.
+//
+// This means once we visit a node, we know all the possible ancestors have 
been
+// visited.
+//
+// clang-format off
+//
+// Given this graph:
+//
+// ,-> B -\
+// A -++---> D > E -> F -> G -> H
+// `-> C -/  ^ |
+//   +-+
+//
+// Visit order is:
+//  A, [B, C in any order], D, E, F, G, H
+//
+// clang-format on
+//
+// Changing the function CFG between the construction of the visitor and
+// visiting is undefined. The visitor can be reused, but if the CFG is updated,
+// the visitor must be rebuilt.
+class PartialOrderingVisitor {
+  DomTreeBuilder::BBDomTree DT;
+  LoopInfo LI;
+  BlockSet Visited;
+  std::unordered_map B2R;
+  std::vector> Order;
+
+  // Get all basic-blocks reachable from Start.
+  BlockSet getReachableFrom(BasicBlock *Start) {
+std::queue ToVisit;
+ToVisit.push(Start);
+
+BlockSet Output;
+while (ToVisit.size() != 0) {
+  BasicBlock *BB = ToVisit.front();
+  ToVisit.pop();
+
+  if (Output.count(BB) != 0)
+continue;
+  Output.insert(BB);
+
+  for (BasicBlock *Successor : successors(BB)) {
+if (DT.dominates(Successor, BB))
+  continue;
+ToVisit.push(Successor);
+  }
+}
+
+return Output;
+  }
+
+  size_t visit(BasicBlock *BB, size_t Rank) {
+if (Visited.count(BB) != 0)
+  return Rank;
+
+Loop *L = LI.getLoopFor(BB);
+const bool isLoopHeader = LI.isLoopHeader(BB);
+
+if (B2R.count(BB) == 0) {
+  B2R.emplace(BB, Rank);
+} else {
+  B2R[BB] = std::max(B2R[BB], Rank);
+}
+
+for (BasicBlock *Predecessor : predecessors(BB)) {
+  if (isLoopHeader && L->contains(Predecessor)) {
+continue;
+  }
+
+  if (B2R.count(Predecessor) == 0) {
+return Rank;
+  }
+}
+
+Visited.insert(BB);
+
+SmallVector OtherSuccessors;
+BasicBlock *LoopSuccessor = nullptr;
+
+for (BasicBlock *Successor : successors(BB)) {
+  // Ignoring back-edges.
+  if (DT.dominates(Successor, BB))
+continue;
+
+  if (isLoopHeader && L->contains(Successor)) {
+assert(LoopSuccessor == nullptr);
+LoopSuccessor = Successor;
+  } else
+OtherSuccessors.push_back(Successor);
+}
+
+if (LoopSuccessor)
+  Rank = visit(LoopSuccessor, Rank + 1);
+
+size_t OutputRank = Rank;
+for (BasicBlock *Item : OtherSuccessors)
+  OutputRank = std::max(OutputRank, visit(Item, Rank + 1));
+return OutputRank;
+  };
+
+public:
+  // Build the visitor to operate on the function F.
+  PartialOrderingVisitor(Function &F) {
+DT.recalculate(F);
+LI = LoopInfo(DT);
+
+visit(&*F.begin(), 0);
+
+for (auto &[BB, Rank] : B2R)
+  Order.emplace_back(BB, Rank);
+
+std::sort(Order.begin(), Order.end(), [](const auto &LHS, const auto &RHS) 
{
+  return LHS.second < RHS.second;
+});
+
+for (size_t i = 0; i < Order.size(); i++)
+  B2R[Order[i].first] = i;
+  }
+
+  // Visit the function starting from the basic block |Start|, and calling |Op|
+  // on each visited BB. This traversal ignores back-edges, meaning this won't
+  // visit a node to which |Start| is not an ancestor.
+  void partialOrder

[clang] [lldb] [ASTImporter][lldb] Avoid implicit imports in VisitFieldDecl (PR #107828)

2024-09-09 Thread Andrew Savonichev via cfe-commits

https://github.com/asavonic created 
https://github.com/llvm/llvm-project/pull/107828

Fields from external sources are typically loaded implicitly by `RecordDecl` or 
`DeclContext` iterators and other functions (see LoadFieldsFromExternalStorage 
function and its uses). The assumption is that we only need to load such fields 
whenever a complete list of fields is necessary. However, there are cases where 
implicit loads are not expected and they may break AST importer logic.

In ASTNodeImporter::VisitFieldDecl:

  1) We first check that a field is not imported already.
  2) Then proceed to import it.
  3) Finally add it to the record with `setLexicalDeclContext` and 
`addDeclInternal`.

If an implicit import happens between (2) and (3), it may indirectly bring the 
same field into the context. When (3) happens we add it again, duplicating the 
field and breaking the record. This is not detected until we crash later during 
layout computation:

llvm/clang/lib/AST/RecordLayoutBuilder.cpp:81
Assertion `FieldOffsets.count(FD) && "Field does not have an external 
offset"' failed.

Detecting a possible duplication is difficult, especially considering that 
`addDeclInternal` may cause an implicit import as well.

The patch attempts to workaround this problem by triggering implicit imports 
before (1). However, it is hard to tell if it covers all the cases, because 
some of them are nested: `DeclContext::addHiddenDecl` calls 
`CXXRecordDecl::addedMember`, which calls `Type::isLiteralType` on a base type, 
which tries to iterate over fields and cause an implicit load.

It is quite tricky to get a reproducer for such problems, because they depend 
on order of imports of fields and records. Debugging Unreal Engine v5.3.2 with 
LLDB shows this problem once issue #90938 is fixed or workarounded. Only some 
UE classes are affected. Reducing it down to a LIT test is problematic due to 
size of libraries involved, and "flaky" nature of the problem.

TestCppReferenceToOuterClass shows an improvement with the patch, but it likely 
has no relation to the problem.

>From ee3a6a5b4eef069c5cef2820aeab5ab773df69a4 Mon Sep 17 00:00:00 2001
From: Andrew Savonichev 
Date: Mon, 9 Sep 2024 17:56:20 +0900
Subject: [PATCH] [ASTImporter][lldb] Avoid implicit imports in VisitFieldDecl

Fields from external sources are typically loaded implicitly by
`RecordDecl` or `DeclContext` iterators and other functions (see
LoadFieldsFromExternalStorage function and its uses). The assumption
is that we only need to load such fields whenever a complete list of
fields is necessary. However, there are cases where implicit loads are
not expected and they may break AST importer logic.

In ASTNodeImporter::VisitFieldDecl:

  1) We first check that a field is not imported already.
  2) Then proceed to import it.
  3) Finally add it to the record with `setLexicalDeclContext` and 
`addDeclInternal`.

If an implicit import happens between (2) and (3), it may indirectly
bring the same field into the context. When (3) happens we add it
again, duplicating the field and breaking the record. This is not
detected until we crash later during layout computation:

  llvm/clang/lib/AST/RecordLayoutBuilder.cpp:81
  Assertion `FieldOffsets.count(FD) && "Field does not have an external 
offset"' failed.

Detecting a possible duplication is difficult, especially considering
that `addDeclInternal` may cause an implicit import as well.

The patch attempts to workaround this problem by triggering implicit
imports before (1). However, it is hard to tell if it covers all the
cases, because some of them are nested: `DeclContext::addHiddenDecl`
calls `CXXRecordDecl::addedMember`, which calls `Type::isLiteralType`
on a base type, which tries to iterate over fields and cause an
implicit load.

It is quite tricky to get a reproducer for such problems, because they
depend on order of imports of fields and records. Debugging Unreal
Engine v5.3.2 with LLDB shows this problem once issue #90938 is fixed
or workarounded. Only some UE classes are affected. Reducing it down
to a LIT test is problematic due to size of libraries involved, and
"flaky" nature of the problem.

TestCppReferenceToOuterClass shows an improvement with the patch, but
it likely has no relation to the problem.
---
 clang/lib/AST/ASTImporter.cpp | 22 +--
 .../TestCppReferenceToOuterClass.py   |  1 -
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index c2fb7dddcfc637..6e48f21c57d9d6 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -4172,6 +4172,26 @@ ExpectedDecl ASTNodeImporter::VisitFieldDecl(FieldDecl 
*D) {
   if (ToD)
 return ToD;
 
+  // Implicit imports of external fields may import the same field
+  // *after* we check for its presence with findDeclsInToCtx. If this
+  // happens we may import the field twice and break the record
+  // type.
+  //
+

[clang] [lldb] [ASTImporter][lldb] Avoid implicit imports in VisitFieldDecl (PR #107828)

2024-09-09 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Andrew Savonichev (asavonic)


Changes

Fields from external sources are typically loaded implicitly by `RecordDecl` or 
`DeclContext` iterators and other functions (see LoadFieldsFromExternalStorage 
function and its uses). The assumption is that we only need to load such fields 
whenever a complete list of fields is necessary. However, there are cases where 
implicit loads are not expected and they may break AST importer logic.

In ASTNodeImporter::VisitFieldDecl:

  1) We first check that a field is not imported already.
  2) Then proceed to import it.
  3) Finally add it to the record with `setLexicalDeclContext` and 
`addDeclInternal`.

If an implicit import happens between (2) and (3), it may indirectly bring the 
same field into the context. When (3) happens we add it again, duplicating the 
field and breaking the record. This is not detected until we crash later during 
layout computation:

llvm/clang/lib/AST/RecordLayoutBuilder.cpp:81
Assertion `FieldOffsets.count(FD) && "Field does not have an 
external offset"' failed.

Detecting a possible duplication is difficult, especially considering that 
`addDeclInternal` may cause an implicit import as well.

The patch attempts to workaround this problem by triggering implicit imports 
before (1). However, it is hard to tell if it covers all the cases, because 
some of them are nested: `DeclContext::addHiddenDecl` calls 
`CXXRecordDecl::addedMember`, which calls `Type::isLiteralType` on a base type, 
which tries to iterate over fields and cause an implicit load.

It is quite tricky to get a reproducer for such problems, because they depend 
on order of imports of fields and records. Debugging Unreal Engine v5.3.2 with 
LLDB shows this problem once issue #90938 is fixed or workarounded. 
Only some UE classes are affected. Reducing it down to a LIT test is 
problematic due to size of libraries involved, and "flaky" nature of the 
problem.

TestCppReferenceToOuterClass shows an improvement with the patch, but it likely 
has no relation to the problem.

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


2 Files Affected:

- (modified) clang/lib/AST/ASTImporter.cpp (+20-2) 
- (modified) 
lldb/test/API/lang/cpp/reference-to-outer-type/TestCppReferenceToOuterClass.py 
(-1) 


``diff
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index c2fb7dddcfc637..6e48f21c57d9d6 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -4172,6 +4172,26 @@ ExpectedDecl ASTNodeImporter::VisitFieldDecl(FieldDecl 
*D) {
   if (ToD)
 return ToD;
 
+  // Implicit imports of external fields may import the same field
+  // *after* we check for its presence with findDeclsInToCtx. If this
+  // happens we may import the field twice and break the record
+  // type.
+  //
+  // Force import the context now to avoid this problem.
+  DC->decls_begin();
+  LexicalDC->decls_begin();
+
+  // C++ types may cause an import of fields later, so force import them too.
+  Error Err = Error::success();
+  auto ToType = importChecked(Err, D->getType());
+  if (!ToType.isNull()) {
+if (const auto *RT = ToType->getAs()) {
+  if (const auto *ClassDecl = dyn_cast(RT->getDecl())) {
+ClassDecl->decls_begin();
+  }
+}
+  }
+
   // Determine whether we've already imported this field.
   auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
   for (auto *FoundDecl : FoundDecls) {
@@ -4217,8 +4237,6 @@ ExpectedDecl ASTNodeImporter::VisitFieldDecl(FieldDecl 
*D) {
 }
   }
 
-  Error Err = Error::success();
-  auto ToType = importChecked(Err, D->getType());
   auto ToTInfo = importChecked(Err, D->getTypeSourceInfo());
   auto ToBitWidth = importChecked(Err, D->getBitWidth());
   auto ToInnerLocStart = importChecked(Err, D->getInnerLocStart());
diff --git 
a/lldb/test/API/lang/cpp/reference-to-outer-type/TestCppReferenceToOuterClass.py
 
b/lldb/test/API/lang/cpp/reference-to-outer-type/TestCppReferenceToOuterClass.py
index a6e419b7fcdfa2..cb28e2b31fad14 100644
--- 
a/lldb/test/API/lang/cpp/reference-to-outer-type/TestCppReferenceToOuterClass.py
+++ 
b/lldb/test/API/lang/cpp/reference-to-outer-type/TestCppReferenceToOuterClass.py
@@ -6,7 +6,6 @@
 
 
 class TestCase(TestBase):
-@unittest.expectedFailure  # The fix for this was reverted due to 
llvm.org/PR52257
 def test(self):
 self.build()
 self.dbg.CreateTarget(self.getBuildArtifact("a.out"))

``




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


[clang] [llvm] [SPIR-V] Add SPIR-V structurizer (PR #107408)

2024-09-09 Thread Nathan Gauër via cfe-commits


@@ -0,0 +1,1410 @@
+//===-- SPIRVStructurizer.cpp --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//===--===//
+
+#include "Analysis/SPIRVConvergenceRegionAnalysis.h"
+#include "SPIRV.h"
+#include "SPIRVSubtarget.h"
+#include "SPIRVTargetMachine.h"
+#include "SPIRVUtils.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/CodeGen/IntrinsicLowering.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicsSPIRV.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Transforms/Utils/LoopSimplify.h"
+#include "llvm/Transforms/Utils/LowerMemIntrinsics.h"
+#include 
+#include 
+
+using namespace llvm;
+using namespace SPIRV;
+
+namespace llvm {
+
+void initializeSPIRVStructurizerPass(PassRegistry &);
+
+namespace {
+
+using BlockSet = std::unordered_set;
+using Edge = std::pair;
+
+// This class implements a partial ordering visitor, which visits a cyclic 
graph
+// in natural topological-like ordering. Topological ordering is not defined 
for
+// directed graphs with cycles, so this assumes cycles are a single node, and
+// ignores back-edges. The cycle is visited from the entry in the same
+// topological-like ordering.
+//
+// This means once we visit a node, we know all the possible ancestors have 
been
+// visited.
+//
+// clang-format off
+//
+// Given this graph:
+//
+// ,-> B -\
+// A -++---> D > E -> F -> G -> H
+// `-> C -/  ^ |
+//   +-+
+//
+// Visit order is:
+//  A, [B, C in any order], D, E, F, G, H
+//
+// clang-format on
+//
+// Changing the function CFG between the construction of the visitor and
+// visiting is undefined. The visitor can be reused, but if the CFG is updated,
+// the visitor must be rebuilt.
+class PartialOrderingVisitor {
+  DomTreeBuilder::BBDomTree DT;
+  LoopInfo LI;
+  BlockSet Visited;
+  std::unordered_map B2R;
+  std::vector> Order;
+
+  // Get all basic-blocks reachable from Start.
+  BlockSet getReachableFrom(BasicBlock *Start) {
+std::queue ToVisit;
+ToVisit.push(Start);
+
+BlockSet Output;
+while (ToVisit.size() != 0) {
+  BasicBlock *BB = ToVisit.front();
+  ToVisit.pop();
+
+  if (Output.count(BB) != 0)
+continue;
+  Output.insert(BB);
+
+  for (BasicBlock *Successor : successors(BB)) {
+if (DT.dominates(Successor, BB))
+  continue;
+ToVisit.push(Successor);
+  }
+}
+
+return Output;
+  }
+
+  size_t visit(BasicBlock *BB, size_t Rank) {
+if (Visited.count(BB) != 0)
+  return Rank;
+
+Loop *L = LI.getLoopFor(BB);
+const bool isLoopHeader = LI.isLoopHeader(BB);
+
+if (B2R.count(BB) == 0) {
+  B2R.emplace(BB, Rank);
+} else {
+  B2R[BB] = std::max(B2R[BB], Rank);
+}
+
+for (BasicBlock *Predecessor : predecessors(BB)) {
+  if (isLoopHeader && L->contains(Predecessor)) {
+continue;
+  }
+
+  if (B2R.count(Predecessor) == 0) {
+return Rank;
+  }
+}
+
+Visited.insert(BB);
+
+SmallVector OtherSuccessors;
+BasicBlock *LoopSuccessor = nullptr;
+
+for (BasicBlock *Successor : successors(BB)) {
+  // Ignoring back-edges.
+  if (DT.dominates(Successor, BB))
+continue;
+
+  if (isLoopHeader && L->contains(Successor)) {
+assert(LoopSuccessor == nullptr);
+LoopSuccessor = Successor;
+  } else
+OtherSuccessors.push_back(Successor);
+}
+
+if (LoopSuccessor)
+  Rank = visit(LoopSuccessor, Rank + 1);
+
+size_t OutputRank = Rank;
+for (BasicBlock *Item : OtherSuccessors)
+  OutputRank = std::max(OutputRank, visit(Item, Rank + 1));
+return OutputRank;
+  };
+
+public:
+  // Build the visitor to operate on the function F.
+  PartialOrderingVisitor(Function &F) {
+DT.recalculate(F);
+LI = LoopInfo(DT);
+
+visit(&*F.begin(), 0);
+
+for (auto &[BB, Rank] : B2R)
+  Order.emplace_back(BB, Rank);
+
+std::sort(Order.begin(), Order.end(), [](const auto &LHS, const auto &RHS) 
{
+  return LHS.second < RHS.second;
+});
+
+for (size_t i = 0; i < Order.size(); i++)
+  B2R[Order[i].first] = i;
+  }
+
+  // Visit the function starting from the basic block |Start|, and calling |Op|
+  // on each visited BB. This traversal ignores back-edges, meaning this won't
+  // visit a node to which |Start| is not an ancestor.
+  void partialOrder

[clang] [llvm] [AArch64] Implement NEON vamin/vamax intrinsics (PR #99041)

2024-09-09 Thread Momchil Velikov via cfe-commits

https://github.com/momchil-velikov updated 
https://github.com/llvm/llvm-project/pull/99041

>From 0cca71a770750e34474d7734c8f803fb31feacee Mon Sep 17 00:00:00 2001
From: Momchil Velikov 
Date: Mon, 15 Jul 2024 17:50:43 +0100
Subject: [PATCH 1/4] [AArch64] Implement NEON vamin/vamax intrinsics

This patch implements the intrinsics of the form

floatNxM_t vamin[q]_fN(floatNxM_t vn, floatNxM_t vm);
floatNxM_t vamax[q]_fN(floatNxM_t vn, floatNxM_t vm);

as defined in https://github.com/ARM-software/acle/pull/324

Co-authored-by: Hassnaa Hamdi 
---
 clang/include/clang/Basic/arm_neon.td |   7 +-
 clang/lib/CodeGen/CGBuiltin.cpp   |  17 +++
 .../aarch64-neon-faminmax-intrinsics.c| 112 ++
 llvm/include/llvm/IR/IntrinsicsAArch64.td |   3 +
 .../lib/Target/AArch64/AArch64InstrFormats.td |  20 
 llvm/lib/Target/AArch64/AArch64InstrInfo.td   |   6 +-
 llvm/test/CodeGen/AArch64/neon-famin-famax.ll |  96 +++
 7 files changed, 258 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/CodeGen/aarch64-neon-faminmax-intrinsics.c
 create mode 100644 llvm/test/CodeGen/AArch64/neon-famin-famax.ll

diff --git a/clang/include/clang/Basic/arm_neon.td 
b/clang/include/clang/Basic/arm_neon.td
index 875ec6e90b685b..4f6dc314941200 100644
--- a/clang/include/clang/Basic/arm_neon.td
+++ b/clang/include/clang/Basic/arm_neon.td
@@ -2120,4 +2120,9 @@ let ArchGuard = "defined(__aarch64__)", TargetGuard = 
"lut" in {
 def VLUTI4_BF_X2_Q   : SInst<"vluti4_laneq_x2", ".2(]>;
   }
-}
\ No newline at end of file
+}
+
+let ArchGuard = "defined(__aarch64__)", TargetGuard = "faminmax" in {
+  def FAMIN : WInst<"vamin", "...", "fhQdQfQh">;
+  def FAMAX : WInst<"vamax", "...", "fhQdQfQh">;
+}
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index da7a1a55da5313..b0dd299edaf9cc 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -13573,6 +13573,23 @@ Value 
*CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
 Int = Intrinsic::aarch64_neon_vluti4q_laneq_x2;
 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vluti4q_laneq_x2");
   }
+
+  case NEON::BI__builtin_neon_vamin_f16:
+  case NEON::BI__builtin_neon_vaminq_f16:
+  case NEON::BI__builtin_neon_vamin_f32:
+  case NEON::BI__builtin_neon_vaminq_f32:
+  case NEON::BI__builtin_neon_vaminq_f64: {
+Int = Intrinsic::aarch64_neon_famin;
+return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "famin");
+  }
+  case NEON::BI__builtin_neon_vamax_f16:
+  case NEON::BI__builtin_neon_vamaxq_f16:
+  case NEON::BI__builtin_neon_vamax_f32:
+  case NEON::BI__builtin_neon_vamaxq_f32:
+  case NEON::BI__builtin_neon_vamaxq_f64: {
+Int = Intrinsic::aarch64_neon_famax;
+return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "famax");
+  }
   }
 }
 
diff --git a/clang/test/CodeGen/aarch64-neon-faminmax-intrinsics.c 
b/clang/test/CodeGen/aarch64-neon-faminmax-intrinsics.c
new file mode 100644
index 00..631e9738b85c5f
--- /dev/null
+++ b/clang/test/CodeGen/aarch64-neon-faminmax-intrinsics.c
@@ -0,0 +1,112 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 5
+#include 
+
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon 
-target-feature +faminmax -O3 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon 
-target-feature +faminmax -S -O3 -Werror -Wall -o /dev/null %s
+
+// CHECK-LABEL: define dso_local <4 x half> @test_vamin_f16(
+// CHECK-SAME: <4 x half> noundef [[VN:%.*]], <4 x half> noundef [[VM:%.*]]) 
local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[FAMIN2_I:%.*]] = tail call <4 x half> 
@llvm.aarch64.neon.famin.v4f16(<4 x half> [[VN]], <4 x half> [[VM]])
+// CHECK-NEXT:ret <4 x half> [[FAMIN2_I]]
+//
+float16x4_t test_vamin_f16(float16x4_t vn, float16x4_t vm) {
+  return vamin_f16(vn, vm);
+}
+
+// CHECK-LABEL: define dso_local <8 x half> @test_vaminq_f16(
+// CHECK-SAME: <8 x half> noundef [[VN:%.*]], <8 x half> noundef [[VM:%.*]]) 
local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[FAMIN2_I:%.*]] = tail call <8 x half> 
@llvm.aarch64.neon.famin.v8f16(<8 x half> [[VN]], <8 x half> [[VM]])
+// CHECK-NEXT:ret <8 x half> [[FAMIN2_I]]
+//
+float16x8_t test_vaminq_f16(float16x8_t vn, float16x8_t vm) {
+  return vaminq_f16(vn, vm);
+
+}
+
+// CHECK-LABEL: define dso_local <2 x float> @test_vamin_f32(
+// CHECK-SAME: <2 x float> noundef [[VN:%.*]], <2 x float> noundef [[VM:%.*]]) 
local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[FAMIN2_I:%.*]] = tail call <2 x float> 
@llvm.aarch64.neon.famin.v2f32(<2 x float> [[VN]], <2 x float> [[VM]])
+// CHECK-NEXT:ret <2 x float> [[FAMIN2_I]]
+//
+float32x2_t test_vamin_f32(float32x2_t vn, float32x2_t vm) {
+  return vamin_f32(vn, vm);
+
+}
+
+// CHECK-

[clang] [lldb] [ASTImporter][lldb] Avoid implicit imports in VisitFieldDecl (PR #107828)

2024-09-09 Thread Michael Buch via cfe-commits

Michael137 wrote:

Thanks for taking a stab at this and for the analysis. You rightly point out 
that this is the root problem: 
 
> If an implicit import happens between (2) and (3), it may indirectly bring 
> the same field into the context. When (3) happens we add it again, 
> duplicating the field and breaking the record. This is not detected until we 
> crash later during layout computation:

And the LLDB test that was XFAILed, is a special case of exactly this problem 
(summarized well in https://reviews.llvm.org/D102993).

The more complete solution here is to make LLDB stop relying on this sort of 
import-pattern. We've been told in the past that the ASTImporter just wasn't 
designed for this use-case. Ideally, we'd remove the need for minimally 
importing record types (which is actually something I've been working on, 
though I can't promise a timeline of when this is supposed to land). In my 
opinion, adding complexity like this into the ASTImporter just to support LLDB 
is going to make it a maintenance burden on both. So I'd vote for trying to 
solve this properly.

I do wonder whether there's something about the build configuration that makes 
you hit this crash more likely in UE. Are you building with precompiled headers 
by any chance? Or with `-flimit-debug-info`?

I'm actually looking at a similar crash at the moment for which I have a 
reproducer. I'm trying to extract it into a smaller test-case.

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


[clang] Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by aggregate initialization using a default member initializer" (PR #97308)

2024-09-09 Thread via cfe-commits


@@ -206,19 +206,28 @@ namespace cwg1814 { // cwg1814: yes
 #endif
 }
 
-namespace cwg1815 { // cwg1815: no
+namespace cwg1815 { // cwg1815: 19

yronglin wrote:

Oh, I missed this! I'll fix it. Thank you for point out this.

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


[clang] [llvm] [SPIR-V] Add SPIR-V structurizer (PR #107408)

2024-09-09 Thread Nathan Gauër via cfe-commits


@@ -0,0 +1,1410 @@
+//===-- SPIRVStructurizer.cpp --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//===--===//
+
+#include "Analysis/SPIRVConvergenceRegionAnalysis.h"
+#include "SPIRV.h"
+#include "SPIRVSubtarget.h"
+#include "SPIRVTargetMachine.h"
+#include "SPIRVUtils.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/CodeGen/IntrinsicLowering.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicsSPIRV.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Transforms/Utils/LoopSimplify.h"
+#include "llvm/Transforms/Utils/LowerMemIntrinsics.h"
+#include 
+#include 
+
+using namespace llvm;
+using namespace SPIRV;
+
+namespace llvm {
+
+void initializeSPIRVStructurizerPass(PassRegistry &);
+
+namespace {
+
+using BlockSet = std::unordered_set;
+using Edge = std::pair;
+
+// This class implements a partial ordering visitor, which visits a cyclic 
graph
+// in natural topological-like ordering. Topological ordering is not defined 
for
+// directed graphs with cycles, so this assumes cycles are a single node, and
+// ignores back-edges. The cycle is visited from the entry in the same
+// topological-like ordering.
+//
+// This means once we visit a node, we know all the possible ancestors have 
been
+// visited.
+//
+// clang-format off
+//
+// Given this graph:
+//
+// ,-> B -\
+// A -++---> D > E -> F -> G -> H
+// `-> C -/  ^ |
+//   +-+
+//
+// Visit order is:
+//  A, [B, C in any order], D, E, F, G, H
+//
+// clang-format on
+//
+// Changing the function CFG between the construction of the visitor and
+// visiting is undefined. The visitor can be reused, but if the CFG is updated,
+// the visitor must be rebuilt.
+class PartialOrderingVisitor {
+  DomTreeBuilder::BBDomTree DT;
+  LoopInfo LI;
+  BlockSet Visited;
+  std::unordered_map B2R;
+  std::vector> Order;
+
+  // Get all basic-blocks reachable from Start.
+  BlockSet getReachableFrom(BasicBlock *Start) {
+std::queue ToVisit;
+ToVisit.push(Start);
+
+BlockSet Output;
+while (ToVisit.size() != 0) {
+  BasicBlock *BB = ToVisit.front();
+  ToVisit.pop();
+
+  if (Output.count(BB) != 0)
+continue;
+  Output.insert(BB);
+
+  for (BasicBlock *Successor : successors(BB)) {
+if (DT.dominates(Successor, BB))
+  continue;
+ToVisit.push(Successor);
+  }
+}
+
+return Output;
+  }
+
+  size_t visit(BasicBlock *BB, size_t Rank) {
+if (Visited.count(BB) != 0)
+  return Rank;
+
+Loop *L = LI.getLoopFor(BB);
+const bool isLoopHeader = LI.isLoopHeader(BB);
+
+if (B2R.count(BB) == 0) {
+  B2R.emplace(BB, Rank);
+} else {
+  B2R[BB] = std::max(B2R[BB], Rank);
+}
+
+for (BasicBlock *Predecessor : predecessors(BB)) {
+  if (isLoopHeader && L->contains(Predecessor)) {
+continue;
+  }
+
+  if (B2R.count(Predecessor) == 0) {
+return Rank;
+  }
+}
+
+Visited.insert(BB);
+
+SmallVector OtherSuccessors;
+BasicBlock *LoopSuccessor = nullptr;
+
+for (BasicBlock *Successor : successors(BB)) {
+  // Ignoring back-edges.
+  if (DT.dominates(Successor, BB))
+continue;
+
+  if (isLoopHeader && L->contains(Successor)) {
+assert(LoopSuccessor == nullptr);
+LoopSuccessor = Successor;
+  } else
+OtherSuccessors.push_back(Successor);
+}
+
+if (LoopSuccessor)
+  Rank = visit(LoopSuccessor, Rank + 1);
+
+size_t OutputRank = Rank;
+for (BasicBlock *Item : OtherSuccessors)
+  OutputRank = std::max(OutputRank, visit(Item, Rank + 1));
+return OutputRank;
+  };
+
+public:
+  // Build the visitor to operate on the function F.
+  PartialOrderingVisitor(Function &F) {
+DT.recalculate(F);
+LI = LoopInfo(DT);
+
+visit(&*F.begin(), 0);
+
+for (auto &[BB, Rank] : B2R)
+  Order.emplace_back(BB, Rank);
+
+std::sort(Order.begin(), Order.end(), [](const auto &LHS, const auto &RHS) 
{
+  return LHS.second < RHS.second;
+});
+
+for (size_t i = 0; i < Order.size(); i++)
+  B2R[Order[i].first] = i;
+  }
+
+  // Visit the function starting from the basic block |Start|, and calling |Op|
+  // on each visited BB. This traversal ignores back-edges, meaning this won't
+  // visit a node to which |Start| is not an ancestor.
+  void partialOrder

[clang] [llvm] [SPIR-V] Add SPIR-V structurizer (PR #107408)

2024-09-09 Thread Nathan Gauër via cfe-commits

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


[clang] [llvm] [SPIR-V] Add SPIR-V structurizer (PR #107408)

2024-09-09 Thread Nathan Gauër via cfe-commits

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


[clang] [llvm] [SPIR-V] Add SPIR-V structurizer (PR #107408)

2024-09-09 Thread Nathan Gauër via cfe-commits


@@ -0,0 +1,1410 @@
+//===-- SPIRVStructurizer.cpp --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//===--===//
+
+#include "Analysis/SPIRVConvergenceRegionAnalysis.h"
+#include "SPIRV.h"
+#include "SPIRVSubtarget.h"
+#include "SPIRVTargetMachine.h"
+#include "SPIRVUtils.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/CodeGen/IntrinsicLowering.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicsSPIRV.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Transforms/Utils/LoopSimplify.h"
+#include "llvm/Transforms/Utils/LowerMemIntrinsics.h"
+#include 
+#include 
+
+using namespace llvm;
+using namespace SPIRV;
+
+namespace llvm {
+
+void initializeSPIRVStructurizerPass(PassRegistry &);
+
+namespace {
+
+using BlockSet = std::unordered_set;
+using Edge = std::pair;
+
+// This class implements a partial ordering visitor, which visits a cyclic 
graph
+// in natural topological-like ordering. Topological ordering is not defined 
for
+// directed graphs with cycles, so this assumes cycles are a single node, and
+// ignores back-edges. The cycle is visited from the entry in the same
+// topological-like ordering.
+//
+// This means once we visit a node, we know all the possible ancestors have 
been
+// visited.
+//
+// clang-format off
+//
+// Given this graph:
+//
+// ,-> B -\
+// A -++---> D > E -> F -> G -> H
+// `-> C -/  ^ |
+//   +-+
+//
+// Visit order is:
+//  A, [B, C in any order], D, E, F, G, H
+//
+// clang-format on
+//
+// Changing the function CFG between the construction of the visitor and
+// visiting is undefined. The visitor can be reused, but if the CFG is updated,
+// the visitor must be rebuilt.
+class PartialOrderingVisitor {
+  DomTreeBuilder::BBDomTree DT;
+  LoopInfo LI;
+  BlockSet Visited;
+  std::unordered_map B2R;
+  std::vector> Order;
+
+  // Get all basic-blocks reachable from Start.
+  BlockSet getReachableFrom(BasicBlock *Start) {
+std::queue ToVisit;
+ToVisit.push(Start);
+
+BlockSet Output;
+while (ToVisit.size() != 0) {
+  BasicBlock *BB = ToVisit.front();
+  ToVisit.pop();
+
+  if (Output.count(BB) != 0)
+continue;
+  Output.insert(BB);
+
+  for (BasicBlock *Successor : successors(BB)) {
+if (DT.dominates(Successor, BB))
+  continue;
+ToVisit.push(Successor);
+  }
+}
+
+return Output;
+  }
+
+  size_t visit(BasicBlock *BB, size_t Rank) {
+if (Visited.count(BB) != 0)
+  return Rank;
+
+Loop *L = LI.getLoopFor(BB);
+const bool isLoopHeader = LI.isLoopHeader(BB);
+
+if (B2R.count(BB) == 0) {
+  B2R.emplace(BB, Rank);
+} else {
+  B2R[BB] = std::max(B2R[BB], Rank);
+}
+
+for (BasicBlock *Predecessor : predecessors(BB)) {
+  if (isLoopHeader && L->contains(Predecessor)) {
+continue;
+  }
+
+  if (B2R.count(Predecessor) == 0) {
+return Rank;
+  }
+}
+
+Visited.insert(BB);
+
+SmallVector OtherSuccessors;
+BasicBlock *LoopSuccessor = nullptr;
+
+for (BasicBlock *Successor : successors(BB)) {
+  // Ignoring back-edges.
+  if (DT.dominates(Successor, BB))
+continue;
+
+  if (isLoopHeader && L->contains(Successor)) {
+assert(LoopSuccessor == nullptr);
+LoopSuccessor = Successor;
+  } else
+OtherSuccessors.push_back(Successor);
+}
+
+if (LoopSuccessor)
+  Rank = visit(LoopSuccessor, Rank + 1);
+
+size_t OutputRank = Rank;
+for (BasicBlock *Item : OtherSuccessors)
+  OutputRank = std::max(OutputRank, visit(Item, Rank + 1));
+return OutputRank;
+  };
+
+public:
+  // Build the visitor to operate on the function F.
+  PartialOrderingVisitor(Function &F) {
+DT.recalculate(F);
+LI = LoopInfo(DT);
+
+visit(&*F.begin(), 0);
+
+for (auto &[BB, Rank] : B2R)
+  Order.emplace_back(BB, Rank);
+
+std::sort(Order.begin(), Order.end(), [](const auto &LHS, const auto &RHS) 
{
+  return LHS.second < RHS.second;
+});
+
+for (size_t i = 0; i < Order.size(); i++)
+  B2R[Order[i].first] = i;
+  }
+
+  // Visit the function starting from the basic block |Start|, and calling |Op|
+  // on each visited BB. This traversal ignores back-edges, meaning this won't
+  // visit a node to which |Start| is not an ancestor.
+  void partialOrder

[clang] [llvm] [SPIR-V] Add SPIR-V structurizer (PR #107408)

2024-09-09 Thread Nathan Gauër via cfe-commits


@@ -0,0 +1,1410 @@
+//===-- SPIRVStructurizer.cpp --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//===--===//
+
+#include "Analysis/SPIRVConvergenceRegionAnalysis.h"
+#include "SPIRV.h"
+#include "SPIRVSubtarget.h"
+#include "SPIRVTargetMachine.h"
+#include "SPIRVUtils.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/CodeGen/IntrinsicLowering.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicsSPIRV.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Transforms/Utils/LoopSimplify.h"
+#include "llvm/Transforms/Utils/LowerMemIntrinsics.h"
+#include 
+#include 
+
+using namespace llvm;
+using namespace SPIRV;
+
+namespace llvm {
+
+void initializeSPIRVStructurizerPass(PassRegistry &);
+
+namespace {
+
+using BlockSet = std::unordered_set;
+using Edge = std::pair;
+
+// This class implements a partial ordering visitor, which visits a cyclic 
graph
+// in natural topological-like ordering. Topological ordering is not defined 
for
+// directed graphs with cycles, so this assumes cycles are a single node, and
+// ignores back-edges. The cycle is visited from the entry in the same
+// topological-like ordering.
+//
+// This means once we visit a node, we know all the possible ancestors have 
been
+// visited.
+//
+// clang-format off
+//
+// Given this graph:
+//
+// ,-> B -\
+// A -++---> D > E -> F -> G -> H
+// `-> C -/  ^ |
+//   +-+
+//
+// Visit order is:
+//  A, [B, C in any order], D, E, F, G, H
+//
+// clang-format on
+//
+// Changing the function CFG between the construction of the visitor and
+// visiting is undefined. The visitor can be reused, but if the CFG is updated,
+// the visitor must be rebuilt.
+class PartialOrderingVisitor {
+  DomTreeBuilder::BBDomTree DT;
+  LoopInfo LI;
+  BlockSet Visited;
+  std::unordered_map B2R;
+  std::vector> Order;
+
+  // Get all basic-blocks reachable from Start.
+  BlockSet getReachableFrom(BasicBlock *Start) {
+std::queue ToVisit;
+ToVisit.push(Start);
+
+BlockSet Output;
+while (ToVisit.size() != 0) {
+  BasicBlock *BB = ToVisit.front();
+  ToVisit.pop();
+
+  if (Output.count(BB) != 0)
+continue;
+  Output.insert(BB);
+
+  for (BasicBlock *Successor : successors(BB)) {
+if (DT.dominates(Successor, BB))
+  continue;
+ToVisit.push(Successor);
+  }
+}
+
+return Output;
+  }
+
+  size_t visit(BasicBlock *BB, size_t Rank) {
+if (Visited.count(BB) != 0)
+  return Rank;
+
+Loop *L = LI.getLoopFor(BB);
+const bool isLoopHeader = LI.isLoopHeader(BB);
+
+if (B2R.count(BB) == 0) {
+  B2R.emplace(BB, Rank);
+} else {
+  B2R[BB] = std::max(B2R[BB], Rank);
+}
+
+for (BasicBlock *Predecessor : predecessors(BB)) {
+  if (isLoopHeader && L->contains(Predecessor)) {
+continue;
+  }
+
+  if (B2R.count(Predecessor) == 0) {
+return Rank;
+  }
+}
+
+Visited.insert(BB);
+
+SmallVector OtherSuccessors;
+BasicBlock *LoopSuccessor = nullptr;
+
+for (BasicBlock *Successor : successors(BB)) {
+  // Ignoring back-edges.
+  if (DT.dominates(Successor, BB))
+continue;
+
+  if (isLoopHeader && L->contains(Successor)) {
+assert(LoopSuccessor == nullptr);
+LoopSuccessor = Successor;
+  } else
+OtherSuccessors.push_back(Successor);
+}
+
+if (LoopSuccessor)
+  Rank = visit(LoopSuccessor, Rank + 1);
+
+size_t OutputRank = Rank;
+for (BasicBlock *Item : OtherSuccessors)
+  OutputRank = std::max(OutputRank, visit(Item, Rank + 1));
+return OutputRank;
+  };
+
+public:
+  // Build the visitor to operate on the function F.
+  PartialOrderingVisitor(Function &F) {
+DT.recalculate(F);
+LI = LoopInfo(DT);
+
+visit(&*F.begin(), 0);
+
+for (auto &[BB, Rank] : B2R)
+  Order.emplace_back(BB, Rank);
+
+std::sort(Order.begin(), Order.end(), [](const auto &LHS, const auto &RHS) 
{
+  return LHS.second < RHS.second;
+});
+
+for (size_t i = 0; i < Order.size(); i++)
+  B2R[Order[i].first] = i;
+  }
+
+  // Visit the function starting from the basic block |Start|, and calling |Op|
+  // on each visited BB. This traversal ignores back-edges, meaning this won't
+  // visit a node to which |Start| is not an ancestor.
+  void partialOrder

[clang] [PS4, PS5][Driver] Detangle --sysroot and -isysroot (PR #107410)

2024-09-09 Thread Edd Dawson via cfe-commits

https://github.com/playstation-edd updated 
https://github.com/llvm/llvm-project/pull/107410

>From a20158570f15b4200937650b90e07b99e230e3df Mon Sep 17 00:00:00 2001
From: Edd Dawson 
Date: Wed, 4 Sep 2024 12:30:11 +0100
Subject: [PATCH 1/3] [PS4,PS5][Driver] Detangle --sysroot and -isysroot

The following discrepancies concerning `-isysroot` and `--sysroot`
motivated this change:

- The SDK directory can be specified via `-isysroot`, but `--sysroot`
  has no influence over this. Yet, we check for the presence of either
  switch to determine whether we ought to warn about a missing SDK
  *headers*.

- The presence of `-isysroot` is ignored when deciding whether to warn
  about missing SDK *libraries*, depsite it being the only switch
  capable of specifying a non-default SDK location.

- The `--sysroot`s passed to the PlayStation linkers by the driver are
  unrelated to the SDK directory resolved in the PS4PS5Base constructor.

(We also ought to pass a sysroot-relative library search path to the
linker via `-L=/target/lib`, but that's for another PR).

So we're half way between two worlds, currently:

World 1: `-isysroot` and `--sysroot=` mean the same thing and each may
 override the SDK directory, from which both header and library
 search paths are derived.
World 2: `-isysroot` influences header search paths and `--sysroot=`
 influences library search paths. Each independently defaults
 to the SDK directory.

This change commits to world 2, which seems to offer more flexibility
for the user and better adheres to the principle of least surprise for
those familiar with these options outside of a PlayStation development
environment.

The test updates to ps{4,5}-sdk-root.c were of the scale of a rewrite so
I also took the opportunity to clarify the purpose of each part,
eliminate some redundancy and add some missing coverage.

SIE tracker: TOOLCHAIN-16704
---
 clang/lib/Driver/ToolChains/PS4CPU.cpp| 81 -
 clang/lib/Driver/ToolChains/PS4CPU.h  |  7 +-
 clang/test/Driver/ps4-linker.c|  9 +++
 clang/test/Driver/ps4-ps5-header-search.c |  4 +-
 clang/test/Driver/ps4-sdk-root.c  | 89 +--
 clang/test/Driver/ps5-linker.c|  9 +++
 clang/test/Driver/ps5-sdk-root.c  | 89 +--
 7 files changed, 175 insertions(+), 113 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/PS4CPU.cpp 
b/clang/lib/Driver/ToolChains/PS4CPU.cpp
index 54ec59e6398f85..ddb5917b86a7c7 100644
--- a/clang/lib/Driver/ToolChains/PS4CPU.cpp
+++ b/clang/lib/Driver/ToolChains/PS4CPU.cpp
@@ -135,8 +135,8 @@ void tools::PS4cpu::Linker::ConstructJob(Compilation &C, 
const JobAction &JA,
   // handled somewhere else.
   Args.ClaimAllArgs(options::OPT_w);
 
-  if (!D.SysRoot.empty())
-CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+  CmdArgs.push_back(
+  Args.MakeArgString("--sysroot=" + TC.getSDKLibraryRootDir()));
 
   if (Args.hasArg(options::OPT_pie))
 CmdArgs.push_back("-pie");
@@ -234,8 +234,8 @@ void tools::PS5cpu::Linker::ConstructJob(Compilation &C, 
const JobAction &JA,
   // handled somewhere else.
   Args.ClaimAllArgs(options::OPT_w);
 
-  if (!D.SysRoot.empty())
-CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+  CmdArgs.push_back(
+  Args.MakeArgString("--sysroot=" + TC.getSDKLibraryRootDir()));
 
   // Default to PIE for non-static executables.
   const bool PIE =
@@ -323,46 +323,57 @@ toolchains::PS4PS5Base::PS4PS5Base(const Driver &D, const 
llvm::Triple &Triple,
const ArgList &Args, StringRef Platform,
const char *EnvVar)
 : Generic_ELF(D, Triple, Args) {
-  // Determine where to find the PS4/PS5 libraries.
-  // If -isysroot was passed, use that as the SDK base path.
-  // If not, we use the EnvVar if it exists; otherwise use the driver's
-  // installation path, which should be /host_tools/bin.
+  // Determine the baseline SDK directory from the environment, else
+  // the driver's location, which should be /host_tools/bin.
+  SmallString<128> SDKRootDir;
   SmallString<80> Whence;
-  if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
-SDKRootDir = A->getValue();
-if (!llvm::sys::fs::exists(SDKRootDir))
-  D.Diag(clang::diag::warn_missing_sysroot) << SDKRootDir;
-Whence = A->getSpelling();
-  } else if (const char *EnvValue = getenv(EnvVar)) {
+  if (const char *EnvValue = getenv(EnvVar)) {
 SDKRootDir = EnvValue;
-Whence = { "environment variable '", EnvVar, "'" };
+Whence = {"environment variable '", EnvVar, "'"};
   } else {
 SDKRootDir = D.Dir + "/../../";
 Whence = "compiler's location";
   }
 
-  SmallString<512> SDKIncludeDir(SDKRootDir);
-  llvm::sys::path::append(SDKIncludeDir, "target/include");
-  if (!Args.hasArg(options::OPT_nostdinc) &&
-  !Args.hasArg(options::OPT_nostdlibinc) &&
-  !Args.hasArg(optio

[clang] [llvm] [SPIR-V] Add SPIR-V structurizer (PR #107408)

2024-09-09 Thread Nathan Gauër via cfe-commits


@@ -744,79 +744,139 @@ static void insertSpirvDecorations(MachineFunction &MF, 
MachineIRBuilder MIB) {
 MI->eraseFromParent();
 }
 
-// Find basic blocks of the switch and replace registers in spv_switch() by its
-// MBB equivalent.
-static void processSwitches(MachineFunction &MF, SPIRVGlobalRegistry *GR,
-MachineIRBuilder MIB) {
-  DenseMap BB2MBB;
-  SmallVector>>
-  Switches;
+// LLVM allows the switches to use registers as cases, while SPIR-V required
+// those to be immediate values. This function replaces such operands with the
+// equivalent immediate constant.
+static void processSwitchesConstants(MachineFunction &MF,
+ SPIRVGlobalRegistry *GR,
+ MachineIRBuilder MIB) {
+  MachineRegisterInfo &MRI = MF.getRegInfo();
   for (MachineBasicBlock &MBB : MF) {
-MachineRegisterInfo &MRI = MF.getRegInfo();
-BB2MBB[MBB.getBasicBlock()] = &MBB;
 for (MachineInstr &MI : MBB) {
   if (!isSpvIntrinsic(MI, Intrinsic::spv_switch))
 continue;
-  // Calls to spv_switch intrinsics representing IR switches.
-  SmallVector NewOps;
-  for (unsigned i = 2; i < MI.getNumOperands(); ++i) {
+
+  SmallVector NewOperands;
+  NewOperands.push_back(MI.getOperand(0)); // Opcode
+  NewOperands.push_back(MI.getOperand(1)); // Condition
+  NewOperands.push_back(MI.getOperand(2)); // Default
+  for (unsigned i = 3; i < MI.getNumOperands(); i += 2) {
 Register Reg = MI.getOperand(i).getReg();
-if (i % 2 == 1) {
-  MachineInstr *ConstInstr = getDefInstrMaybeConstant(Reg, &MRI);
-  NewOps.push_back(ConstInstr);
-} else {
-  MachineInstr *BuildMBB = MRI.getVRegDef(Reg);
-  assert(BuildMBB &&
- BuildMBB->getOpcode() == TargetOpcode::G_BLOCK_ADDR &&
- BuildMBB->getOperand(1).isBlockAddress() &&
- BuildMBB->getOperand(1).getBlockAddress());
-  NewOps.push_back(BuildMBB);
-}
+MachineInstr *ConstInstr = getDefInstrMaybeConstant(Reg, &MRI);
+NewOperands.push_back(
+MachineOperand::CreateCImm(ConstInstr->getOperand(1).getCImm()));
+
+NewOperands.push_back(MI.getOperand(i + 1));
   }
-  Switches.push_back(std::make_pair(&MI, NewOps));
+
+  assert(MI.getNumOperands() == NewOperands.size());
+  while (MI.getNumOperands() > 0)
+MI.removeOperand(0);
+  for (auto &MO : NewOperands)
+MI.addOperand(MO);
 }
   }
+}
 
+// Some instructions are used during CodeGen but should never be emitted.
+// Cleaning up those.
+static void cleanupHelperInstructions(MachineFunction &MF) {
   SmallPtrSet ToEraseMI;
+  for (MachineBasicBlock &MBB : MF) {
+for (MachineInstr &MI : MBB) {
+  if (isSpvIntrinsic(MI, Intrinsic::spv_track_constant) ||
+  MI.getOpcode() == TargetOpcode::G_BRINDIRECT)
+ToEraseMI.insert(&MI);
+}
+  }
+
+  for (MachineInstr *MI : ToEraseMI)
+MI->eraseFromParent();
+}
+
+// Find all usages of G_BLOCK_ADDR in our intrinsics and replace those
+// operands/registers by the actual MBB it references.
+static void processBlockAddr(MachineFunction &MF, SPIRVGlobalRegistry *GR,
+ MachineIRBuilder MIB) {
+  // Gather the reverse-mapping BB -> MBB.
+  DenseMap BB2MBB;
+  for (MachineBasicBlock &MBB : MF)
+BB2MBB[MBB.getBasicBlock()] = &MBB;
+
+  // Gather instructions requiring patching. For now, only those can use
+  // G_BLOCK_ADDR.
+  SmallVector InstructionsToPatch;
+  for (MachineBasicBlock &MBB : MF) {
+for (MachineInstr &MI : MBB) {
+  if (isSpvIntrinsic(MI, Intrinsic::spv_switch) ||
+  isSpvIntrinsic(MI, Intrinsic::spv_loop_merge) ||
+  isSpvIntrinsic(MI, Intrinsic::spv_selection_merge))
+InstructionsToPatch.push_back(&MI);
+}
+  }
+
+  // For each instruction to fix, we replace all the G_BLOCK_ADDR operands by
+  // the actual MBB it references. Once those references updated, we can 
cleanup
+  // remaining G_BLOCK_ADDR references.
   SmallPtrSet ClearAddressTaken;
-  for (auto &SwIt : Switches) {
-MachineInstr &MI = *SwIt.first;
-MachineBasicBlock *MBB = MI.getParent();
-SmallVector &Ins = SwIt.second;
+  SmallPtrSet ToEraseMI;
+  MachineRegisterInfo &MRI = MF.getRegInfo();
+  for (MachineInstr *MI : InstructionsToPatch) {
 SmallVector NewOps;
-for (unsigned i = 0; i < Ins.size(); ++i) {
-  if (Ins[i]->getOpcode() == TargetOpcode::G_BLOCK_ADDR) {
-BasicBlock *CaseBB =
-Ins[i]->getOperand(1).getBlockAddress()->getBasicBlock();
-auto It = BB2MBB.find(CaseBB);
-if (It == BB2MBB.end())
-  report_fatal_error("cannot find a machine basic block by a basic "
- "block in a switch statement");
-MachineBasicBlock *Succ = It->second;
-ClearAddressTaken.insert(Succ);
-Ne

[clang] [llvm] [SPIR-V] Add SPIR-V structurizer (PR #107408)

2024-09-09 Thread Nathan Gauër via cfe-commits


@@ -744,79 +744,139 @@ static void insertSpirvDecorations(MachineFunction &MF, 
MachineIRBuilder MIB) {
 MI->eraseFromParent();
 }
 
-// Find basic blocks of the switch and replace registers in spv_switch() by its
-// MBB equivalent.
-static void processSwitches(MachineFunction &MF, SPIRVGlobalRegistry *GR,
-MachineIRBuilder MIB) {
-  DenseMap BB2MBB;
-  SmallVector>>
-  Switches;
+// LLVM allows the switches to use registers as cases, while SPIR-V required
+// those to be immediate values. This function replaces such operands with the
+// equivalent immediate constant.
+static void processSwitchesConstants(MachineFunction &MF,
+ SPIRVGlobalRegistry *GR,
+ MachineIRBuilder MIB) {
+  MachineRegisterInfo &MRI = MF.getRegInfo();
   for (MachineBasicBlock &MBB : MF) {
-MachineRegisterInfo &MRI = MF.getRegInfo();
-BB2MBB[MBB.getBasicBlock()] = &MBB;
 for (MachineInstr &MI : MBB) {
   if (!isSpvIntrinsic(MI, Intrinsic::spv_switch))
 continue;
-  // Calls to spv_switch intrinsics representing IR switches.
-  SmallVector NewOps;
-  for (unsigned i = 2; i < MI.getNumOperands(); ++i) {
+
+  SmallVector NewOperands;
+  NewOperands.push_back(MI.getOperand(0)); // Opcode
+  NewOperands.push_back(MI.getOperand(1)); // Condition
+  NewOperands.push_back(MI.getOperand(2)); // Default
+  for (unsigned i = 3; i < MI.getNumOperands(); i += 2) {
 Register Reg = MI.getOperand(i).getReg();
-if (i % 2 == 1) {
-  MachineInstr *ConstInstr = getDefInstrMaybeConstant(Reg, &MRI);
-  NewOps.push_back(ConstInstr);
-} else {
-  MachineInstr *BuildMBB = MRI.getVRegDef(Reg);
-  assert(BuildMBB &&
- BuildMBB->getOpcode() == TargetOpcode::G_BLOCK_ADDR &&
- BuildMBB->getOperand(1).isBlockAddress() &&
- BuildMBB->getOperand(1).getBlockAddress());
-  NewOps.push_back(BuildMBB);
-}
+MachineInstr *ConstInstr = getDefInstrMaybeConstant(Reg, &MRI);
+NewOperands.push_back(
+MachineOperand::CreateCImm(ConstInstr->getOperand(1).getCImm()));
+
+NewOperands.push_back(MI.getOperand(i + 1));
   }
-  Switches.push_back(std::make_pair(&MI, NewOps));
+
+  assert(MI.getNumOperands() == NewOperands.size());
+  while (MI.getNumOperands() > 0)
+MI.removeOperand(0);
+  for (auto &MO : NewOperands)
+MI.addOperand(MO);
 }
   }
+}
 
+// Some instructions are used during CodeGen but should never be emitted.
+// Cleaning up those.
+static void cleanupHelperInstructions(MachineFunction &MF) {
   SmallPtrSet ToEraseMI;

Keenuts wrote:

That's correct! updated.

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


[clang] Add Clang attribute to ensure that fields are initialized explicitly (PR #102040)

2024-09-09 Thread Ilya Biryukov via cfe-commits

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


[clang] Add Clang attribute to ensure that fields are initialized explicitly (PR #102040)

2024-09-09 Thread Ilya Biryukov via cfe-commits

https://github.com/ilya-biryukov commented:

I think there are some good parallel disscussions happening in the RFC, but 
despite their outcomes, we could probably update the PR to capture current 
behavior in those interesting cases.

I left a few comments along those lines, PTAL. 

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


[clang] Add Clang attribute to ensure that fields are initialized explicitly (PR #102040)

2024-09-09 Thread Ilya Biryukov via cfe-commits


@@ -1472,3 +1472,25 @@ template struct Outer {
   };
 };
 Outer::Inner outerinner;
+
+void aggregate() {

ilya-biryukov wrote:

Could we add examples from @AaronBallman's [RFC 
comment](https://discourse.llvm.org/t/rfc-add-clang-attribute-to-ensure-that-fields-are-initialized-explicitly/80626/20)?

This raises all the same interesting questions that he mentioned, I am leaning 
towards limiting the support on any cases that require significant work to 
support (e.g. empty struct, zero-width bitfields or all bitfields altogether) 
in the initial implementation and simply filing bugs to address those 
limitations later.
I do feel  we should warn that an attribute has no effect on those fields / 
structs if we choose to do so and test those warnings show up.

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


[clang] Add Clang attribute to ensure that fields are initialized explicitly (PR #102040)

2024-09-09 Thread Ilya Biryukov via cfe-commits


@@ -2133,6 +2142,18 @@ void 
CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) {
   for (conversion_iterator I = conversion_begin(), E = conversion_end();
I != E; ++I)
 I.setAccess((*I)->getAccess());
+
+  ASTContext &Context = getASTContext();
+  if (!Context.getLangOpts().CPlusPlus20 && hasUserDeclaredConstructor()) {
+// Diagnose any aggregate behavior changes in C++20
+for (field_iterator I = field_begin(), E = field_end(); I != E; ++I) {
+  if (const auto *attr = I->getAttr()) {
+Context.getDiagnostics().Report(
+getLocation(), diag::warn_cxx20_compat_aggregate_init_with_ctors)

ilya-biryukov wrote:

Should we add a new warning here?
`"Attribute [[clang:...]] will have no effect in C++20 as the type will be 
non-aggregate due to user-declared constructors"`.
The wording for an existing attribute suggests there is already some 
initialization of this type happening, which is not necessarily the case.

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


[clang] [llvm] Double run offloading (PR #107834)

2024-09-09 Thread Aleksei Romanov via cfe-commits

https://github.com/saveasguy created 
https://github.com/llvm/llvm-project/pull/107834

None

>From 5ca9c3f25663e78ea5205a901735b649756e9c1e Mon Sep 17 00:00:00 2001
From: Aleksei Romanov 
Date: Wed, 20 Sep 2023 01:10:02 +0300
Subject: [PATCH 1/5] [LVN] Add tests on LVN Pass (NFC)

---
 llvm/include/llvm/Transforms/Scalar/LVN.h | 15 ++
 llvm/lib/Passes/PassBuilder.cpp   |  1 +
 llvm/lib/Passes/PassRegistry.def  |  1 +
 llvm/lib/Transforms/Scalar/CMakeLists.txt |  1 +
 llvm/lib/Transforms/Scalar/LVN.cpp|  7 +++
 llvm/test/Transforms/LVN/basic_tests.ll   | 66 +++
 6 files changed, 91 insertions(+)
 create mode 100644 llvm/include/llvm/Transforms/Scalar/LVN.h
 create mode 100644 llvm/lib/Transforms/Scalar/LVN.cpp
 create mode 100644 llvm/test/Transforms/LVN/basic_tests.ll

diff --git a/llvm/include/llvm/Transforms/Scalar/LVN.h 
b/llvm/include/llvm/Transforms/Scalar/LVN.h
new file mode 100644
index 00..a99e81a5922c8a
--- /dev/null
+++ b/llvm/include/llvm/Transforms/Scalar/LVN.h
@@ -0,0 +1,15 @@
+#ifndef LLVM_TRANSFORMS_SCALAR_LVN_H
+#define LLVM_TRANSFORMS_SCALAR_LVN_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class LVNPass : public PassInfoMixin {
+public:
+  PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_LVN_H
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 5c7f26109930c9..dc99c9408a20cd 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -201,6 +201,7 @@
 #include "llvm/Transforms/Scalar/LowerGuardIntrinsic.h"
 #include "llvm/Transforms/Scalar/LowerMatrixIntrinsics.h"
 #include "llvm/Transforms/Scalar/LowerWidenableCondition.h"
+#include "llvm/Transforms/Scalar/LVN.h"
 #include "llvm/Transforms/Scalar/MakeGuardsExplicit.h"
 #include "llvm/Transforms/Scalar/MemCpyOptimizer.h"
 #include "llvm/Transforms/Scalar/MergeICmps.h"
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index b9aa015d02dd95..1729eb6120db72 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -358,6 +358,7 @@ FUNCTION_PASS("loop-simplify", LoopSimplifyPass())
 FUNCTION_PASS("loop-sink", LoopSinkPass())
 FUNCTION_PASS("lowerinvoke", LowerInvokePass())
 FUNCTION_PASS("lowerswitch", LowerSwitchPass())
+FUNCTION_PASS("lvn", LVNPass())
 FUNCTION_PASS("mem2reg", PromotePass())
 FUNCTION_PASS("memcpyopt", MemCpyOptPass())
 FUNCTION_PASS("mergeicmps", MergeICmpsPass())
diff --git a/llvm/lib/Transforms/Scalar/CMakeLists.txt 
b/llvm/lib/Transforms/Scalar/CMakeLists.txt
index eb008c15903a74..1f39809420e4c7 100644
--- a/llvm/lib/Transforms/Scalar/CMakeLists.txt
+++ b/llvm/lib/Transforms/Scalar/CMakeLists.txt
@@ -52,6 +52,7 @@ add_llvm_component_library(LLVMScalarOpts
   LowerGuardIntrinsic.cpp
   LowerMatrixIntrinsics.cpp
   LowerWidenableCondition.cpp
+  LVN.cpp
   MakeGuardsExplicit.cpp
   MemCpyOptimizer.cpp
   MergeICmps.cpp
diff --git a/llvm/lib/Transforms/Scalar/LVN.cpp 
b/llvm/lib/Transforms/Scalar/LVN.cpp
new file mode 100644
index 00..e5daccf0d78dd5
--- /dev/null
+++ b/llvm/lib/Transforms/Scalar/LVN.cpp
@@ -0,0 +1,7 @@
+#include "llvm/Transforms/Scalar/LVN.h"
+
+using namespace llvm;
+
+PreservedAnalyses LVNPass::run(Function &F, FunctionAnalysisManager &FAM) {
+  return PreservedAnalyses::all();
+}
diff --git a/llvm/test/Transforms/LVN/basic_tests.ll 
b/llvm/test/Transforms/LVN/basic_tests.ll
new file mode 100644
index 00..a3197101db694a
--- /dev/null
+++ b/llvm/test/Transforms/LVN/basic_tests.ll
@@ -0,0 +1,66 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 
UTC_ARGS: --version 3
+; RUN: opt -passes='lvn,dce' -S < %s | FileCheck %s
+
+define i32 @redundant_add(i32 %a, i32 %b, i32  %c) {
+; CHECK-LABEL: define i32 @redundant_add(
+; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:[[ADD:%.*]] = add i32 [[A]], [[B]]
+; CHECK-NEXT:[[MUL:%.*]] = mul i32 [[B]], [[C]]
+; CHECK-NEXT:[[ADD1:%.*]] = add i32 [[A]], [[B]]
+; CHECK-NEXT:[[MUL2:%.*]] = mul i32 [[ADD]], [[MUL]]
+; CHECK-NEXT:[[ADD2:%.*]] = add i32 [[MUL2]], [[ADD1]]
+; CHECK-NEXT:ret i32 [[ADD2]]
+;
+entry:
+  %add = add i32 %a, %b
+  %mul = mul i32 %b, %c
+  %add1 = add i32 %a, %b
+  %mul2 = mul i32 %add, %mul
+  %add2 = add i32 %mul2, %add1
+  ret i32 %add2
+}
+
+define i32 @redundant_mul(i32 noundef %a, i32 noundef %b, i32 noundef %c) {
+; CHECK-LABEL: define i32 @redundant_mul(
+; CHECK-SAME: i32 noundef [[A:%.*]], i32 noundef [[B:%.*]], i32 noundef 
[[C:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:[[ADD:%.*]] = add i32 [[A]], [[B]]
+; CHECK-NEXT:[[MUL:%.*]] = mul i32 [[B]], [[C]]
+; CHECK-NEXT:[[MUL1:%.*]] = mul i32 [[B]], [[C]]
+; CHECK-NEXT:[[MUL2:%.*]] = mul i32 [[ADD]], [[MUL]]
+; CHECK-NEXT:[[ADD1:%.*]] = add i32 [[MUL2]], [[MUL1]]
+; CHECK-

[clang] [llvm] Double run offloading (PR #107834)

2024-09-09 Thread via cfe-commits

github-actions[bot] wrote:



Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this 
page.

If this is not working for you, it is probably because you do not have write 
permissions for the repository. In which case you can instead tag reviewers by 
name in a comment by using `@` followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a 
review by "ping"ing the PR by adding a comment “Ping”. The common courtesy 
"ping" rate is once a week. Please remember that you are asking for valuable 
time from other developers.

If you have further questions, they may be answered by the [LLVM GitHub User 
Guide](https://llvm.org/docs/GitHub.html).

You can also ask questions in a comment on this PR, on the [LLVM 
Discord](https://discord.com/invite/xS7Z362) or on the 
[forums](https://discourse.llvm.org/).

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


[clang] [llvm] Double run offloading (PR #107834)

2024-09-09 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-clang

@llvm/pr-subscribers-llvm-transforms

Author: Aleksei Romanov (saveasguy)


Changes



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


11 Files Affected:

- (modified) clang/include/clang/Driver/Options.td (+6) 
- (modified) clang/lib/Driver/Driver.cpp (+60) 
- (added) llvm/include/llvm/Transforms/Scalar/LVN.h (+18) 
- (modified) llvm/lib/Passes/PassBuilder.cpp (+1) 
- (modified) llvm/lib/Passes/PassRegistry.def (+1) 
- (modified) llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (+10-3) 
- (modified) llvm/lib/Transforms/Scalar/CMakeLists.txt (+1) 
- (added) llvm/lib/Transforms/Scalar/LVN.cpp (+50) 
- (modified) llvm/test/MC/RISCV/rvv/invalid.s (+26-26) 
- (modified) llvm/test/MC/RISCV/rvv/vsetvl.s (+6) 
- (added) llvm/test/Transforms/LVN/basic_tests.ll (+62) 


``diff
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 553c7928c4f949..0363f34ed790e1 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -6118,6 +6118,12 @@ def fno_sycl : Flag<["-"], "fno-sycl">, 
Flags<[NoXarchOption]>,
   Visibility<[ClangOption, CLOption]>,
   Group, HelpText<"Disables SYCL kernels compilation for device">;
 
+// double run options
+def fdoublerun : Flag<["-"], "fdoublerun">,
+  Group, HelpText<"Enables double run">;
+def fno_doublerun : Flag<["-"], "fno-doublerun">,
+  Group, HelpText<"Disables double run">;
+
 
//===--===//
 // FLangOption + NoXarchOption
 
//===--===//
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 84b8fc7685fed4..c5794e9644e5bf 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -2865,6 +2865,64 @@ class OffloadingActionBuilder final {
 }
   };
 
+  class MyActionBuilder : public DeviceActionBuilder {
+Action *FirstRunAction;
+  public:
+MyActionBuilder(Compilation &C, DerivedArgList &Args,
+const Driver::InputList &Inputs)
+: DeviceActionBuilder(C, Args, Inputs, Action::OFK_Host) {}
+
+bool initialize() override {
+  if (Args.hasFlag(options::OPT_fdoublerun, options::OPT_fno_doublerun,
+   false)) {
+const ToolChain *TC =
+C.getSingleOffloadToolChain();
+ToolChains.push_back(TC);
+return false;
+  }
+  return true;
+}
+
+ActionBuilderReturnCode addDeviceDependences(Action *HostAction) override {
+  if (auto *IA = dyn_cast(HostAction)) {
+FirstRunAction = C.MakeAction(
+IA->getInputArg(), IA->getType(), IA->getId());
+return ABRT_Success;
+  }
+  return ABRT_Inactive;
+}
+
+ActionBuilderReturnCode
+getDeviceDependences(OffloadAction::DeviceDependences &DA,
+ phases::ID CurPhase, phases::ID FinalPhase,
+ PhasesTy &Phases) override {
+  if (CurPhase != phases::Backend)
+return ABRT_Inactive;
+
+  assert(FirstRunAction);
+  Action *PrevFirstRunAction = FirstRunAction;
+  for (auto Ph : Phases) {
+if (Ph > CurPhase)
+  break;
+FirstRunAction = C.getDriver().ConstructPhaseAction(C, Args, Ph, 
FirstRunAction);
+// FirstRunAction
+  }
+  if (PrevFirstRunAction == FirstRunAction)
+return ABRT_Inactive;
+  DA.add(*FirstRunAction, *ToolChains.front(), 
ToolChains.front()->getArchName().data(), Action::OFK_Host);
+  return ABRT_Success;
+}
+
+StringRef getCanonicalOffloadArch(StringRef Arch) {
+  return Arch;
+}
+
+std::optional>
+getConflictOffloadArchCombination(const std::set &ArchSet) {
+  return std::nullopt;
+}
+  };
+
   /// Base class for CUDA/HIP action builder. It injects device code in
   /// the host backend action.
   class CudaActionBuilderBase : public DeviceActionBuilder {
@@ -3612,6 +3670,8 @@ class OffloadingActionBuilder final {
 // Create a specialized builder for HIP.
 SpecializedBuilders.push_back(new HIPActionBuilder(C, Args, Inputs));
 
+SpecializedBuilders.push_back(new MyActionBuilder(C, Args, Inputs));
+
 //
 // TODO: Build other specialized builders here.
 //
diff --git a/llvm/include/llvm/Transforms/Scalar/LVN.h 
b/llvm/include/llvm/Transforms/Scalar/LVN.h
new file mode 100644
index 00..de6feed0fc8837
--- /dev/null
+++ b/llvm/include/llvm/Transforms/Scalar/LVN.h
@@ -0,0 +1,18 @@
+#ifndef LLVM_TRANSFORMS_SCALAR_LVN_H
+#define LLVM_TRANSFORMS_SCALAR_LVN_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class LVNPass : public PassInfoMixin {
+public:
+  PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
+
+private:
+  void runOnBasicBlock(BasicBlock &BB);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_LVN_H
diff --git a/llvm/

[clang] [llvm] Double run offloading (PR #107834)

2024-09-09 Thread Aleksei Romanov via cfe-commits

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


[clang] [PS4, PS5][Driver] Detangle --sysroot and -isysroot (PR #107410)

2024-09-09 Thread Edd Dawson via cfe-commits

https://github.com/playstation-edd updated 
https://github.com/llvm/llvm-project/pull/107410

>From a20158570f15b4200937650b90e07b99e230e3df Mon Sep 17 00:00:00 2001
From: Edd Dawson 
Date: Wed, 4 Sep 2024 12:30:11 +0100
Subject: [PATCH 1/4] [PS4,PS5][Driver] Detangle --sysroot and -isysroot

The following discrepancies concerning `-isysroot` and `--sysroot`
motivated this change:

- The SDK directory can be specified via `-isysroot`, but `--sysroot`
  has no influence over this. Yet, we check for the presence of either
  switch to determine whether we ought to warn about a missing SDK
  *headers*.

- The presence of `-isysroot` is ignored when deciding whether to warn
  about missing SDK *libraries*, depsite it being the only switch
  capable of specifying a non-default SDK location.

- The `--sysroot`s passed to the PlayStation linkers by the driver are
  unrelated to the SDK directory resolved in the PS4PS5Base constructor.

(We also ought to pass a sysroot-relative library search path to the
linker via `-L=/target/lib`, but that's for another PR).

So we're half way between two worlds, currently:

World 1: `-isysroot` and `--sysroot=` mean the same thing and each may
 override the SDK directory, from which both header and library
 search paths are derived.
World 2: `-isysroot` influences header search paths and `--sysroot=`
 influences library search paths. Each independently defaults
 to the SDK directory.

This change commits to world 2, which seems to offer more flexibility
for the user and better adheres to the principle of least surprise for
those familiar with these options outside of a PlayStation development
environment.

The test updates to ps{4,5}-sdk-root.c were of the scale of a rewrite so
I also took the opportunity to clarify the purpose of each part,
eliminate some redundancy and add some missing coverage.

SIE tracker: TOOLCHAIN-16704
---
 clang/lib/Driver/ToolChains/PS4CPU.cpp| 81 -
 clang/lib/Driver/ToolChains/PS4CPU.h  |  7 +-
 clang/test/Driver/ps4-linker.c|  9 +++
 clang/test/Driver/ps4-ps5-header-search.c |  4 +-
 clang/test/Driver/ps4-sdk-root.c  | 89 +--
 clang/test/Driver/ps5-linker.c|  9 +++
 clang/test/Driver/ps5-sdk-root.c  | 89 +--
 7 files changed, 175 insertions(+), 113 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/PS4CPU.cpp 
b/clang/lib/Driver/ToolChains/PS4CPU.cpp
index 54ec59e6398f85..ddb5917b86a7c7 100644
--- a/clang/lib/Driver/ToolChains/PS4CPU.cpp
+++ b/clang/lib/Driver/ToolChains/PS4CPU.cpp
@@ -135,8 +135,8 @@ void tools::PS4cpu::Linker::ConstructJob(Compilation &C, 
const JobAction &JA,
   // handled somewhere else.
   Args.ClaimAllArgs(options::OPT_w);
 
-  if (!D.SysRoot.empty())
-CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+  CmdArgs.push_back(
+  Args.MakeArgString("--sysroot=" + TC.getSDKLibraryRootDir()));
 
   if (Args.hasArg(options::OPT_pie))
 CmdArgs.push_back("-pie");
@@ -234,8 +234,8 @@ void tools::PS5cpu::Linker::ConstructJob(Compilation &C, 
const JobAction &JA,
   // handled somewhere else.
   Args.ClaimAllArgs(options::OPT_w);
 
-  if (!D.SysRoot.empty())
-CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+  CmdArgs.push_back(
+  Args.MakeArgString("--sysroot=" + TC.getSDKLibraryRootDir()));
 
   // Default to PIE for non-static executables.
   const bool PIE =
@@ -323,46 +323,57 @@ toolchains::PS4PS5Base::PS4PS5Base(const Driver &D, const 
llvm::Triple &Triple,
const ArgList &Args, StringRef Platform,
const char *EnvVar)
 : Generic_ELF(D, Triple, Args) {
-  // Determine where to find the PS4/PS5 libraries.
-  // If -isysroot was passed, use that as the SDK base path.
-  // If not, we use the EnvVar if it exists; otherwise use the driver's
-  // installation path, which should be /host_tools/bin.
+  // Determine the baseline SDK directory from the environment, else
+  // the driver's location, which should be /host_tools/bin.
+  SmallString<128> SDKRootDir;
   SmallString<80> Whence;
-  if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
-SDKRootDir = A->getValue();
-if (!llvm::sys::fs::exists(SDKRootDir))
-  D.Diag(clang::diag::warn_missing_sysroot) << SDKRootDir;
-Whence = A->getSpelling();
-  } else if (const char *EnvValue = getenv(EnvVar)) {
+  if (const char *EnvValue = getenv(EnvVar)) {
 SDKRootDir = EnvValue;
-Whence = { "environment variable '", EnvVar, "'" };
+Whence = {"environment variable '", EnvVar, "'"};
   } else {
 SDKRootDir = D.Dir + "/../../";
 Whence = "compiler's location";
   }
 
-  SmallString<512> SDKIncludeDir(SDKRootDir);
-  llvm::sys::path::append(SDKIncludeDir, "target/include");
-  if (!Args.hasArg(options::OPT_nostdinc) &&
-  !Args.hasArg(options::OPT_nostdlibinc) &&
-  !Args.hasArg(optio

[clang] [llvm] [Offload] Provide a kernel library useable by the offload runtime (PR #104168)

2024-09-09 Thread Jan Patrick Lehr via cfe-commits

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


[clang] [llvm] [Offload] Provide a kernel library useable by the offload runtime (PR #104168)

2024-09-09 Thread Jan Patrick Lehr via cfe-commits

https://github.com/jplehr commented:

I tried a bot-config build and it fails with a compiler error, see my comment.

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


[clang] [llvm] [Offload] Provide a kernel library useable by the offload runtime (PR #104168)

2024-09-09 Thread Jan Patrick Lehr via cfe-commits


@@ -1533,6 +1565,67 @@ Error GenericDeviceTy::printInfo() {
   return Plugin::success();
 }
 
+Expected GenericDeviceTy::getKernel(llvm::StringRef Name,
+   DeviceImageTy *ImagePtr,
+   bool Optional) {
+  bool KernelFound = false;
+  GenericKernelTy *&KernelPtr = KernelMap[Name];
+  if (!KernelPtr) {
+GenericGlobalHandlerTy &GHandler = Plugin.getGlobalHandler();
+
+auto CheckImage = [&](DeviceImageTy &Image) -> GenericKernelTy * {
+  if (!GHandler.isSymbolInImage(*this, Image, Name))
+return nullptr;
+  KernelFound = true;
+
+  auto KernelOrErr = constructKernelImpl(Name);
+  if (Error Err = KernelOrErr.takeError()) {
+[[maybe_unused]] std::string ErrStr = toString(std::move(Err));
+DP("Failed to construct kernel ('%s'): %s", Name.data(),
+   ErrStr.c_str());
+return nullptr;
+  }
+
+  GenericKernelTy &Kernel = *KernelOrErr;
+  if (auto Err = Kernel.init(*this, Image)) {
+[[maybe_unused]] std::string ErrStr = toString(std::move(Err));
+DP("Failed to initialize kernel ('%s'): %s", Name.data(),
+   ErrStr.c_str());
+return nullptr;
+  }
+
+  return &Kernel;
+};
+
+if (ImagePtr) {
+  KernelPtr = CheckImage(*ImagePtr);
+} else {
+  for (DeviceImageTy *Image : LoadedImages) {
+KernelPtr = CheckImage(*Image);
+if (KernelPtr)
+  break;
+  }
+}
+  }
+
+  // If we didn't find the kernel and it was optional, we do not emit an error.
+  if (!KernelPtr && !KernelFound && Optional)
+return nullptr;
+  // If we didn't find the kernel and it was not optional, we will emit an
+  // error.
+  if (!KernelPtr && !KernelFound)
+return Plugin::error(
+"Kernel '%s' not found%s", Name.data(),
+ImagePtr
+? ""
+: ", searched " + std::to_string(LoadedImages.size()) + " images");

jplehr wrote:

I believe this misses a `.data()` or something.

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


[clang] Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by aggregate initialization using a default member initializer" (PR #97308)

2024-09-09 Thread Martin Storsjö via cfe-commits

mstorsjo wrote:

This PR triggers failed asserts. This is reproducible with 
https://martin.st/temp/qtdeclarative-repro1.cpp, like this:
```
$ clang -target aarch64-w64-mingw32 -c qtdeclarative-repro1.cpp
Assertion failed: ((ND->isUsed(false) || !isa(ND) || E->isNonOdrUse() 
|| !E->getLocation().isValid()) && "Should not use decl without marking it 
used!"), function EmitDeclRefLValue, file 
/home/martin/code/llvm-project/clang/lib/CodeGen/CGExpr.cpp, line 3107.
```
(This file isn't the final reduced form, but creduce seems to be running quite 
slowly on this file, so it's a partially reduced testcase.)

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


[clang] [PS4, PS5][Driver] Detangle --sysroot and -isysroot (PR #107410)

2024-09-09 Thread Edd Dawson via cfe-commits


@@ -1,42 +1,64 @@
-// Check that PS4 clang doesn't report a warning message when locating
-// system header files (either by looking at the value of SCE_ORBIS_SDK_DIR
-// or relative to the location of the compiler driver), if "-nostdinc",
-// "--sysroot" or "-isysroot" option is specified on the command line.
-// Otherwise, check that PS4 clang reports a warning.
-
-// Check that PS4 clang doesn't report a warning message when locating
-// system libraries (either by looking at the value of SCE_ORBIS_SDK_DIR
-// or relative to the location of the compiler driver), if "-c", "-S", "-E"
-// or "--sysroot" option is specified on the command line.
-// Otherwise, check that PS4 clang reports a warning.
-
-// Setting up SCE_ORBIS_SDK_DIR to existing location, which is not a PS4 SDK.
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory 
-### -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-SYS-HEADERS 
-check-prefix=WARN-SYS-LIBS -check-prefix=NO-WARN %s
-
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory 
-### -c -target x86_64-scei-ps4 %s 2>&1 | FileCheck 
-check-prefix=WARN-SYS-HEADERS -check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory 
-### -S -target x86_64-scei-ps4 %s 2>&1 | FileCheck 
-check-prefix=WARN-SYS-HEADERS -check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory 
-### -E -target x86_64-scei-ps4 %s 2>&1 | FileCheck 
-check-prefix=WARN-SYS-HEADERS -check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory 
-### -emit-ast -target x86_64-scei-ps4 %s 2>&1 | FileCheck 
-check-prefix=WARN-SYS-HEADERS -check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory 
-### -isysroot foo -target x86_64-scei-ps4 %s 2>&1 | FileCheck 
-check-prefix=WARN-ISYSROOT -check-prefix=WARN-SYS-LIBS -check-prefix=NO-WARN %s
-
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory 
-### -c -nostdinc -target x86_64-scei-ps4 %s 2>&1 | FileCheck 
-check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory 
-### -S -nostdinc -target x86_64-scei-ps4 %s 2>&1 | FileCheck 
-check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory 
-### -E -nostdinc -target x86_64-scei-ps4 %s 2>&1 | FileCheck 
-check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory 
-### -emit-ast -nostdinc -target x86_64-scei-ps4 %s 2>&1 | FileCheck 
-check-prefix=NO-WARN %s
-
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory 
-### -c --sysroot=foo/ -target x86_64-scei-ps4 %s 2>&1 | FileCheck 
-check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory 
-### -S --sysroot=foo/ -target x86_64-scei-ps4 %s 2>&1 | FileCheck 
-check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory 
-### -E --sysroot=foo/ -target x86_64-scei-ps4 %s 2>&1 | FileCheck 
-check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory 
-### -emit-ast --sysroot=foo/ -target x86_64-scei-ps4 %s 2>&1 | FileCheck 
-check-prefix=NO-WARN %s
-
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory 
-### -c -isysroot foo -target x86_64-scei-ps4 %s 2>&1 | FileCheck 
-check-prefix=WARN-ISYSROOT -check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory 
-### -S -isysroot foo -target x86_64-scei-ps4 %s 2>&1 | FileCheck 
-check-prefix=WARN-ISYSROOT -check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory 
-### -E -isysroot foo -target x86_64-scei-ps4 %s 2>&1 | FileCheck 
-check-prefix=WARN-ISYSROOT -check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory 
-### -emit-ast -isysroot foo -target x86_64-scei-ps4 %s 2>&1 | FileCheck 
-check-prefix=WARN-ISYSROOT -check-prefix=NO-WARN %s
-// RUN: env SCE_ORBIS_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory 
-### --sysroot=foo/ -isysroot foo -target x86_64-scei-ps4 %s 2>&1 | FileCheck 
-check-prefix=WARN-ISYSROOT -check-prefix=NO-WARN %s
+/// PS4 clang emits warnings when SDK headers or libraries are missing, or if a
+/// specified `-isysroot` or `--sysroot` does not exist.
+///
+/// If the user takes control of header or library search, the respective
+/// existence check is skipped. User control of header search is assumed if
+/// `--sysroot`, `-isysroot`, `-nostdinc` or `-nostdlibinc` is supplied. User
+/// control of library search is assumed if `--sysroot` is supplied.

playstation-edd wrote:

Fixed - thanks.

https://github.com/llvm/llvm-project/pull/107410
___
cfe-commits mailing list
cfe-commits@lists.

[clang] [clang] Diagnose dangling issues for the "Container" case. (PR #107213)

2024-09-09 Thread Utkarsh Saxena via cfe-commits

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

LGTM. Thanks.

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


[clang] [clang] Diagnose dangling issues for the "Container" case. (PR #107213)

2024-09-09 Thread Utkarsh Saxena via cfe-commits

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


[clang] [clang] Diagnose dangling issues for the "Container" case. (PR #107213)

2024-09-09 Thread Utkarsh Saxena via cfe-commits


@@ -990,13 +1009,16 @@ static void checkExprLifetimeImpl(Sema &SemaRef,
 //   int &p = *localUniquePtr;
 //   someContainer.add(std::move(localUniquePtr));
 //   return p;
-IsLocalGslOwner = isRecordWithAttr(L->getType());
+IsLocalGslOwner =
+isRecordWithAttr(L->getType()) &&
+!isContainerOfPointer(L->getType()->getAsRecordDecl());

usx95 wrote:

This looks useful to be a extracted to a separate function, `IsGSLOwner`. This 
could be used to replace the  use below as well.

There are other instances `!isRecordWithAttr` which can be replaced 
as a no-op as well. It would make it more consistent and easy to follow.

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


[clang] [clang] Diagnose dangling issues for the "Container" case. (PR #107213)

2024-09-09 Thread Utkarsh Saxena via cfe-commits


@@ -292,7 +292,7 @@ Improvements to Clang's diagnostics
 
 - Clang now warns for u8 character literals used in C23 with 
``-Wpre-c23-compat`` instead of ``-Wpre-c++17-compat``.
 
-- Clang now diagnoses cases where a dangling `GSLOwner`` object is 
constructed, e.g. `std::vector v = {std::string}` (#GH100526).
+- Clang now diagnoses cases where a dangling ``GSLOwner`` object 
is constructed, e.g. `std::vector v = {std::string()};` 
(#GH100526).

usx95 wrote:

nit: put `std::vector v = {std::string()};` in double \`\`

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


[clang] [clang] Diagnose dangling issues for the "Container" case. (PR #107213)

2024-09-09 Thread Utkarsh Saxena via cfe-commits

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


[clang] [RISCV] Allow -mcmodel= to accept large for RV64 (PR #107817)

2024-09-09 Thread Sam Elliott via cfe-commits

lenary wrote:

What's the status of backend support for the large code model? That would 
presumably be a prerequisite to landing this.

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


[clang] [llvm] [SPIR-V] Add SPIR-V structurizer (PR #107408)

2024-09-09 Thread Nathan Gauër via cfe-commits


@@ -0,0 +1,1410 @@
+//===-- SPIRVStructurizer.cpp --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//===--===//
+
+#include "Analysis/SPIRVConvergenceRegionAnalysis.h"
+#include "SPIRV.h"
+#include "SPIRVSubtarget.h"
+#include "SPIRVTargetMachine.h"
+#include "SPIRVUtils.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/CodeGen/IntrinsicLowering.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicsSPIRV.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Transforms/Utils/LoopSimplify.h"
+#include "llvm/Transforms/Utils/LowerMemIntrinsics.h"
+#include 
+#include 
+
+using namespace llvm;
+using namespace SPIRV;
+
+namespace llvm {
+
+void initializeSPIRVStructurizerPass(PassRegistry &);
+
+namespace {
+
+using BlockSet = std::unordered_set;
+using Edge = std::pair;
+
+// This class implements a partial ordering visitor, which visits a cyclic 
graph
+// in natural topological-like ordering. Topological ordering is not defined 
for
+// directed graphs with cycles, so this assumes cycles are a single node, and
+// ignores back-edges. The cycle is visited from the entry in the same
+// topological-like ordering.
+//
+// This means once we visit a node, we know all the possible ancestors have 
been
+// visited.
+//
+// clang-format off
+//
+// Given this graph:
+//
+// ,-> B -\
+// A -++---> D > E -> F -> G -> H
+// `-> C -/  ^ |
+//   +-+
+//
+// Visit order is:
+//  A, [B, C in any order], D, E, F, G, H
+//
+// clang-format on
+//
+// Changing the function CFG between the construction of the visitor and
+// visiting is undefined. The visitor can be reused, but if the CFG is updated,
+// the visitor must be rebuilt.
+class PartialOrderingVisitor {
+  DomTreeBuilder::BBDomTree DT;
+  LoopInfo LI;
+  BlockSet Visited;
+  std::unordered_map B2R;
+  std::vector> Order;
+
+  // Get all basic-blocks reachable from Start.
+  BlockSet getReachableFrom(BasicBlock *Start) {
+std::queue ToVisit;
+ToVisit.push(Start);
+
+BlockSet Output;
+while (ToVisit.size() != 0) {
+  BasicBlock *BB = ToVisit.front();
+  ToVisit.pop();
+
+  if (Output.count(BB) != 0)
+continue;
+  Output.insert(BB);
+
+  for (BasicBlock *Successor : successors(BB)) {
+if (DT.dominates(Successor, BB))
+  continue;
+ToVisit.push(Successor);
+  }
+}
+
+return Output;
+  }
+
+  size_t visit(BasicBlock *BB, size_t Rank) {
+if (Visited.count(BB) != 0)
+  return Rank;
+
+Loop *L = LI.getLoopFor(BB);
+const bool isLoopHeader = LI.isLoopHeader(BB);
+
+if (B2R.count(BB) == 0) {
+  B2R.emplace(BB, Rank);
+} else {
+  B2R[BB] = std::max(B2R[BB], Rank);
+}
+
+for (BasicBlock *Predecessor : predecessors(BB)) {
+  if (isLoopHeader && L->contains(Predecessor)) {
+continue;
+  }
+
+  if (B2R.count(Predecessor) == 0) {
+return Rank;
+  }
+}
+
+Visited.insert(BB);
+
+SmallVector OtherSuccessors;
+BasicBlock *LoopSuccessor = nullptr;
+
+for (BasicBlock *Successor : successors(BB)) {
+  // Ignoring back-edges.
+  if (DT.dominates(Successor, BB))
+continue;
+
+  if (isLoopHeader && L->contains(Successor)) {
+assert(LoopSuccessor == nullptr);
+LoopSuccessor = Successor;
+  } else
+OtherSuccessors.push_back(Successor);
+}
+
+if (LoopSuccessor)
+  Rank = visit(LoopSuccessor, Rank + 1);
+
+size_t OutputRank = Rank;
+for (BasicBlock *Item : OtherSuccessors)
+  OutputRank = std::max(OutputRank, visit(Item, Rank + 1));
+return OutputRank;
+  };
+
+public:
+  // Build the visitor to operate on the function F.
+  PartialOrderingVisitor(Function &F) {
+DT.recalculate(F);
+LI = LoopInfo(DT);
+
+visit(&*F.begin(), 0);
+
+for (auto &[BB, Rank] : B2R)
+  Order.emplace_back(BB, Rank);
+
+std::sort(Order.begin(), Order.end(), [](const auto &LHS, const auto &RHS) 
{
+  return LHS.second < RHS.second;
+});
+
+for (size_t i = 0; i < Order.size(); i++)
+  B2R[Order[i].first] = i;
+  }
+
+  // Visit the function starting from the basic block |Start|, and calling |Op|
+  // on each visited BB. This traversal ignores back-edges, meaning this won't
+  // visit a node to which |Start| is not an ancestor.
+  void partialOrder

[clang] [llvm] [SPIR-V] Add SPIR-V structurizer (PR #107408)

2024-09-09 Thread Nathan Gauër via cfe-commits


@@ -0,0 +1,1410 @@
+//===-- SPIRVStructurizer.cpp --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//===--===//
+
+#include "Analysis/SPIRVConvergenceRegionAnalysis.h"
+#include "SPIRV.h"
+#include "SPIRVSubtarget.h"
+#include "SPIRVTargetMachine.h"
+#include "SPIRVUtils.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/CodeGen/IntrinsicLowering.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicsSPIRV.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Transforms/Utils/LoopSimplify.h"
+#include "llvm/Transforms/Utils/LowerMemIntrinsics.h"
+#include 
+#include 
+
+using namespace llvm;
+using namespace SPIRV;
+
+namespace llvm {
+
+void initializeSPIRVStructurizerPass(PassRegistry &);
+
+namespace {
+
+using BlockSet = std::unordered_set;
+using Edge = std::pair;
+
+// This class implements a partial ordering visitor, which visits a cyclic 
graph
+// in natural topological-like ordering. Topological ordering is not defined 
for
+// directed graphs with cycles, so this assumes cycles are a single node, and
+// ignores back-edges. The cycle is visited from the entry in the same
+// topological-like ordering.
+//
+// This means once we visit a node, we know all the possible ancestors have 
been
+// visited.
+//
+// clang-format off
+//
+// Given this graph:
+//
+// ,-> B -\
+// A -++---> D > E -> F -> G -> H
+// `-> C -/  ^ |
+//   +-+
+//
+// Visit order is:
+//  A, [B, C in any order], D, E, F, G, H
+//
+// clang-format on
+//
+// Changing the function CFG between the construction of the visitor and
+// visiting is undefined. The visitor can be reused, but if the CFG is updated,
+// the visitor must be rebuilt.
+class PartialOrderingVisitor {
+  DomTreeBuilder::BBDomTree DT;
+  LoopInfo LI;
+  BlockSet Visited;
+  std::unordered_map B2R;
+  std::vector> Order;
+
+  // Get all basic-blocks reachable from Start.
+  BlockSet getReachableFrom(BasicBlock *Start) {
+std::queue ToVisit;
+ToVisit.push(Start);
+
+BlockSet Output;
+while (ToVisit.size() != 0) {
+  BasicBlock *BB = ToVisit.front();
+  ToVisit.pop();
+
+  if (Output.count(BB) != 0)
+continue;
+  Output.insert(BB);
+
+  for (BasicBlock *Successor : successors(BB)) {
+if (DT.dominates(Successor, BB))
+  continue;
+ToVisit.push(Successor);
+  }
+}
+
+return Output;
+  }
+
+  size_t visit(BasicBlock *BB, size_t Rank) {
+if (Visited.count(BB) != 0)
+  return Rank;
+
+Loop *L = LI.getLoopFor(BB);
+const bool isLoopHeader = LI.isLoopHeader(BB);
+
+if (B2R.count(BB) == 0) {
+  B2R.emplace(BB, Rank);
+} else {
+  B2R[BB] = std::max(B2R[BB], Rank);
+}
+
+for (BasicBlock *Predecessor : predecessors(BB)) {
+  if (isLoopHeader && L->contains(Predecessor)) {
+continue;
+  }
+
+  if (B2R.count(Predecessor) == 0) {
+return Rank;
+  }
+}
+
+Visited.insert(BB);
+
+SmallVector OtherSuccessors;
+BasicBlock *LoopSuccessor = nullptr;
+
+for (BasicBlock *Successor : successors(BB)) {
+  // Ignoring back-edges.
+  if (DT.dominates(Successor, BB))
+continue;
+
+  if (isLoopHeader && L->contains(Successor)) {
+assert(LoopSuccessor == nullptr);
+LoopSuccessor = Successor;
+  } else
+OtherSuccessors.push_back(Successor);
+}
+
+if (LoopSuccessor)
+  Rank = visit(LoopSuccessor, Rank + 1);
+
+size_t OutputRank = Rank;
+for (BasicBlock *Item : OtherSuccessors)
+  OutputRank = std::max(OutputRank, visit(Item, Rank + 1));
+return OutputRank;
+  };
+
+public:
+  // Build the visitor to operate on the function F.
+  PartialOrderingVisitor(Function &F) {
+DT.recalculate(F);
+LI = LoopInfo(DT);
+
+visit(&*F.begin(), 0);
+
+for (auto &[BB, Rank] : B2R)
+  Order.emplace_back(BB, Rank);
+
+std::sort(Order.begin(), Order.end(), [](const auto &LHS, const auto &RHS) 
{
+  return LHS.second < RHS.second;
+});
+
+for (size_t i = 0; i < Order.size(); i++)
+  B2R[Order[i].first] = i;
+  }
+
+  // Visit the function starting from the basic block |Start|, and calling |Op|
+  // on each visited BB. This traversal ignores back-edges, meaning this won't
+  // visit a node to which |Start| is not an ancestor.
+  void partialOrder

[clang] Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by aggregate initialization using a default member initializer" (PR #97308)

2024-09-09 Thread via cfe-commits

yronglin wrote:

> This PR triggers failed asserts. This is reproducible with 
> https://martin.st/temp/qtdeclarative-repro1.cpp, like this:
> 
> ```
> $ clang -target aarch64-w64-mingw32 -c qtdeclarative-repro1.cpp
> Assertion failed: ((ND->isUsed(false) || !isa(ND) || 
> E->isNonOdrUse() || !E->getLocation().isValid()) && "Should not use decl 
> without marking it used!"), function EmitDeclRefLValue, file 
> /home/martin/code/llvm-project/clang/lib/CodeGen/CGExpr.cpp, line 3107.
> ```
> 
> (This file isn't the final reduced form, but creduce seems to be running 
> quite slowly on this file, so it's a partially reduced testcase.)

Oh, sorry for this. Could you please create an issue for this when creduce 
finish? If this blocking you, feel free to revert the PR. I'll take a look as 
soon as possible.

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


[clang] [NFC][clang] Fix clang version in the test for the implementation of cwg1815 (PR #107838)

2024-09-09 Thread via cfe-commits

https://github.com/yronglin created 
https://github.com/llvm/llvm-project/pull/107838

This PR fix the clang version in 
https://github.com/llvm/llvm-project/pull/97308 .

>From d99447b57b723efea16ad10015a6b83cc1fd51c5 Mon Sep 17 00:00:00 2001
From: yronglin 
Date: Mon, 9 Sep 2024 18:48:37 +0800
Subject: [PATCH] [NFC][clang] Fix clang version in the test for

Signed-off-by: yronglin 
---
 clang/test/CXX/drs/cwg18xx.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/CXX/drs/cwg18xx.cpp b/clang/test/CXX/drs/cwg18xx.cpp
index 43df5880a14d67..7f0fb8cf589d48 100644
--- a/clang/test/CXX/drs/cwg18xx.cpp
+++ b/clang/test/CXX/drs/cwg18xx.cpp
@@ -206,7 +206,7 @@ namespace cwg1814 { // cwg1814: yes
 #endif
 }
 
-namespace cwg1815 { // cwg1815: 19
+namespace cwg1815 { // cwg1815: 20
 #if __cplusplus >= 201402L
   struct A { int &&r = 0; };
   A a = {};

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


[clang] [NFC][clang] Fix clang version in the test for the implementation of cwg1815 (PR #107838)

2024-09-09 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: None (yronglin)


Changes

This PR fix the clang version in 
https://github.com/llvm/llvm-project/pull/97308 .

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


1 Files Affected:

- (modified) clang/test/CXX/drs/cwg18xx.cpp (+1-1) 


``diff
diff --git a/clang/test/CXX/drs/cwg18xx.cpp b/clang/test/CXX/drs/cwg18xx.cpp
index 43df5880a14d67..7f0fb8cf589d48 100644
--- a/clang/test/CXX/drs/cwg18xx.cpp
+++ b/clang/test/CXX/drs/cwg18xx.cpp
@@ -206,7 +206,7 @@ namespace cwg1814 { // cwg1814: yes
 #endif
 }
 
-namespace cwg1815 { // cwg1815: 19
+namespace cwg1815 { // cwg1815: 20
 #if __cplusplus >= 201402L
   struct A { int &&r = 0; };
   A a = {};

``




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


[clang] [llvm] [SPIR-V] Add SPIR-V structurizer (PR #107408)

2024-09-09 Thread Nathan Gauër via cfe-commits


@@ -0,0 +1,1410 @@
+//===-- SPIRVStructurizer.cpp --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//===--===//
+
+#include "Analysis/SPIRVConvergenceRegionAnalysis.h"
+#include "SPIRV.h"
+#include "SPIRVSubtarget.h"
+#include "SPIRVTargetMachine.h"
+#include "SPIRVUtils.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/CodeGen/IntrinsicLowering.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicsSPIRV.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Transforms/Utils/LoopSimplify.h"
+#include "llvm/Transforms/Utils/LowerMemIntrinsics.h"
+#include 
+#include 
+
+using namespace llvm;
+using namespace SPIRV;
+
+namespace llvm {
+
+void initializeSPIRVStructurizerPass(PassRegistry &);
+
+namespace {
+
+using BlockSet = std::unordered_set;
+using Edge = std::pair;
+
+// This class implements a partial ordering visitor, which visits a cyclic 
graph
+// in natural topological-like ordering. Topological ordering is not defined 
for
+// directed graphs with cycles, so this assumes cycles are a single node, and
+// ignores back-edges. The cycle is visited from the entry in the same
+// topological-like ordering.
+//
+// This means once we visit a node, we know all the possible ancestors have 
been
+// visited.
+//
+// clang-format off
+//
+// Given this graph:
+//
+// ,-> B -\
+// A -++---> D > E -> F -> G -> H
+// `-> C -/  ^ |
+//   +-+
+//
+// Visit order is:
+//  A, [B, C in any order], D, E, F, G, H
+//
+// clang-format on
+//
+// Changing the function CFG between the construction of the visitor and
+// visiting is undefined. The visitor can be reused, but if the CFG is updated,
+// the visitor must be rebuilt.
+class PartialOrderingVisitor {
+  DomTreeBuilder::BBDomTree DT;
+  LoopInfo LI;
+  BlockSet Visited;
+  std::unordered_map B2R;
+  std::vector> Order;
+
+  // Get all basic-blocks reachable from Start.
+  BlockSet getReachableFrom(BasicBlock *Start) {
+std::queue ToVisit;
+ToVisit.push(Start);
+
+BlockSet Output;
+while (ToVisit.size() != 0) {
+  BasicBlock *BB = ToVisit.front();
+  ToVisit.pop();
+
+  if (Output.count(BB) != 0)
+continue;
+  Output.insert(BB);
+
+  for (BasicBlock *Successor : successors(BB)) {
+if (DT.dominates(Successor, BB))
+  continue;
+ToVisit.push(Successor);
+  }
+}
+
+return Output;
+  }
+
+  size_t visit(BasicBlock *BB, size_t Rank) {
+if (Visited.count(BB) != 0)
+  return Rank;
+
+Loop *L = LI.getLoopFor(BB);
+const bool isLoopHeader = LI.isLoopHeader(BB);
+
+if (B2R.count(BB) == 0) {
+  B2R.emplace(BB, Rank);
+} else {
+  B2R[BB] = std::max(B2R[BB], Rank);
+}
+
+for (BasicBlock *Predecessor : predecessors(BB)) {
+  if (isLoopHeader && L->contains(Predecessor)) {
+continue;
+  }
+
+  if (B2R.count(Predecessor) == 0) {
+return Rank;
+  }
+}
+
+Visited.insert(BB);
+
+SmallVector OtherSuccessors;
+BasicBlock *LoopSuccessor = nullptr;
+
+for (BasicBlock *Successor : successors(BB)) {
+  // Ignoring back-edges.
+  if (DT.dominates(Successor, BB))
+continue;
+
+  if (isLoopHeader && L->contains(Successor)) {
+assert(LoopSuccessor == nullptr);
+LoopSuccessor = Successor;
+  } else
+OtherSuccessors.push_back(Successor);
+}
+
+if (LoopSuccessor)
+  Rank = visit(LoopSuccessor, Rank + 1);
+
+size_t OutputRank = Rank;
+for (BasicBlock *Item : OtherSuccessors)
+  OutputRank = std::max(OutputRank, visit(Item, Rank + 1));
+return OutputRank;
+  };
+
+public:
+  // Build the visitor to operate on the function F.
+  PartialOrderingVisitor(Function &F) {
+DT.recalculate(F);
+LI = LoopInfo(DT);
+
+visit(&*F.begin(), 0);
+
+for (auto &[BB, Rank] : B2R)
+  Order.emplace_back(BB, Rank);
+
+std::sort(Order.begin(), Order.end(), [](const auto &LHS, const auto &RHS) 
{
+  return LHS.second < RHS.second;
+});
+
+for (size_t i = 0; i < Order.size(); i++)
+  B2R[Order[i].first] = i;
+  }
+
+  // Visit the function starting from the basic block |Start|, and calling |Op|
+  // on each visited BB. This traversal ignores back-edges, meaning this won't
+  // visit a node to which |Start| is not an ancestor.
+  void partialOrder

[clang] 049512e - [NFC][clang] Fix clang version in the test for the implementation of cwg1815 (#107838)

2024-09-09 Thread via cfe-commits

Author: yronglin
Date: 2024-09-09T19:01:11+08:00
New Revision: 049512e39d96995cb373a76cf2d009a86eaf3aab

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

LOG: [NFC][clang] Fix clang version in the test for the implementation of 
cwg1815 (#107838)

This PR fix the clang version in
https://github.com/llvm/llvm-project/pull/97308 .

Signed-off-by: yronglin 

Added: 


Modified: 
clang/test/CXX/drs/cwg18xx.cpp

Removed: 




diff  --git a/clang/test/CXX/drs/cwg18xx.cpp b/clang/test/CXX/drs/cwg18xx.cpp
index 43df5880a14d67..7f0fb8cf589d48 100644
--- a/clang/test/CXX/drs/cwg18xx.cpp
+++ b/clang/test/CXX/drs/cwg18xx.cpp
@@ -206,7 +206,7 @@ namespace cwg1814 { // cwg1814: yes
 #endif
 }
 
-namespace cwg1815 { // cwg1815: 19
+namespace cwg1815 { // cwg1815: 20
 #if __cplusplus >= 201402L
   struct A { int &&r = 0; };
   A a = {};



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


[clang] [NFC][clang] Fix clang version in the test for the implementation of cwg1815 (PR #107838)

2024-09-09 Thread via cfe-commits

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


[clang] [clang][TableGen] Migrate clang-tblgen to use const RecordKeeper (PR #107533)

2024-09-09 Thread Rahul Joshi via cfe-commits

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


[clang] [llvm] [LLVM][Coroutines] Transform "coro_elide_safe" calls to switch ABI coroutines to the `noalloc` variant (PR #99285)

2024-09-09 Thread LLVM Continuous Integration via cfe-commits

llvm-ci wrote:

LLVM Buildbot has detected a new failure on builder 
`llvm-clang-x86_64-expensive-checks-win` running on `as-worker-93` while 
building `llvm` at step 7 "test-build-unified-tree-check-all".

Full details are available at: 
https://lab.llvm.org/buildbot/#/builders/14/builds/1362


Here is the relevant piece of the build log for the reference

```
Step 7 (test-build-unified-tree-check-all) failure: test (failure)
 TEST 'LLVM :: 
Transforms/Coroutines/coro-transform-must-elide.ll' FAILED 
Exit Code: 2

Command Output (stdout):
--
# RUN: at line 2
c:\a\llvm-clang-x86_64-expensive-checks-win\build\bin\opt.exe < 
C:\a\llvm-clang-x86_64-expensive-checks-win\llvm-project\llvm\test\Transforms\Coroutines\coro-transform-must-elide.ll
 -S -passes='cgscc(coro-annotation-elide)' | 
c:\a\llvm-clang-x86_64-expensive-checks-win\build\bin\filecheck.exe 
C:\a\llvm-clang-x86_64-expensive-checks-win\llvm-project\llvm\test\Transforms\Coroutines\coro-transform-must-elide.ll
# executed command: 
'c:\a\llvm-clang-x86_64-expensive-checks-win\build\bin\opt.exe' -S 
'-passes=cgscc(coro-annotation-elide)'
# .---command stderr
# | Assertion failed: (RC == &TargetRC || RC->isAncestorOf(TargetRC)) && "New 
call edge is not trivial!", file 
C:\a\llvm-clang-x86_64-expensive-checks-win\llvm-project\llvm\lib\Analysis\CGSCCPassManager.cpp,
 line 982
# | PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ 
and include the crash backtrace.
# | Stack dump:
# | 0.  Program arguments: 
c:\\a\\llvm-clang-x86_64-expensive-checks-win\\build\\bin\\opt.exe -S 
-passes=cgscc(coro-annotation-elide)
# | 1.  Running pass "cgscc(coro-annotation-elide)" on module ""
# | Exception Code: 0x8003
# |  #0 0x7ff71ff0a33c HandleAbort 
C:\a\llvm-clang-x86_64-expensive-checks-win\llvm-project\llvm\lib\Support\Windows\Signals.inc:429:0
# |  #1 0x7ffddb8590ed (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0xa90ed)
# |  #2 0x7ffddb85ae49 (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0xaae49)
# |  #3 0x7ffddb860c6f (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0xb0c6f)
# |  #4 0x7ffddb85eba1 (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0xaeba1)
# |  #5 0x7ffddb8618af (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0xb18af)
# |  #6 0x7ff71da5c2ae updateCGAndAnalysisManagerForPass 
C:\a\llvm-clang-x86_64-expensive-checks-win\llvm-project\llvm\lib\Analysis\CGSCCPassManager.cpp:981:0
# |  #7 0x7ff71da586db llvm::updateCGAndAnalysisManagerForCGSCCPass(class 
llvm::LazyCallGraph &, class llvm::LazyCallGraph::SCC &, class 
llvm::LazyCallGraph::Node &, class llvm::AnalysisManager &, struct 
llvm::CGSCCUpdateResult &, class llvm::AnalysisManager &) 
C:\a\llvm-clang-x86_64-expensive-checks-win\llvm-project\llvm\lib\Analysis\CGSCCPassManager.cpp:1191:0
# |  #8 0x7ff721cbc728 llvm::CoroAnnotationElidePass::run(class 
llvm::LazyCallGraph::SCC &, class llvm::AnalysisManager &, class 
llvm::LazyCallGraph &, struct llvm::CGSCCUpdateResult &) 
C:\a\llvm-clang-x86_64-expensive-checks-win\llvm-project\llvm\lib\Transforms\Coroutines\CoroAnnotationElide.cpp:149:0
# |  #9 0x7ff72033e264 llvm::detail::PassModel, class llvm::LazyCallGraph &, struct llvm::CGSCCUpdateResult &>::run(class 
llvm::LazyCallGraph::SCC &, class llvm::AnalysisManager &, class 
llvm::LazyCallGraph &, struct llvm::CGSCCUpdateResult &) 
C:\a\llvm-clang-x86_64-expensive-checks-win\llvm-project\llvm\include\llvm\IR\PassManagerInternal.h:90:0
# | #10 0x7ff71da56d12 llvm::PassManager, class llvm::LazyCallGraph &, struct 
llvm::CGSCCUpdateResult &>::run(class llvm::LazyCallGraph::SCC &, class 
llvm::AnalysisManager &, class llvm::LazyCallGraph &, struct llvm::CGSCCUpdateResult &) 
C:\a\llvm-clang-x86_64-expensive-checks-win\llvm-project\llvm\lib\Analysis\CGSCCPassManager.cpp:90:0
# | #11 0x7ff72033e3e4 llvm::detail::PassModel, class 
llvm::LazyCallGraph &, struct llvm::CGSCCUpdateResult &>, class 
llvm::AnalysisManager, class llvm::LazyCallGraph &, struct llvm::CGSCCUpdateResult &>::run(class 
llvm::LazyCallGraph::SCC &, class llvm::AnalysisManager &, class 
llvm::LazyCallGraph &, struct llvm::CGSCCUpdateResult &) 
C:\a\llvm-clang-x86_64-expensive-checks-win\llvm-project\llvm\include\llvm\IR\PassManagerInternal.h:90:0
# | #12 0x7ff71da57bf8 llvm::ModuleToPostOrderCGSCCPassAdaptor::run(class 
llvm::Module &, class llvm::AnalysisManager &) 
C:\a\llvm-clang-x86_64-expensive-checks-win\llvm-project\llvm\lib\Analysis\CGSCCPassManager.cpp:277:0
# | #13 0x7ff72033dc90 llvm::detail::PassModel>::run(class llvm::Module &, class llvm::AnalysisManager &) 
C:\a\llvm-clang-x86_64-expensive-checks-win\llvm-project\llvm\include\llvm\IR\PassManagerInternal.h:90:0
# | #14 0x7ff71eeaaf04 llvm::PassManager>::run(class llvm::Module &, class 
llvm::AnalysisManager &) 
C:\a\llvm-clang-x86_64-expensive-checks-win\llvm-project\llvm\include\llvm\IR\PassManagerImpl.h:85:0
# | #15 0x7ff719abe28b llvm::runPassPipeline(class llvm::StringRef, class 
llvm::M

[clang] d84d955 - [clang][analyzer] Fix #embed crash (#107764)

2024-09-09 Thread via cfe-commits

Author: Nicolas van Kempen
Date: 2024-09-09T13:12:46+02:00
New Revision: d84d9559bdc7aeb4ce14c251f6a3490c66db8d3a

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

LOG: [clang][analyzer] Fix #embed crash (#107764)

Fix #107724.

Added: 
clang/test/Analysis/embed.c

Modified: 
clang/lib/StaticAnalyzer/Core/ExprEngine.cpp

Removed: 




diff  --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 315d85319a85a9..fdabba46992b08 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1938,6 +1938,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
 case Stmt::CXXRewrittenBinaryOperatorClass:
 case Stmt::RequiresExprClass:
 case Expr::CXXParenListInitExprClass:
+case Stmt::EmbedExprClass:
   // Fall through.
 
 // Cases we intentionally don't evaluate, since they don't need
@@ -2440,10 +2441,6 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
   Bldr.addNodes(Dst);
   break;
 }
-
-case Stmt::EmbedExprClass:
-  llvm::report_fatal_error("Support for EmbedExpr is not implemented.");
-  break;
   }
 }
 

diff  --git a/clang/test/Analysis/embed.c b/clang/test/Analysis/embed.c
new file mode 100644
index 00..32f6c130325740
--- /dev/null
+++ b/clang/test/Analysis/embed.c
@@ -0,0 +1,12 @@
+// RUN: %clang_analyze_cc1 -std=c23 
-analyzer-checker=core,debug.ExprInspection -verify %s
+
+void clang_analyzer_dump_ptr(const unsigned char *ptr);
+void clang_analyzer_dump(unsigned char val);
+
+int main() {
+const unsigned char SelfBytes[] = {
+#embed "embed.c"
+};
+clang_analyzer_dump_ptr(SelfBytes); // expected-warning 
{{&Element{SelfBytes,0 S64b,unsigned char}}}
+clang_analyzer_dump(SelfBytes[0]); // expected-warning {{Unknown}} FIXME: 
This should be the `/` character.
+}



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


[clang] [clang][analyzer] Fix #embed crash (PR #107764)

2024-09-09 Thread Balazs Benics via cfe-commits

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


[clang] [llvm] [TableGen] Change SetTheory set/vec to use const Record * (PR #107692)

2024-09-09 Thread Rahul Joshi via cfe-commits

https://github.com/jurahul updated 
https://github.com/llvm/llvm-project/pull/107692

>From b11f8fbde5cc005e4667877ed60954f36abcec0c Mon Sep 17 00:00:00 2001
From: Rahul Joshi 
Date: Sat, 7 Sep 2024 04:33:09 -0700
Subject: [PATCH] [TableGen] Change SetTheory set/vec to use consr Record *

Change SetTheory::RecSet/RecVec to use const Record pointers.
---
 clang/utils/TableGen/NeonEmitter.cpp  |  2 +-
 llvm/include/llvm/TableGen/Record.h   |  4 +-
 llvm/include/llvm/TableGen/SetTheory.h|  4 +-
 llvm/lib/TableGen/Record.cpp  |  6 +--
 llvm/utils/TableGen/AsmMatcherEmitter.cpp | 38 ++-
 .../TableGen/Common/CodeGenRegisters.cpp  | 29 +++---
 llvm/utils/TableGen/Common/CodeGenRegisters.h | 16 
 .../utils/TableGen/Common/CodeGenSchedule.cpp | 27 ++---
 llvm/utils/TableGen/Common/CodeGenSchedule.h  | 10 +++--
 llvm/utils/TableGen/RegisterInfoEmitter.cpp   | 30 +++
 llvm/utils/TableGen/TableGen.cpp  |  2 +-
 11 files changed, 86 insertions(+), 82 deletions(-)

diff --git a/clang/utils/TableGen/NeonEmitter.cpp 
b/clang/utils/TableGen/NeonEmitter.cpp
index e0d7b0db7f5780..4707ce1ea3b792 100644
--- a/clang/utils/TableGen/NeonEmitter.cpp
+++ b/clang/utils/TableGen/NeonEmitter.cpp
@@ -1636,7 +1636,7 @@ std::pair 
Intrinsic::DagEmitter::emitDagShuffle(DagInit *DI){
   int64_t VectorSize = cast(Expr->getArg(0))->getValue();
   VectorSize /= ElementSize;
 
-  std::vector Revved;
+  std::vector Revved;
   for (unsigned VI = 0; VI < Elts2.size(); VI += VectorSize) {
 for (int LI = VectorSize - 1; LI >= 0; --LI) {
   Revved.push_back(Elts2[VI + LI]);
diff --git a/llvm/include/llvm/TableGen/Record.h 
b/llvm/include/llvm/TableGen/Record.h
index 98c8fd0ca051f9..dc86f28a453285 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -1669,7 +1669,7 @@ class Record {
   RecordKeeper &TrackedRecords;
 
   // The DefInit corresponding to this record.
-  DefInit *CorrespondingDefInit = nullptr;
+  mutable DefInit *CorrespondingDefInit = nullptr;
 
   // Unique record ID.
   unsigned ID;
@@ -1736,7 +1736,7 @@ class Record {
   RecordRecTy *getType() const;
 
   /// get the corresponding DefInit.
-  DefInit *getDefInit();
+  DefInit *getDefInit() const;
 
   bool isClass() const { return Kind == RK_Class; }
 
diff --git a/llvm/include/llvm/TableGen/SetTheory.h 
b/llvm/include/llvm/TableGen/SetTheory.h
index 954453b783d4d8..771dcff2f214c3 100644
--- a/llvm/include/llvm/TableGen/SetTheory.h
+++ b/llvm/include/llvm/TableGen/SetTheory.h
@@ -64,8 +64,8 @@ class Record;
 
 class SetTheory {
 public:
-  using RecVec = std::vector;
-  using RecSet = SmallSetVector;
+  using RecVec = std::vector;
+  using RecSet = SmallSetVector;
 
   /// Operator - A callback representing a DAG operator.
   class Operator {
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 85516b7b9f20aa..26f45d5bb8a3b7 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -2802,10 +2802,10 @@ RecordRecTy *Record::getType() const {
   return RecordRecTy::get(TrackedRecords, DirectSCs);
 }
 
-DefInit *Record::getDefInit() {
+DefInit *Record::getDefInit() const {
   if (!CorrespondingDefInit) {
-CorrespondingDefInit =
-new (TrackedRecords.getImpl().Allocator) DefInit(this);
+CorrespondingDefInit = new (TrackedRecords.getImpl().Allocator)
+DefInit(const_cast(this));
   }
   return CorrespondingDefInit;
 }
diff --git a/llvm/utils/TableGen/AsmMatcherEmitter.cpp 
b/llvm/utils/TableGen/AsmMatcherEmitter.cpp
index f351087ad212f7..574a3344a02f8d 100644
--- a/llvm/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/llvm/utils/TableGen/AsmMatcherEmitter.cpp
@@ -140,7 +140,7 @@ class AsmMatcherInfo;
 // RegisterSets can be seen in the outputted AsmMatcher tables occasionally, 
and
 // can even affect compiler output (at least seen in diagnostics produced when
 // all matches fail). So we use a type that sorts them consistently.
-typedef std::set RegisterSet;
+typedef std::set RegisterSet;
 
 class AsmMatcherEmitter {
   RecordKeeper &Records;
@@ -242,7 +242,7 @@ struct ClassInfo {
   if (!isRegisterClass() || !RHS.isRegisterClass())
 return false;
 
-  std::vector Tmp;
+  std::vector Tmp;
   std::set_intersection(Registers.begin(), Registers.end(),
 RHS.Registers.begin(), RHS.Registers.end(),
 std::back_inserter(Tmp), LessRecordByID());
@@ -403,7 +403,7 @@ struct MatchableInfo {
 bool IsIsolatedToken;
 
 /// Register record if this token is singleton register.
-Record *SingletonReg;
+const Record *SingletonReg;
 
 explicit AsmOperand(bool IsIsolatedToken, StringRef T)
 : Token(T), Class(nullptr), SubOpIdx(-1),
@@ -582,7 +582,7 @@ struct MatchableInfo {
   void formTwoOperandAlias(StringRef Constraint);
 
   void initialize(const As

[clang] [clang][analyzer] Fix #embed crash (PR #107764)

2024-09-09 Thread Balazs Benics via cfe-commits

steakhal wrote:

> PS: Should this be cherry-picked into 19?

Requested the backport in https://github.com/llvm/llvm-project/pull/107841

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


[clang] [clang-tools-extra] [clangd] Collect comments from function definitions into the index (PR #67802)

2024-09-09 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler updated 
https://github.com/llvm/llvm-project/pull/67802

>From 80e15f748b30d4e977b58a42d8fd4403234bb954 Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Fri, 29 Sep 2023 15:01:58 +0200
Subject: [PATCH] [clangd] Collect comments from function definitions into the
 index

This is useful with projects that put their (doxygen) comments at the
implementation site, rather than the header.
---
 clang-tools-extra/clangd/index/Symbol.h   |  4 +-
 .../clangd/index/SymbolCollector.cpp  | 42 +++
 .../clangd/index/SymbolCollector.h|  3 +-
 .../clangd/unittests/SymbolCollectorTests.cpp | 20 +
 clang/lib/AST/ASTContext.cpp  | 11 -
 5 files changed, 69 insertions(+), 11 deletions(-)

diff --git a/clang-tools-extra/clangd/index/Symbol.h 
b/clang-tools-extra/clangd/index/Symbol.h
index 1aa5265299231b..62c47ddfc5758d 100644
--- a/clang-tools-extra/clangd/index/Symbol.h
+++ b/clang-tools-extra/clangd/index/Symbol.h
@@ -145,9 +145,11 @@ struct Symbol {
 ImplementationDetail = 1 << 2,
 /// Symbol is visible to other files (not e.g. a static helper function).
 VisibleOutsideFile = 1 << 3,
+/// Symbol has an attached documentation comment.
+HasDocComment = 1 << 4
   };
-
   SymbolFlag Flags = SymbolFlag::None;
+
   /// FIXME: also add deprecation message and fixit?
 };
 
diff --git a/clang-tools-extra/clangd/index/SymbolCollector.cpp 
b/clang-tools-extra/clangd/index/SymbolCollector.cpp
index 5c4e2150cf3123..d3df6a26fd9365 100644
--- a/clang-tools-extra/clangd/index/SymbolCollector.cpp
+++ b/clang-tools-extra/clangd/index/SymbolCollector.cpp
@@ -635,17 +635,20 @@ bool SymbolCollector::handleDeclOccurrence(
 return true;
 
   const Symbol *BasicSymbol = Symbols.find(ID);
-  if (isPreferredDeclaration(*OriginalDecl, Roles))
+  bool SkipDocCheckInDef = false;
+  if (isPreferredDeclaration(*OriginalDecl, Roles)) {
 // If OriginalDecl is preferred, replace/create the existing canonical
 // declaration (e.g. a class forward declaration). There should be at most
 // one duplicate as we expect to see only one preferred declaration per
 // TU, because in practice they are definitions.
 BasicSymbol = addDeclaration(*OriginalDecl, std::move(ID), IsMainFileOnly);
-  else if (!BasicSymbol || DeclIsCanonical)
+SkipDocCheckInDef = true;
+  } else if (!BasicSymbol || DeclIsCanonical) {
 BasicSymbol = addDeclaration(*ND, std::move(ID), IsMainFileOnly);
+  }
 
   if (Roles & static_cast(index::SymbolRole::Definition))
-addDefinition(*OriginalDecl, *BasicSymbol);
+addDefinition(*OriginalDecl, *BasicSymbol, SkipDocCheckInDef);
 
   return true;
 }
@@ -1025,15 +1028,17 @@ const Symbol *SymbolCollector::addDeclaration(const 
NamedDecl &ND, SymbolID ID,
   *ASTCtx, *PP, CodeCompletionContext::CCC_Symbol, *CompletionAllocator,
   *CompletionTUInfo,
   /*IncludeBriefComments*/ false);
-  std::string Documentation =
-  formatDocumentation(*CCS, getDocComment(Ctx, SymbolCompletion,
-  /*CommentsFromHeaders=*/true));
+  std::string DocComment = getDocComment(Ctx, SymbolCompletion,
+ /*CommentsFromHeaders=*/true);
+  std::string Documentation = formatDocumentation(*CCS, DocComment);
   if (!(S.Flags & Symbol::IndexedForCodeCompletion)) {
 if (Opts.StoreAllDocumentation)
   S.Documentation = Documentation;
 Symbols.insert(S);
 return Symbols.find(S.ID);
   }
+  if (!DocComment.empty())
+S.Flags |= Symbol::HasDocComment;
   S.Documentation = Documentation;
   std::string Signature;
   std::string SnippetSuffix;
@@ -1058,8 +1063,8 @@ const Symbol *SymbolCollector::addDeclaration(const 
NamedDecl &ND, SymbolID ID,
   return Symbols.find(S.ID);
 }
 
-void SymbolCollector::addDefinition(const NamedDecl &ND,
-const Symbol &DeclSym) {
+void SymbolCollector::addDefinition(const NamedDecl &ND, const Symbol &DeclSym,
+bool SkipDocCheck) {
   if (DeclSym.Definition)
 return;
   const auto &SM = ND.getASTContext().getSourceManager();
@@ -1074,6 +1079,27 @@ void SymbolCollector::addDefinition(const NamedDecl &ND,
   Symbol S = DeclSym;
   // FIXME: use the result to filter out symbols.
   S.Definition = *DefLoc;
+
+  std::string DocComment;
+  std::string Documentation;
+  if (!SkipDocCheck && !(S.Flags & Symbol::HasDocComment) &&
+  (llvm::isa(ND) || llvm::isa(ND))) {
+CodeCompletionResult SymbolCompletion(&getTemplateOrThis(ND), 0);
+const auto *CCS = SymbolCompletion.CreateCodeCompletionString(
+*ASTCtx, *PP, CodeCompletionContext::CCC_Symbol, *CompletionAllocator,
+*CompletionTUInfo,
+/*IncludeBriefComments*/ false);
+DocComment = getDocComment(ND.getASTContext(), SymbolCompletion,
+   /*CommentsFromHeaders=*/true);
+if (!S.Documentation.emp

[clang] [clang][analyzer] Fix #embed crash (PR #107764)

2024-09-09 Thread LLVM Continuous Integration via cfe-commits

llvm-ci wrote:

LLVM Buildbot has detected a new failure on builder 
`openmp-offload-libc-amdgpu-runtime` running on `omp-vega20-1` while building 
`clang` at step 10 "Add check check-offload".

Full details are available at: 
https://lab.llvm.org/buildbot/#/builders/73/builds/5193


Here is the relevant piece of the build log for the reference

```
Step 10 (Add check check-offload) failure: test (failure)
 TEST 'libomptarget :: amdgcn-amd-amdhsa :: 
sanitizer/ptr_outside_alloc_2.c' FAILED 
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 2
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./bin/clang 
-fopenmp-I 
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.src/offload/test 
-I 
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src
 -L 
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload
 -L /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./lib -L 
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src
  -nogpulib 
-Wl,-rpath,/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload
 
-Wl,-rpath,/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src
 
-Wl,-rpath,/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./lib
  -fopenmp-targets=amdgcn-amd-amdhsa -O3 
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.src/offload/test/sanitizer/ptr_outside_alloc_2.c
 -o 
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/sanitizer/Output/ptr_outside_alloc_2.c.tmp
 
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./lib/libomptarget.devicertl.a
# executed command: 
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./bin/clang 
-fopenmp -I 
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.src/offload/test 
-I 
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src
 -L 
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload
 -L /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./lib -L 
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src
 -nogpulib 
-Wl,-rpath,/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload
 
-Wl,-rpath,/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src
 
-Wl,-rpath,/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./lib
 -fopenmp-targets=amdgcn-amd-amdhsa -O3 
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.src/offload/test/sanitizer/ptr_outside_alloc_2.c
 -o 
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/sanitizer/Output/ptr_outside_alloc_2.c.tmp
 
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./lib/libomptarget.devicertl.a
# RUN: at line 3
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./bin/not 
--crash env -u LLVM_DISABLE_SYMBOLIZATION OFFLOAD_TRACK_ALLOCATION_TRACES=1 
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/sanitizer/Output/ptr_outside_alloc_2.c.tmp
 2>&1 | 
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./bin/FileCheck
 
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.src/offload/test/sanitizer/ptr_outside_alloc_2.c
 --check-prefixes=CHECK
# executed command: 
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./bin/not 
--crash env -u LLVM_DISABLE_SYMBOLIZATION OFFLOAD_TRACK_ALLOCATION_TRACES=1 
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/sanitizer/Output/ptr_outside_alloc_2.c.tmp
# executed command: 
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./bin/FileCheck
 
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.src/offload/test/sanitizer/ptr_outside_alloc_2.c
 --check-prefixes=CHECK
# .---command stderr
# | 
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.src/offload/test/sanitizer/ptr_outside_alloc_2.c:21:11:
 error: CHECK: expected string not found in input
# | // CHECK: OFFLOAD ERROR: Memory access fault by GPU {{.*}} (agent 0x{{.*}}) 
at virtual address [[PTR:0x[0-9a-z]*]]. Reasons: {{.*}}
# |   ^
# | :1:1: note: scanning from here
# | AMDGPU error: Error in hsa_amd_memory_pool_allocate: 
HSA_STATUS_ERROR_OUT_OF_RESOURCES: The runtime failed to allocate the necessary 
resources. This error may also occur when the c

[clang] [clang-tools-extra] [clangd] Collect comments from function definitions into the index (PR #67802)

2024-09-09 Thread Christian Kandeler via cfe-commits

ckandeler wrote:

> At this point, my main feedback is that it would be good to include some unit 
> tests. `SymbolCollectorTests.cpp` is a good 
> place for them.

I've added a new test and verified that it fails without this patch.

> What is the purpose of the change to `ASTContext.cpp`? 

There was some assumption about the order of redeclarations that did not match 
reality, like that the definition always comes first or something along those 
lines. I do not know whether the assumption there was wrong or whether some 
other code messed up by breaking it. 

> This codepath has consumers other than clangd, so if we're changing the 
> behaviour, we need to evaluate whether it's 
> appropriate for other consumers (and maybe add libAST unit tests as well).

Hence my original comment. Though it should be noted that no existing tests 
appear to have been broken.

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


[clang] [clang-tools-extra] [clangd] Collect comments from function definitions into the index (PR #67802)

2024-09-09 Thread Christian Kandeler via cfe-commits


@@ -1069,6 +1071,27 @@ void SymbolCollector::addDefinition(const NamedDecl &ND,
   Symbol S = DeclSym;
   // FIXME: use the result to filter out symbols.
   S.Definition = *DefLoc;
+
+  std::string DocComment;
+  std::string Documentation;
+  if (!(S.Flags & Symbol::HasDocComment) &&

ckandeler wrote:

Done.

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


[clang-tools-extra] [clang-tidy] remove type annotations that require python3.9 in add_new_check.py (PR #107850)

2024-09-09 Thread Julian Schmidt via cfe-commits

https://github.com/5chmidti created 
https://github.com/llvm/llvm-project/pull/107850

Subscripting `Tuple`: `Tuple[str, str]` is not supported until python 3.9.
Tested with python 3.8.19, 3.9.19 and 3.12.4.

Fixes #107846


>From 36fff2ffdb29d8510c31464f6f6aad97721607c9 Mon Sep 17 00:00:00 2001
From: Julian Schmidt 
Date: Mon, 9 Sep 2024 14:03:12 +0200
Subject: [PATCH] [clang-tidy] remove type annotations that require python3.9
 in add_new_check.py

Subscripting `Tuple`: `Tuple[str, str]` is not supported until python 3.9.
Tested with python 3.8.19, 3.9.19 and 3.12.4.

Fixes #107846
---
 clang-tools-extra/clang-tidy/add_new_check.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/add_new_check.py 
b/clang-tools-extra/clang-tidy/add_new_check.py
index d384dbae28abbc..7230b3b17b2b79 100755
--- a/clang-tools-extra/clang-tidy/add_new_check.py
+++ b/clang-tools-extra/clang-tidy/add_new_check.py
@@ -511,7 +511,7 @@ def has_auto_fix(check_name: str) -> str:
 
 return ""
 
-def process_doc(doc_file: Tuple[str, str]) -> Tuple[str, 
Optional[re.Match[str]]]:
+def process_doc(doc_file):
 check_name = doc_file[0] + "-" + doc_file[1].replace(".rst", "")
 
 with io.open(os.path.join(docs_dir, *doc_file), "r", encoding="utf8") 
as doc:
@@ -526,7 +526,7 @@ def process_doc(doc_file: Tuple[str, str]) -> Tuple[str, 
Optional[re.Match[str]]
 # Is it a redirect?
 return check_name, match
 
-def format_link(doc_file: Tuple[str, str]) -> str:
+def format_link(doc_file) -> str:
 check_name, match = process_doc(doc_file)
 if not match and check_name and not 
check_name.startswith("clang-analyzer-"):
 return "   :doc:`%(check_name)s 
<%(module)s/%(check)s>`,%(autofix)s\n" % {
@@ -538,7 +538,7 @@ def format_link(doc_file: Tuple[str, str]) -> str:
 else:
 return ""
 
-def format_link_alias(doc_file: Tuple[str, str]) -> str:
+def format_link_alias(doc_file) -> str:
 check_name, match = process_doc(doc_file)
 if (match or (check_name.startswith("clang-analyzer-"))) and 
check_name:
 module = doc_file[0]

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


[clang-tools-extra] [clang-tidy] remove type annotations that require python3.9 in add_new_check.py (PR #107850)

2024-09-09 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-tidy

Author: Julian Schmidt (5chmidti)


Changes

Subscripting `Tuple`: `Tuple[str, str]` is not supported until python 3.9.
Tested with python 3.8.19, 3.9.19 and 3.12.4.

Fixes #107846


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


1 Files Affected:

- (modified) clang-tools-extra/clang-tidy/add_new_check.py (+3-3) 


``diff
diff --git a/clang-tools-extra/clang-tidy/add_new_check.py 
b/clang-tools-extra/clang-tidy/add_new_check.py
index d384dbae28abbc..7230b3b17b2b79 100755
--- a/clang-tools-extra/clang-tidy/add_new_check.py
+++ b/clang-tools-extra/clang-tidy/add_new_check.py
@@ -511,7 +511,7 @@ def has_auto_fix(check_name: str) -> str:
 
 return ""
 
-def process_doc(doc_file: Tuple[str, str]) -> Tuple[str, 
Optional[re.Match[str]]]:
+def process_doc(doc_file):
 check_name = doc_file[0] + "-" + doc_file[1].replace(".rst", "")
 
 with io.open(os.path.join(docs_dir, *doc_file), "r", encoding="utf8") 
as doc:
@@ -526,7 +526,7 @@ def process_doc(doc_file: Tuple[str, str]) -> Tuple[str, 
Optional[re.Match[str]]
 # Is it a redirect?
 return check_name, match
 
-def format_link(doc_file: Tuple[str, str]) -> str:
+def format_link(doc_file) -> str:
 check_name, match = process_doc(doc_file)
 if not match and check_name and not 
check_name.startswith("clang-analyzer-"):
 return "   :doc:`%(check_name)s 
<%(module)s/%(check)s>`,%(autofix)s\n" % {
@@ -538,7 +538,7 @@ def format_link(doc_file: Tuple[str, str]) -> str:
 else:
 return ""
 
-def format_link_alias(doc_file: Tuple[str, str]) -> str:
+def format_link_alias(doc_file) -> str:
 check_name, match = process_doc(doc_file)
 if (match or (check_name.startswith("clang-analyzer-"))) and 
check_name:
 module = doc_file[0]

``




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


[clang] cca54e3 - Revert "Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by aggregate initialization using a default member initializer" (#97308)"

2024-09-09 Thread Martin Storsjö via cfe-commits

Author: Martin Storsjö
Date: 2024-09-09T15:09:45+03:00
New Revision: cca54e347ac34912cdfb9983533c61836db135e0

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

LOG: Revert "Reapply "[Clang][CWG1815] Support lifetime extension of temporary 
created by aggregate initialization using a default member initializer" 
(#97308)"

This reverts commit 45c8766973bb3bb73dd8d996231e114dcf45df9f
and 049512e39d96995cb373a76cf2d009a86eaf3aab.

This change triggers failed asserts on inputs like this:

struct a {
} constexpr b;
class c {
public:
  c(a);
};
class B {
public:
  using d = int;
  struct e {
enum { f } g;
int h;
c i;
d j{};
  };
};
B::e k{B::e::f, int(), b};

Compiled like this:

clang -target x86_64-linux-gnu -c repro.cpp
clang: ../../clang/lib/CodeGen/CGExpr.cpp:3105: clang::CodeGen::LValue
clang::CodeGen::CodeGenFunction::EmitDeclRefLValue(const 
clang::DeclRefExpr*):
Assertion `(ND->isUsed(false) || !isa(ND) || E->isNonOdrUse() ||
!E->getLocation().isValid()) && "Should not use decl without marking it 
used!"' failed.

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Sema/Sema.h
clang/lib/Parse/ParseDecl.cpp
clang/lib/Sema/CheckExprLifetime.cpp
clang/lib/Sema/SemaExpr.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/SemaInit.cpp
clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
clang/lib/Sema/TreeTransform.h
clang/test/AST/ast-dump-default-init-json.cpp
clang/test/AST/ast-dump-default-init.cpp
clang/test/Analysis/lifetime-extended-regions.cpp
clang/test/CXX/drs/cwg16xx.cpp
clang/test/CXX/drs/cwg18xx.cpp
clang/test/CXX/special/class.temporary/p6.cpp
clang/test/SemaCXX/constexpr-default-arg.cpp
clang/test/SemaCXX/cxx11-default-member-initializers.cpp
clang/test/SemaCXX/eval-crashes.cpp
clang/www/cxx_dr_status.html

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 07f3544e2324e3..250821a9f9c45c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -108,9 +108,6 @@ C++ Language Changes
 - Allow single element access of GCC vector/ext_vector_type object to be
   constant expression. Supports the `V.xyzw` syntax and other tidbits
   as seen in OpenCL. Selecting multiple elements is left as a future work.
-- Implement `CWG1815 `_. Support lifetime extension 
-  of temporary created by aggregate initialization using a default member
-  initializer.
 
 - Accept C++26 user-defined ``static_assert`` messages in C++11 as an 
extension.
 

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4609d2ec2b7209..58819a64813fce 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10159,6 +10159,13 @@ def warn_dangling_pointer_assignment : Warning<
"will be destroyed at the end of the full-expression">,
InGroup;
 
+def warn_unsupported_lifetime_extension : Warning<
+  "lifetime extension of "
+  "%select{temporary|backing array of initializer list}0 created "
+  "by aggregate initialization using a default member initializer "
+  "is not yet supported; lifetime of %select{temporary|backing array}0 "
+  "will end at the end of the full-expression">, InGroup;
+
 // For non-floating point, expressions of the form x == x or x != x
 // should result in a warning, since these always evaluate to a constant.
 // Array comparisons have similar warnings

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index ac4c11964b126f..68c782a15c6f1b 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -6403,9 +6403,6 @@ class Sema final : public SemaBase {
 /// example, in a for-range initializer).
 bool InLifetimeExtendingContext = false;
 
-/// Whether we should rebuild CXXDefaultArgExpr and CXXDefaultInitExpr.
-bool RebuildDefaultArgOrDefaultInit = false;
-
 // When evaluating immediate functions in the initializer of a default
 // argument or default member initializer, this is the declaration whose
 // default initializer is being evaluated and the location of the call
@@ -7813,11 +7810,9 @@ class Sema final : public SemaBase {
   }
 
   bool isInLifetimeExtendingContext() const {
-return currentEvaluationContext().InLifetimeExtendingContext;
-  }
-
-  bool needRebuildDefaultArgOrInit() const {
-return currentEvaluationContext().RebuildDefaultArgOrDefaultInit;
+assert(!ExprEvalContexts.empty() &&
+   "Must be in an expression eva

[clang] Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by aggregate initialization using a default member initializer" (PR #97308)

2024-09-09 Thread Martin Storsjö via cfe-commits

mstorsjo wrote:

I pushed a revert now.

My reduction did complete in the end - it's reproducible with a small snippet 
like this:
```c++
struct a {
} constexpr b;
class c {
public:
  c(a);
};
class B {
public:
  using d = int;
  struct e {
enum { f } g;
int h;
c i;
d j{};
  };
};
B::e k{B::e::f, int(), b};
```
Compiled like this:
```
$ clang -target x86_64-linux-gnu -c repro.cpp
```

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


[clang] [llvm] [SPIRV][RFC] Rework / extend support for memory scopes (PR #106429)

2024-09-09 Thread Alex Voicu via cfe-commits


@@ -766,8 +766,17 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr 
*Expr, Address Dest,
   // LLVM atomic instructions always have synch scope. If clang atomic
   // expression has no scope operand, use default LLVM synch scope.
   if (!ScopeModel) {
+llvm::SyncScope::ID SS = CGF.getLLVMContext().getOrInsertSyncScopeID("");
+if (CGF.getLangOpts().OpenCL)
+  // OpenCL approach is: "The functions that do not have memory_scope

AlexVlx wrote:

This is the primary entry point for Atomic emission, so things like the Clang 
builtins (which do not carry scopes) would end up here.

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


[clang] [RISCV] Allow -mcmodel= to accept large for RV64 (PR #107817)

2024-09-09 Thread Pengcheng Wang via cfe-commits

wangpc-pp wrote:

> What's the status of backend support for the large code model? That would 
> presumably be a prerequisite to landing this.

It was just merged: https://github.com/llvm/llvm-project/pull/70308.

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


[clang] [Clang] prevent recovery call expression from proceeding with explicit attributes and undeclared templates (PR #107786)

2024-09-09 Thread Oleksandr T. via cfe-commits

https://github.com/a-tarasyuk updated 
https://github.com/llvm/llvm-project/pull/107786

>From b50e49be3765c31b1c555384c41e1f528d529a88 Mon Sep 17 00:00:00 2001
From: Oleksandr T 
Date: Mon, 9 Sep 2024 02:30:35 +0300
Subject: [PATCH] [Clang] prevent recovery call expression from proceeding with
 explicit attributes and undeclared templates

---
 clang/docs/ReleaseNotes.rst   |  3 +-
 clang/lib/Sema/SemaTemplate.cpp   |  6 
 .../SemaTemplate/recovery-crash-cxx20.cpp | 32 +++
 3 files changed, 40 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/SemaTemplate/recovery-crash-cxx20.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f7c3194c91fa31..f96045c57e7a0d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -376,8 +376,9 @@ Bug Fixes to C++ Support
 - Fixed a bug in the substitution of empty pack indexing types. (#GH105903)
 - Clang no longer tries to capture non-odr used default arguments of template 
parameters of generic lambdas (#GH107048)
 - Fixed a bug where defaulted comparison operators would remove ``const`` from 
base classes. (#GH102588)
-
 - Fix a crash when using ``source_location`` in the trailing return type of a 
lambda expression. (#GH67134)
+- Fixed an assertion failure when invoking recovery call expressions with 
explicit attributes
+  and undeclared templates. (#GH107047, #GH49093)
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 513f83146fb59e..1ec6219bbd6ea8 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -4458,6 +4458,12 @@ ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec 
&SS,
   R.getAsSingle(), TemplateArgs);
   }
 
+  if (TemplateArgs && R.getAsSingle()) {
+if (R.getAsSingle()->getTemplateSpecializationKind() ==
+TemplateSpecializationKind::TSK_Undeclared)
+  return ExprError();
+  }
+
   // We don't want lookup warnings at this point.
   R.suppressDiagnostics();
 
diff --git a/clang/test/SemaTemplate/recovery-crash-cxx20.cpp 
b/clang/test/SemaTemplate/recovery-crash-cxx20.cpp
new file mode 100644
index 00..dd92ddcd36ab02
--- /dev/null
+++ b/clang/test/SemaTemplate/recovery-crash-cxx20.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+
+namespace GH49093 {
+  class B {
+  public:
+static int a() { return 0; } // expected-note {{member is declared here}}
+decltype(a< 0 >(0)) test;// expected-error {{member 'a' used before 
its declaration}}
+  };
+
+  struct C {
+  static int a() { return 0; } // expected-note {{member is declared here}}
+  decltype(a < 0 > (0)) test;  // expected-error {{member 'a' used before 
its declaration}}
+  };
+
+  void test_is_bool(bool t) {}
+  void test_is_bool(int t) {}
+
+  int main() {
+B b;
+test_is_bool(b.test);
+
+C c;
+test_is_bool(c.test);
+  }
+}
+
+namespace GH107047 {
+  struct A {
+static constexpr auto test() { return 1; } // expected-note {{member is 
declared here}}
+static constexpr int s = test< 1 >();  // expected-error {{member 
'test' used before its declaration}}
+  };
+}

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


  1   2   3   4   5   >