[clang] [Sema] Fix c23 not checking CheckBoolLikeConversion (PR #79588)

2024-01-28 Thread Pil Eghoff via cfe-commits

https://github.com/pileghoff updated 
https://github.com/llvm/llvm-project/pull/79588

>From f22d0a6888be86c5105a00e3f83201f71165f78f Mon Sep 17 00:00:00 2001
From: Pil Eghoff 
Date: Fri, 26 Jan 2024 13:30:17 +0100
Subject: [PATCH] [Sema] Fix c23 not checking CheckBoolLikeConversion

---
 clang/docs/ReleaseNotes.rst|  2 ++
 clang/lib/Sema/SemaChecking.cpp|  2 +-
 clang/test/C/C2x/n3042.c   | 36 --
 clang/test/Sema/warn-int-in-bool-context.c |  7 +
 4 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index db3d74e124e7d1..b184eb378cd02a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -104,6 +104,8 @@ Improvements to Clang's time-trace
 Bug Fixes in This Version
 -
 
+- Fixed missing warnings when doing bool-like conversions in C23 (`#79435 
`_).
+
 Bug Fixes to Compiler Builtins
 ^^
 
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 4d280f25cc04c2..8e3bd1cd46076d 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -16166,7 +16166,7 @@ static void CheckConditionalOperator(Sema &S, 
AbstractConditionalOperator *E,
 /// Check conversion of given expression to boolean.
 /// Input argument E is a logical expression.
 static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC) {
-  if (S.getLangOpts().Bool)
+  if (S.getLangOpts().Bool && !S.getLangOpts().C23)
 return;
   if (E->IgnoreParenImpCasts()->getType()->isAtomicType())
 return;
diff --git a/clang/test/C/C2x/n3042.c b/clang/test/C/C2x/n3042.c
index 3f869013af4807..99661b1fb39eba 100644
--- a/clang/test/C/C2x/n3042.c
+++ b/clang/test/C/C2x/n3042.c
@@ -65,13 +65,15 @@ void test() {
   void *other_ptr = null_val;
 
   // Can it be used in all the places a scalar can be used?
-  if (null_val) {}
-  if (!null_val) {}
-  for (;null_val;) {}
-  while (nullptr) {}
-  null_val && nullptr;
-  nullptr || null_val;
-  null_val ? 0 : 1;
+  if (null_val) {} // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  if (!null_val) {}// expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  for (;null_val;) {}  // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  while (nullptr) {}   // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  null_val && nullptr; // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}} \
+  expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  nullptr || null_val; // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}} \
+  expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  null_val ? 0 : 1;// expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
   sizeof(null_val);
   alignas(nullptr_t) int aligned;
 
@@ -95,12 +97,12 @@ void test() {
   // Can it be converted to bool with the result false (this relies on Clang
   // accepting additional kinds of constant expressions where an ICE is
   // required)?
-  static_assert(!nullptr);
-  static_assert(!null_val);
-  static_assert(nullptr);  // expected-error {{static assertion failed due to 
requirement 'nullptr'}} \
-  expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
-  static_assert(null_val); // expected-error {{static assertion failed due to 
requirement 'null_val'}} \
-  expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(!nullptr);  // expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(!null_val); // expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(nullptr);   // expected-error {{static assertion failed due to 
requirement 'nullptr'}} \
+   expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(null_val);  // expected-error {{static assertion failed due to 
requirement 'null_val'}} \
+   expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
 
   // Do equality operators work as expected with it?
   static_assert(nullptr == nullptr);
@@ -142,11 +144,11 @@ void test() {
   _Generic(1 ? typed_ptr : nullptr, typeof(typed_ptr) : 0);
 
   // Same for GNU conditional operators?
-  _Generic(nullptr ?: nullptr, nullptr_t : 0);
-  _Generic(null_val ?: null_val, nullptr_t : 0);
+  _Generic(nullptr ?: nullptr, nullptr_t : 0);// expected-warning 
{{implicit conversion of nullptr constant to 'bool'}}
+  _Generic(null_val ?: null_val, nullptr_t : 0);  // expected-warning 
{{implicit conversion

[clang] [Sema] Fix c23 not checking CheckBoolLikeConversion (PR #79588)

2024-01-28 Thread Pil Eghoff via cfe-commits

https://github.com/pileghoff updated 
https://github.com/llvm/llvm-project/pull/79588

>From b059e03eb5330054e76c833699611fdc9bfb1967 Mon Sep 17 00:00:00 2001
From: Pil Eghoff 
Date: Fri, 26 Jan 2024 13:30:17 +0100
Subject: [PATCH] [Sema] Fix c23 not checking CheckBoolLikeConversion

---
 clang/docs/ReleaseNotes.rst|  2 ++
 clang/lib/Sema/SemaChecking.cpp|  2 +-
 clang/test/C/C2x/n3042.c   | 36 --
 clang/test/Sema/warn-int-in-bool-context.c |  7 +
 4 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index db3d74e124e7d1d..55b76a273906b45 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -104,6 +104,8 @@ Improvements to Clang's time-trace
 Bug Fixes in This Version
 -
 
+- Fixed missing warnings when doing bool-like conversions in C23 (`#79435: 
`_).
+
 Bug Fixes to Compiler Builtins
 ^^
 
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 4d280f25cc04c25..8e3bd1cd46076d6 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -16166,7 +16166,7 @@ static void CheckConditionalOperator(Sema &S, 
AbstractConditionalOperator *E,
 /// Check conversion of given expression to boolean.
 /// Input argument E is a logical expression.
 static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC) {
-  if (S.getLangOpts().Bool)
+  if (S.getLangOpts().Bool && !S.getLangOpts().C23)
 return;
   if (E->IgnoreParenImpCasts()->getType()->isAtomicType())
 return;
diff --git a/clang/test/C/C2x/n3042.c b/clang/test/C/C2x/n3042.c
index 3f869013af48070..99661b1fb39eba1 100644
--- a/clang/test/C/C2x/n3042.c
+++ b/clang/test/C/C2x/n3042.c
@@ -65,13 +65,15 @@ void test() {
   void *other_ptr = null_val;
 
   // Can it be used in all the places a scalar can be used?
-  if (null_val) {}
-  if (!null_val) {}
-  for (;null_val;) {}
-  while (nullptr) {}
-  null_val && nullptr;
-  nullptr || null_val;
-  null_val ? 0 : 1;
+  if (null_val) {} // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  if (!null_val) {}// expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  for (;null_val;) {}  // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  while (nullptr) {}   // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  null_val && nullptr; // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}} \
+  expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  nullptr || null_val; // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}} \
+  expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  null_val ? 0 : 1;// expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
   sizeof(null_val);
   alignas(nullptr_t) int aligned;
 
@@ -95,12 +97,12 @@ void test() {
   // Can it be converted to bool with the result false (this relies on Clang
   // accepting additional kinds of constant expressions where an ICE is
   // required)?
-  static_assert(!nullptr);
-  static_assert(!null_val);
-  static_assert(nullptr);  // expected-error {{static assertion failed due to 
requirement 'nullptr'}} \
-  expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
-  static_assert(null_val); // expected-error {{static assertion failed due to 
requirement 'null_val'}} \
-  expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(!nullptr);  // expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(!null_val); // expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(nullptr);   // expected-error {{static assertion failed due to 
requirement 'nullptr'}} \
+   expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(null_val);  // expected-error {{static assertion failed due to 
requirement 'null_val'}} \
+   expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
 
   // Do equality operators work as expected with it?
   static_assert(nullptr == nullptr);
@@ -142,11 +144,11 @@ void test() {
   _Generic(1 ? typed_ptr : nullptr, typeof(typed_ptr) : 0);
 
   // Same for GNU conditional operators?
-  _Generic(nullptr ?: nullptr, nullptr_t : 0);
-  _Generic(null_val ?: null_val, nullptr_t : 0);
+  _Generic(nullptr ?: nullptr, nullptr_t : 0);// expected-warning 
{{implicit conversion of nullptr constant to 'bool'}}
+  _Generic(null_val ?: null_val, nullptr_t : 0);  // expected-warning 
{{implicit con

[clang] [Sema] Fix c23 not checking CheckBoolLikeConversion (PR #79588)

2024-01-28 Thread Pil Eghoff via cfe-commits

https://github.com/pileghoff updated 
https://github.com/llvm/llvm-project/pull/79588

>From 6ea74d7aa0eadd4093350c04de95cbb2bdbaf0eb Mon Sep 17 00:00:00 2001
From: Pil Eghoff 
Date: Fri, 26 Jan 2024 13:30:17 +0100
Subject: [PATCH] [Sema] Fix c23 not checking CheckBoolLikeConversion

---
 clang/docs/ReleaseNotes.rst|  2 ++
 clang/lib/Sema/SemaChecking.cpp|  2 +-
 clang/test/C/C2x/n3042.c   | 36 --
 clang/test/Sema/warn-int-in-bool-context.c |  7 +
 4 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index db3d74e124e7d1d..641fa14ab069ed5 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -104,6 +104,8 @@ Improvements to Clang's time-trace
 Bug Fixes in This Version
 -
 
+- Fixed missing warnings when doing bool-like conversions in C23 (`#79435: 
https://github.com/llvm/llvm-project/issues/79435`_).
+
 Bug Fixes to Compiler Builtins
 ^^
 
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 4d280f25cc04c25..8e3bd1cd46076d6 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -16166,7 +16166,7 @@ static void CheckConditionalOperator(Sema &S, 
AbstractConditionalOperator *E,
 /// Check conversion of given expression to boolean.
 /// Input argument E is a logical expression.
 static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC) {
-  if (S.getLangOpts().Bool)
+  if (S.getLangOpts().Bool && !S.getLangOpts().C23)
 return;
   if (E->IgnoreParenImpCasts()->getType()->isAtomicType())
 return;
diff --git a/clang/test/C/C2x/n3042.c b/clang/test/C/C2x/n3042.c
index 3f869013af48070..99661b1fb39eba1 100644
--- a/clang/test/C/C2x/n3042.c
+++ b/clang/test/C/C2x/n3042.c
@@ -65,13 +65,15 @@ void test() {
   void *other_ptr = null_val;
 
   // Can it be used in all the places a scalar can be used?
-  if (null_val) {}
-  if (!null_val) {}
-  for (;null_val;) {}
-  while (nullptr) {}
-  null_val && nullptr;
-  nullptr || null_val;
-  null_val ? 0 : 1;
+  if (null_val) {} // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  if (!null_val) {}// expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  for (;null_val;) {}  // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  while (nullptr) {}   // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  null_val && nullptr; // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}} \
+  expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  nullptr || null_val; // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}} \
+  expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  null_val ? 0 : 1;// expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
   sizeof(null_val);
   alignas(nullptr_t) int aligned;
 
@@ -95,12 +97,12 @@ void test() {
   // Can it be converted to bool with the result false (this relies on Clang
   // accepting additional kinds of constant expressions where an ICE is
   // required)?
-  static_assert(!nullptr);
-  static_assert(!null_val);
-  static_assert(nullptr);  // expected-error {{static assertion failed due to 
requirement 'nullptr'}} \
-  expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
-  static_assert(null_val); // expected-error {{static assertion failed due to 
requirement 'null_val'}} \
-  expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(!nullptr);  // expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(!null_val); // expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(nullptr);   // expected-error {{static assertion failed due to 
requirement 'nullptr'}} \
+   expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(null_val);  // expected-error {{static assertion failed due to 
requirement 'null_val'}} \
+   expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
 
   // Do equality operators work as expected with it?
   static_assert(nullptr == nullptr);
@@ -142,11 +144,11 @@ void test() {
   _Generic(1 ? typed_ptr : nullptr, typeof(typed_ptr) : 0);
 
   // Same for GNU conditional operators?
-  _Generic(nullptr ?: nullptr, nullptr_t : 0);
-  _Generic(null_val ?: null_val, nullptr_t : 0);
+  _Generic(nullptr ?: nullptr, nullptr_t : 0);// expected-warning 
{{implicit conversion of nullptr constant to 'bool'}}
+  _Generic(null_val ?: null_val, nullptr_t : 0);  // expected-warning 
{{implicit conve

[clang] [Sema] Fix c23 not checking CheckBoolLikeConversion (PR #79588)

2024-01-28 Thread Pil Eghoff via cfe-commits

https://github.com/pileghoff updated 
https://github.com/llvm/llvm-project/pull/79588

>From 29a1eea6b27210ba35ad035b3c10aa8f5c73d86c Mon Sep 17 00:00:00 2001
From: Pil Eghoff 
Date: Fri, 26 Jan 2024 13:30:17 +0100
Subject: [PATCH] [Sema] Fix c23 not checking CheckBoolLikeConversion

---
 clang/docs/ReleaseNotes.rst|  2 ++
 clang/lib/Sema/SemaChecking.cpp|  2 +-
 clang/test/C/C2x/n3042.c   | 36 --
 clang/test/Sema/warn-int-in-bool-context.c |  7 +
 4 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index db3d74e124e7d1d..641fa14ab069ed5 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -104,6 +104,8 @@ Improvements to Clang's time-trace
 Bug Fixes in This Version
 -
 
+- Fixed missing warnings when doing bool-like conversions in C23 (`#79435: 
https://github.com/llvm/llvm-project/issues/79435`_).
+
 Bug Fixes to Compiler Builtins
 ^^
 
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 4d280f25cc04c25..8e3bd1cd46076d6 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -16166,7 +16166,7 @@ static void CheckConditionalOperator(Sema &S, 
AbstractConditionalOperator *E,
 /// Check conversion of given expression to boolean.
 /// Input argument E is a logical expression.
 static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC) {
-  if (S.getLangOpts().Bool)
+  if (S.getLangOpts().Bool && !S.getLangOpts().C23)
 return;
   if (E->IgnoreParenImpCasts()->getType()->isAtomicType())
 return;
diff --git a/clang/test/C/C2x/n3042.c b/clang/test/C/C2x/n3042.c
index 3f869013af48070..99661b1fb39eba1 100644
--- a/clang/test/C/C2x/n3042.c
+++ b/clang/test/C/C2x/n3042.c
@@ -65,13 +65,15 @@ void test() {
   void *other_ptr = null_val;
 
   // Can it be used in all the places a scalar can be used?
-  if (null_val) {}
-  if (!null_val) {}
-  for (;null_val;) {}
-  while (nullptr) {}
-  null_val && nullptr;
-  nullptr || null_val;
-  null_val ? 0 : 1;
+  if (null_val) {} // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  if (!null_val) {}// expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  for (;null_val;) {}  // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  while (nullptr) {}   // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  null_val && nullptr; // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}} \
+  expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  nullptr || null_val; // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}} \
+  expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  null_val ? 0 : 1;// expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
   sizeof(null_val);
   alignas(nullptr_t) int aligned;
 
@@ -95,12 +97,12 @@ void test() {
   // Can it be converted to bool with the result false (this relies on Clang
   // accepting additional kinds of constant expressions where an ICE is
   // required)?
-  static_assert(!nullptr);
-  static_assert(!null_val);
-  static_assert(nullptr);  // expected-error {{static assertion failed due to 
requirement 'nullptr'}} \
-  expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
-  static_assert(null_val); // expected-error {{static assertion failed due to 
requirement 'null_val'}} \
-  expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(!nullptr);  // expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(!null_val); // expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(nullptr);   // expected-error {{static assertion failed due to 
requirement 'nullptr'}} \
+   expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(null_val);  // expected-error {{static assertion failed due to 
requirement 'null_val'}} \
+   expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
 
   // Do equality operators work as expected with it?
   static_assert(nullptr == nullptr);
@@ -142,11 +144,11 @@ void test() {
   _Generic(1 ? typed_ptr : nullptr, typeof(typed_ptr) : 0);
 
   // Same for GNU conditional operators?
-  _Generic(nullptr ?: nullptr, nullptr_t : 0);
-  _Generic(null_val ?: null_val, nullptr_t : 0);
+  _Generic(nullptr ?: nullptr, nullptr_t : 0);// expected-warning 
{{implicit conversion of nullptr constant to 'bool'}}
+  _Generic(null_val ?: null_val, nullptr_t : 0);  // expected-warning 
{{implicit conve

[clang] [Sema] Fix c23 not checking CheckBoolLikeConversion (PR #79588)

2024-01-28 Thread Pil Eghoff via cfe-commits

https://github.com/pileghoff updated 
https://github.com/llvm/llvm-project/pull/79588

>From 34bb01d59005059c7f8f1156a164993c1839ee36 Mon Sep 17 00:00:00 2001
From: Pil Eghoff 
Date: Fri, 26 Jan 2024 13:30:17 +0100
Subject: [PATCH] [Sema] Fix c23 not checking CheckBoolLikeConversion

---
 clang/docs/ReleaseNotes.rst|  2 ++
 clang/lib/Sema/SemaChecking.cpp|  2 +-
 clang/test/C/C2x/n3042.c   | 36 --
 clang/test/Sema/warn-int-in-bool-context.c |  7 +
 4 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index db3d74e124e7d1..1a8e17b2b3065a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -104,6 +104,8 @@ Improvements to Clang's time-trace
 Bug Fixes in This Version
 -
 
+- Fixed missing warnings when doing bool-like conversions in C23 
[#79435](https://github.com/llvm/llvm-project/issues/79435).
+
 Bug Fixes to Compiler Builtins
 ^^
 
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 4d280f25cc04c2..8e3bd1cd46076d 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -16166,7 +16166,7 @@ static void CheckConditionalOperator(Sema &S, 
AbstractConditionalOperator *E,
 /// Check conversion of given expression to boolean.
 /// Input argument E is a logical expression.
 static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC) {
-  if (S.getLangOpts().Bool)
+  if (S.getLangOpts().Bool && !S.getLangOpts().C23)
 return;
   if (E->IgnoreParenImpCasts()->getType()->isAtomicType())
 return;
diff --git a/clang/test/C/C2x/n3042.c b/clang/test/C/C2x/n3042.c
index 3f869013af4807..99661b1fb39eba 100644
--- a/clang/test/C/C2x/n3042.c
+++ b/clang/test/C/C2x/n3042.c
@@ -65,13 +65,15 @@ void test() {
   void *other_ptr = null_val;
 
   // Can it be used in all the places a scalar can be used?
-  if (null_val) {}
-  if (!null_val) {}
-  for (;null_val;) {}
-  while (nullptr) {}
-  null_val && nullptr;
-  nullptr || null_val;
-  null_val ? 0 : 1;
+  if (null_val) {} // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  if (!null_val) {}// expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  for (;null_val;) {}  // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  while (nullptr) {}   // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  null_val && nullptr; // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}} \
+  expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  nullptr || null_val; // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}} \
+  expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  null_val ? 0 : 1;// expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
   sizeof(null_val);
   alignas(nullptr_t) int aligned;
 
@@ -95,12 +97,12 @@ void test() {
   // Can it be converted to bool with the result false (this relies on Clang
   // accepting additional kinds of constant expressions where an ICE is
   // required)?
-  static_assert(!nullptr);
-  static_assert(!null_val);
-  static_assert(nullptr);  // expected-error {{static assertion failed due to 
requirement 'nullptr'}} \
-  expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
-  static_assert(null_val); // expected-error {{static assertion failed due to 
requirement 'null_val'}} \
-  expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(!nullptr);  // expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(!null_val); // expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(nullptr);   // expected-error {{static assertion failed due to 
requirement 'nullptr'}} \
+   expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(null_val);  // expected-error {{static assertion failed due to 
requirement 'null_val'}} \
+   expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
 
   // Do equality operators work as expected with it?
   static_assert(nullptr == nullptr);
@@ -142,11 +144,11 @@ void test() {
   _Generic(1 ? typed_ptr : nullptr, typeof(typed_ptr) : 0);
 
   // Same for GNU conditional operators?
-  _Generic(nullptr ?: nullptr, nullptr_t : 0);
-  _Generic(null_val ?: null_val, nullptr_t : 0);
+  _Generic(nullptr ?: nullptr, nullptr_t : 0);// expected-warning 
{{implicit conversion of nullptr constant to 'bool'}}
+  _Generic(null_val ?: null_val, nullptr_t : 0);  // expected-warning 
{{implicit conversion of 

[clang] [Sema] Fix c23 not checking CheckBoolLikeConversion (PR #79588)

2024-01-28 Thread Pil Eghoff via cfe-commits

https://github.com/pileghoff updated 
https://github.com/llvm/llvm-project/pull/79588

>From 2c942f755c147a8413af4784f85da46f1f5384bd Mon Sep 17 00:00:00 2001
From: Pil Eghoff 
Date: Fri, 26 Jan 2024 13:30:17 +0100
Subject: [PATCH] [Sema] Fix c23 not checking CheckBoolLikeConversion

---
 clang/lib/Sema/SemaChecking.cpp|  2 +-
 clang/test/C/C2x/n3042.c   | 36 --
 clang/test/Sema/warn-int-in-bool-context.c |  7 +
 3 files changed, 27 insertions(+), 18 deletions(-)

diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 4d280f25cc04c25..8e3bd1cd46076d6 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -16166,7 +16166,7 @@ static void CheckConditionalOperator(Sema &S, 
AbstractConditionalOperator *E,
 /// Check conversion of given expression to boolean.
 /// Input argument E is a logical expression.
 static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC) {
-  if (S.getLangOpts().Bool)
+  if (S.getLangOpts().Bool && !S.getLangOpts().C23)
 return;
   if (E->IgnoreParenImpCasts()->getType()->isAtomicType())
 return;
diff --git a/clang/test/C/C2x/n3042.c b/clang/test/C/C2x/n3042.c
index 3f869013af48070..99661b1fb39eba1 100644
--- a/clang/test/C/C2x/n3042.c
+++ b/clang/test/C/C2x/n3042.c
@@ -65,13 +65,15 @@ void test() {
   void *other_ptr = null_val;
 
   // Can it be used in all the places a scalar can be used?
-  if (null_val) {}
-  if (!null_val) {}
-  for (;null_val;) {}
-  while (nullptr) {}
-  null_val && nullptr;
-  nullptr || null_val;
-  null_val ? 0 : 1;
+  if (null_val) {} // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  if (!null_val) {}// expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  for (;null_val;) {}  // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  while (nullptr) {}   // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  null_val && nullptr; // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}} \
+  expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  nullptr || null_val; // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}} \
+  expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  null_val ? 0 : 1;// expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
   sizeof(null_val);
   alignas(nullptr_t) int aligned;
 
@@ -95,12 +97,12 @@ void test() {
   // Can it be converted to bool with the result false (this relies on Clang
   // accepting additional kinds of constant expressions where an ICE is
   // required)?
-  static_assert(!nullptr);
-  static_assert(!null_val);
-  static_assert(nullptr);  // expected-error {{static assertion failed due to 
requirement 'nullptr'}} \
-  expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
-  static_assert(null_val); // expected-error {{static assertion failed due to 
requirement 'null_val'}} \
-  expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(!nullptr);  // expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(!null_val); // expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(nullptr);   // expected-error {{static assertion failed due to 
requirement 'nullptr'}} \
+   expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(null_val);  // expected-error {{static assertion failed due to 
requirement 'null_val'}} \
+   expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
 
   // Do equality operators work as expected with it?
   static_assert(nullptr == nullptr);
@@ -142,11 +144,11 @@ void test() {
   _Generic(1 ? typed_ptr : nullptr, typeof(typed_ptr) : 0);
 
   // Same for GNU conditional operators?
-  _Generic(nullptr ?: nullptr, nullptr_t : 0);
-  _Generic(null_val ?: null_val, nullptr_t : 0);
+  _Generic(nullptr ?: nullptr, nullptr_t : 0);// expected-warning 
{{implicit conversion of nullptr constant to 'bool'}}
+  _Generic(null_val ?: null_val, nullptr_t : 0);  // expected-warning 
{{implicit conversion of nullptr constant to 'bool'}}
   _Generic(typed_ptr ?: null_val, typeof(typed_ptr) : 0);
-  _Generic(null_val ?: typed_ptr, typeof(typed_ptr) : 0);
-  _Generic(nullptr ?: typed_ptr, typeof(typed_ptr) : 0);
+  _Generic(null_val ?: typed_ptr, typeof(typed_ptr) : 0); // expected-warning 
{{implicit conversion of nullptr constant to 'bool'}}
+  _Generic(nullptr ?: typed_ptr, typeof(typed_ptr) : 0);  // expected-warning 
{{implicit conversion of nullptr constant to 'bool'}}
   _Generic(typed_ptr ?: nullptr, typeof(typed_ptr) : 0);
 
   //

[clang] [Sema] Fix c23 not checking CheckBoolLikeConversion (PR #79588)

2024-01-28 Thread Pil Eghoff via cfe-commits

pileghoff wrote:

For testing i have fixed the new warnings in `n3042.c` and i have expanded 
`warn-int-in-bool-context.c` to check c23 specefically (which was broken, but 
is now fixed) and i added a few extra cases to the test. I will take a look at 
the release notes later today.

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


[clang-tools-extra] [clang] [llvm] [RISCV][ISel] Add ISel support for experimental Zimop extension (PR #77089)

2024-01-28 Thread Jivan Hakobyan via cfe-commits

https://github.com/JivanH updated 
https://github.com/llvm/llvm-project/pull/77089

>From caab6046a26517946bdce7659e4236ae9d5154fe Mon Sep 17 00:00:00 2001
From: ln8-8 
Date: Fri, 5 Jan 2024 16:08:53 +0400
Subject: [PATCH 1/5] [RISCV][ISel] Add ISel support for experimental Zimop
 extension

This implements ISel support for mopr[0-31] and moprr[0-8] instructions for 32 
and 64 bits
---
 llvm/include/llvm/IR/IntrinsicsRISCV.td   |  23 +++
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp   | 171 ++
 llvm/lib/Target/RISCV/RISCVISelLowering.h |   7 +
 llvm/lib/Target/RISCV/RISCVInstrInfoZimop.td  |  28 +++
 .../test/CodeGen/RISCV/rv32zimop-intrinsic.ll |  48 +
 .../test/CodeGen/RISCV/rv64zimop-intrinsic.ll |  97 ++
 6 files changed, 374 insertions(+)
 create mode 100644 llvm/test/CodeGen/RISCV/rv32zimop-intrinsic.ll
 create mode 100644 llvm/test/CodeGen/RISCV/rv64zimop-intrinsic.ll

diff --git a/llvm/include/llvm/IR/IntrinsicsRISCV.td 
b/llvm/include/llvm/IR/IntrinsicsRISCV.td
index a391bc53cdb0e99..8ddda2a13e5c3b4 100644
--- a/llvm/include/llvm/IR/IntrinsicsRISCV.td
+++ b/llvm/include/llvm/IR/IntrinsicsRISCV.td
@@ -108,6 +108,29 @@ let TargetPrefix = "riscv" in {
   def int_riscv_xperm8  : BitManipGPRGPRIntrinsics;
 } // TargetPrefix = "riscv"
 
+//===--===//
+// May-Be-Operations
+
+let TargetPrefix = "riscv" in {
+
+  class MOPGPRIntrinsics
+  : DefaultAttrsIntrinsic<[llvm_any_ty],
+  [LLVMMatchType<0>],
+  [IntrNoMem, IntrSpeculatable]>;
+  class MOPGPRGPRIntrinsics
+  : DefaultAttrsIntrinsic<[llvm_any_ty],
+  [LLVMMatchType<0>, LLVMMatchType<0>],
+  [IntrNoMem, IntrSpeculatable]>;
+
+  // Zimop
+   foreach i = 0...31 in {
+def int_riscv_mopr#i : MOPGPRIntrinsics;
+   }
+  foreach i = 0...7 in {
+def int_riscv_moprr#i : MOPGPRGPRIntrinsics;
+  }
+} // TargetPrefix = "riscv"
+
 
//===--===//
 // Vectors
 
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp 
b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index bc4b2b022c0ae98..f8c10fcd139f82d 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -8404,6 +8404,73 @@ SDValue 
RISCVTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
 IntNo == Intrinsic::riscv_zip ? RISCVISD::ZIP : RISCVISD::UNZIP;
 return DAG.getNode(Opc, DL, XLenVT, Op.getOperand(1));
   }
+#define RISCV_MOPR_64_CASE(NAME, OPCODE)   
\
+  case Intrinsic::riscv_##NAME: {  
\
+if (RV64LegalI32 && Subtarget.is64Bit() && 
\
+Op.getValueType() == MVT::i32) {   
\
+  SDValue NewOp =  
\
+  DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op.getOperand(1));
\
+  SDValue Res = DAG.getNode(OPCODE, DL, MVT::i64, NewOp);  
\
+  return DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Res);
\
+}  
\
+return DAG.getNode(OPCODE, DL, XLenVT, Op.getOperand(1));  
\
+  }
+RISCV_MOPR_64_CASE(mopr0, RISCVISD::MOPR0)
+RISCV_MOPR_64_CASE(mopr1, RISCVISD::MOPR1)
+RISCV_MOPR_64_CASE(mopr2, RISCVISD::MOPR2)
+RISCV_MOPR_64_CASE(mopr3, RISCVISD::MOPR3)
+RISCV_MOPR_64_CASE(mopr4, RISCVISD::MOPR4)
+RISCV_MOPR_64_CASE(mopr5, RISCVISD::MOPR5)
+RISCV_MOPR_64_CASE(mopr6, RISCVISD::MOPR6)
+RISCV_MOPR_64_CASE(mopr7, RISCVISD::MOPR7)
+RISCV_MOPR_64_CASE(mopr8, RISCVISD::MOPR8)
+RISCV_MOPR_64_CASE(mopr9, RISCVISD::MOPR9)
+RISCV_MOPR_64_CASE(mopr10, RISCVISD::MOPR10)
+RISCV_MOPR_64_CASE(mopr11, RISCVISD::MOPR11)
+RISCV_MOPR_64_CASE(mopr12, RISCVISD::MOPR12)
+RISCV_MOPR_64_CASE(mopr13, RISCVISD::MOPR13)
+RISCV_MOPR_64_CASE(mopr14, RISCVISD::MOPR14)
+RISCV_MOPR_64_CASE(mopr15, RISCVISD::MOPR15)
+RISCV_MOPR_64_CASE(mopr16, RISCVISD::MOPR16)
+RISCV_MOPR_64_CASE(mopr17, RISCVISD::MOPR17)
+RISCV_MOPR_64_CASE(mopr18, RISCVISD::MOPR18)
+RISCV_MOPR_64_CASE(mopr19, RISCVISD::MOPR19)
+RISCV_MOPR_64_CASE(mopr20, RISCVISD::MOPR20)
+RISCV_MOPR_64_CASE(mopr21, RISCVISD::MOPR21)
+RISCV_MOPR_64_CASE(mopr22, RISCVISD::MOPR22)
+RISCV_MOPR_64_CASE(mopr23, RISCVISD::MOPR23)
+RISCV_MOPR_64_CASE(mopr24, RISCVISD::MOPR24)
+RISCV_MOPR_64_CASE(mopr25, RISCVISD::MOPR25)
+RISCV_MOPR_64_CASE(mopr26, RISCVISD::MOPR26)
+RISCV_MOPR_64_CASE(mopr27, RISCVISD::MOPR27)
+RISCV_MOPR_64_CASE(mopr28, RISCVISD::MOPR28)
+RISCV_MOPR_64_CASE(mopr29, RISCVISD::MOPR29)
+RISCV_MOPR_64_CASE(mopr30, RISCVISD::MOPR30)
+RISCV_MOPR_64_CASE

[clang] [Sema] Fix c23 not checking CheckBoolLikeConversion (PR #79588)

2024-01-28 Thread Pil Eghoff via cfe-commits

https://github.com/pileghoff updated 
https://github.com/llvm/llvm-project/pull/79588

>From 43241ab75d4c15e6885337be1b0ce4cf0217f384 Mon Sep 17 00:00:00 2001
From: Pil Eghoff 
Date: Fri, 26 Jan 2024 13:30:17 +0100
Subject: [PATCH] [Sema] Fix c23 not checking CheckBoolLikeConversion

---
 clang/lib/Sema/SemaChecking.cpp|  2 +-
 clang/test/C/C2x/n3042.c   | 36 --
 clang/test/Sema/warn-int-in-bool-context.c |  7 +
 3 files changed, 27 insertions(+), 18 deletions(-)

diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 4d280f25cc04c2..8e3bd1cd46076d 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -16166,7 +16166,7 @@ static void CheckConditionalOperator(Sema &S, 
AbstractConditionalOperator *E,
 /// Check conversion of given expression to boolean.
 /// Input argument E is a logical expression.
 static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC) {
-  if (S.getLangOpts().Bool)
+  if (S.getLangOpts().Bool && !S.getLangOpts().C23)
 return;
   if (E->IgnoreParenImpCasts()->getType()->isAtomicType())
 return;
diff --git a/clang/test/C/C2x/n3042.c b/clang/test/C/C2x/n3042.c
index 3f869013af4807..99661b1fb39eba 100644
--- a/clang/test/C/C2x/n3042.c
+++ b/clang/test/C/C2x/n3042.c
@@ -65,13 +65,15 @@ void test() {
   void *other_ptr = null_val;
 
   // Can it be used in all the places a scalar can be used?
-  if (null_val) {}
-  if (!null_val) {}
-  for (;null_val;) {}
-  while (nullptr) {}
-  null_val && nullptr;
-  nullptr || null_val;
-  null_val ? 0 : 1;
+  if (null_val) {} // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  if (!null_val) {}// expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  for (;null_val;) {}  // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  while (nullptr) {}   // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  null_val && nullptr; // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}} \
+  expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  nullptr || null_val; // expected-warning {{implicit conversion of nullptr 
constant to 'bool'}} \
+  expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
+  null_val ? 0 : 1;// expected-warning {{implicit conversion of nullptr 
constant to 'bool'}}
   sizeof(null_val);
   alignas(nullptr_t) int aligned;
 
@@ -95,12 +97,12 @@ void test() {
   // Can it be converted to bool with the result false (this relies on Clang
   // accepting additional kinds of constant expressions where an ICE is
   // required)?
-  static_assert(!nullptr);
-  static_assert(!null_val);
-  static_assert(nullptr);  // expected-error {{static assertion failed due to 
requirement 'nullptr'}} \
-  expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
-  static_assert(null_val); // expected-error {{static assertion failed due to 
requirement 'null_val'}} \
-  expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(!nullptr);  // expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(!null_val); // expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(nullptr);   // expected-error {{static assertion failed due to 
requirement 'nullptr'}} \
+   expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
+  static_assert(null_val);  // expected-error {{static assertion failed due to 
requirement 'null_val'}} \
+   expected-warning {{implicit conversion of 
nullptr constant to 'bool'}}
 
   // Do equality operators work as expected with it?
   static_assert(nullptr == nullptr);
@@ -142,11 +144,11 @@ void test() {
   _Generic(1 ? typed_ptr : nullptr, typeof(typed_ptr) : 0);
 
   // Same for GNU conditional operators?
-  _Generic(nullptr ?: nullptr, nullptr_t : 0);
-  _Generic(null_val ?: null_val, nullptr_t : 0);
+  _Generic(nullptr ?: nullptr, nullptr_t : 0);// expected-warning 
{{implicit conversion of nullptr constant to 'bool'}}
+  _Generic(null_val ?: null_val, nullptr_t : 0);  // expected-warning 
{{implicit conversion of nullptr constant to 'bool'}}
   _Generic(typed_ptr ?: null_val, typeof(typed_ptr) : 0);
-  _Generic(null_val ?: typed_ptr, typeof(typed_ptr) : 0);
-  _Generic(nullptr ?: typed_ptr, typeof(typed_ptr) : 0);
+  _Generic(null_val ?: typed_ptr, typeof(typed_ptr) : 0); // expected-warning 
{{implicit conversion of nullptr constant to 'bool'}}
+  _Generic(nullptr ?: typed_ptr, typeof(typed_ptr) : 0);  // expected-warning 
{{implicit conversion of nullptr constant to 'bool'}}
   _Generic(typed_ptr ?: nullptr, typeof(typed_ptr) : 0);
 
   // Do 

[clang] [Clang][Sema] Fix crash when type used in return statement contains errors (PR #79788)

2024-01-28 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Shafik Yaghmour (shafik)


Changes

In Sema in `BuildReturnStmt(...)` when we try to determine is the type is move 
eligable or copy elidable we don't currently check of the init of the `VarDecl` 
contain errors or not. This can lead to a crash since we may send a type that 
is not complete into `getTypeInfo(...)` which does not allow this.

This fixes: https://github.com/llvm/llvm-project/issues/63244
https://github.com/llvm/llvm-project/issues/79745

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


2 Files Affected:

- (modified) clang/lib/Sema/SemaStmt.cpp (+2) 
- (modified) clang/test/SemaCXX/deduced-return-type-cxx14.cpp (+9) 


``diff
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 9e7c8c7e4e8c12..5d5a29b825ae7d 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -3391,6 +3391,8 @@ Sema::NamedReturnInfo Sema::getNamedReturnInfo(Expr *&E,
   const auto *VD = dyn_cast(DR->getDecl());
   if (!VD)
 return NamedReturnInfo();
+  if (VD->getInit() && VD->getInit()->containsErrors())
+return NamedReturnInfo();
   NamedReturnInfo Res = getNamedReturnInfo(VD);
   if (Res.Candidate && !E->isXValue() &&
   (Mode == SimplerImplicitMoveMode::ForceOn ||
diff --git a/clang/test/SemaCXX/deduced-return-type-cxx14.cpp 
b/clang/test/SemaCXX/deduced-return-type-cxx14.cpp
index c0d43911b8c717..415bbbf1a0bc50 100644
--- a/clang/test/SemaCXX/deduced-return-type-cxx14.cpp
+++ b/clang/test/SemaCXX/deduced-return-type-cxx14.cpp
@@ -724,3 +724,12 @@ struct DeducedTargetTypeOfConversionFunction {
   // since-cxx20-error@-1 {{'decltype(auto)' not allowed in declaration of 
conversion function template}}
 #endif
 };
+
+namespace GH79745 {
+template  struct a; // expected-note {{template is declared 
here}}
+auto f() {
+  a c; // cxx20_23-error {{implicit instantiation of undefined template}} \
+   // cxx14-error {{use of class template 'a' requires template arguments}}
+  return c;
+}
+}

``




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


[clang] [Clang][Sema] Fix crash when type used in return statement contains errors (PR #79788)

2024-01-28 Thread Shafik Yaghmour via cfe-commits

https://github.com/shafik created 
https://github.com/llvm/llvm-project/pull/79788

In Sema in `BuildReturnStmt(...)` when we try to determine is the type is move 
eligable or copy elidable we don't currently check of the init of the `VarDecl` 
contain errors or not. This can lead to a crash since we may send a type that 
is not complete into `getTypeInfo(...)` which does not allow this.

This fixes: https://github.com/llvm/llvm-project/issues/63244
https://github.com/llvm/llvm-project/issues/79745

>From 82d2561488a13edd9527737fbcc2391bb30a78e8 Mon Sep 17 00:00:00 2001
From: Shafik Yaghmour 
Date: Sun, 28 Jan 2024 22:42:53 -0800
Subject: [PATCH] [Clang][Sema] Fix crash when type used in return statement
 contains errors

In Sema in `BuildReturnStmt(...)` when we try to determine is the type is move
eligable or copy elidable we don't currently check of the init of the `VarDecl`
contain errors or not. This can lead to a crash since we may send a type that
is not complete into `getTypeInfo(...)` which does not allow this.

This fixes: https://github.com/llvm/llvm-project/issues/63244
https://github.com/llvm/llvm-project/issues/79745
---
 clang/lib/Sema/SemaStmt.cpp  | 2 ++
 clang/test/SemaCXX/deduced-return-type-cxx14.cpp | 9 +
 2 files changed, 11 insertions(+)

diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 9e7c8c7e4e8c12c..5d5a29b825ae7d7 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -3391,6 +3391,8 @@ Sema::NamedReturnInfo Sema::getNamedReturnInfo(Expr *&E,
   const auto *VD = dyn_cast(DR->getDecl());
   if (!VD)
 return NamedReturnInfo();
+  if (VD->getInit() && VD->getInit()->containsErrors())
+return NamedReturnInfo();
   NamedReturnInfo Res = getNamedReturnInfo(VD);
   if (Res.Candidate && !E->isXValue() &&
   (Mode == SimplerImplicitMoveMode::ForceOn ||
diff --git a/clang/test/SemaCXX/deduced-return-type-cxx14.cpp 
b/clang/test/SemaCXX/deduced-return-type-cxx14.cpp
index c0d43911b8c7174..415bbbf1a0bc509 100644
--- a/clang/test/SemaCXX/deduced-return-type-cxx14.cpp
+++ b/clang/test/SemaCXX/deduced-return-type-cxx14.cpp
@@ -724,3 +724,12 @@ struct DeducedTargetTypeOfConversionFunction {
   // since-cxx20-error@-1 {{'decltype(auto)' not allowed in declaration of 
conversion function template}}
 #endif
 };
+
+namespace GH79745 {
+template  struct a; // expected-note {{template is declared 
here}}
+auto f() {
+  a c; // cxx20_23-error {{implicit instantiation of undefined template}} \
+   // cxx14-error {{use of class template 'a' requires template arguments}}
+  return c;
+}
+}

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


[lld] [flang] [clang] [llvm] [AMDGPU] Introduce Code Object V6 (PR #76954)

2024-01-28 Thread Pierre van Houtryve via cfe-commits


@@ -620,6 +620,15 @@ void ScalarBitSetTraits::bitset(IO &IO,
   BCase(EF_AMDGPU_FEATURE_XNACK_V3);
   BCase(EF_AMDGPU_FEATURE_SRAMECC_V3);
   break;
+case ELF::ELFABIVERSION_AMDGPU_HSA_V6:

Pierre-vh wrote:

elf-headers.test already covers it

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


[mlir] [flang] [clang] [llvm] [mlir][complex] Prevent underflow in complex.abs (PR #79786)

2024-01-28 Thread Kai Sasaki via cfe-commits

https://github.com/Lewuathe updated 
https://github.com/llvm/llvm-project/pull/79786

>From 8a7243c4c2be5db5e0a95535f36386557e68e18c Mon Sep 17 00:00:00 2001
From: Kai Sasaki 
Date: Fri, 15 Dec 2023 15:53:54 +0900
Subject: [PATCH] [mlir][complex] Prevent underflow in complex.abs

---
 .../ComplexToStandard/ComplexToStandard.cpp   |  58 ++--
 .../convert-to-standard.mlir  | 125 +++---
 .../ComplexToStandard/full-conversion.mlir|  27 +++-
 .../Dialect/Complex/CPU/correctness.mlir  |  48 +++
 4 files changed, 218 insertions(+), 40 deletions(-)

diff --git a/mlir/lib/Conversion/ComplexToStandard/ComplexToStandard.cpp 
b/mlir/lib/Conversion/ComplexToStandard/ComplexToStandard.cpp
index 4c9dad9e2c17312..6e0eddab0e3aae0 100644
--- a/mlir/lib/Conversion/ComplexToStandard/ComplexToStandard.cpp
+++ b/mlir/lib/Conversion/ComplexToStandard/ComplexToStandard.cpp
@@ -26,29 +26,59 @@ namespace mlir {
 using namespace mlir;
 
 namespace {
+// The algorithm is listed in https://dl.acm.org/doi/pdf/10.1145/363717.363780.
 struct AbsOpConversion : public OpConversionPattern {
   using OpConversionPattern::OpConversionPattern;
 
   LogicalResult
   matchAndRewrite(complex::AbsOp op, OpAdaptor adaptor,
   ConversionPatternRewriter &rewriter) const override {
-auto loc = op.getLoc();
-auto type = op.getType();
+mlir::ImplicitLocOpBuilder b(op.getLoc(), rewriter);
 
 arith::FastMathFlagsAttr fmf = op.getFastMathFlagsAttr();
 
-Value real =
-rewriter.create(loc, type, adaptor.getComplex());
-Value imag =
-rewriter.create(loc, type, adaptor.getComplex());
-Value realSqr =
-rewriter.create(loc, real, real, fmf.getValue());
-Value imagSqr =
-rewriter.create(loc, imag, imag, fmf.getValue());
-Value sqNorm =
-rewriter.create(loc, realSqr, imagSqr, fmf.getValue());
-
-rewriter.replaceOpWithNewOp(op, sqNorm);
+Type elementType = op.getType();
+Value arg = adaptor.getComplex();
+
+Value zero =
+b.create(elementType, b.getZeroAttr(elementType));
+Value one = b.create(elementType,
+b.getFloatAttr(elementType, 1.0));
+
+Value real = b.create(elementType, arg);
+Value imag = b.create(elementType, arg);
+
+Value realIsZero =
+b.create(arith::CmpFPredicate::OEQ, real, zero);
+Value imagIsZero =
+b.create(arith::CmpFPredicate::OEQ, imag, zero);
+
+// Real > Imag
+Value imagDivReal = b.create(imag, real, fmf.getValue());
+Value imagSq =
+b.create(imagDivReal, imagDivReal, fmf.getValue());
+Value imagSqPlusOne = b.create(imagSq, one, fmf.getValue());
+Value imagSqrt = b.create(imagSqPlusOne, fmf.getValue());
+Value realAbs = b.create(real, fmf.getValue());
+Value absImag = b.create(imagSqrt, realAbs, fmf.getValue());
+
+// Real <= Imag
+Value realDivImag = b.create(real, imag, fmf.getValue());
+Value realSq =
+b.create(realDivImag, realDivImag, fmf.getValue());
+Value realSqPlusOne = b.create(realSq, one, fmf.getValue());
+Value realSqrt = b.create(realSqPlusOne, fmf.getValue());
+Value imagAbs = b.create(imag, fmf.getValue());
+Value absReal = b.create(realSqrt, imagAbs, fmf.getValue());
+
+rewriter.replaceOpWithNewOp(
+op, realIsZero, imag,
+b.create(
+imagIsZero, real,
+b.create(
+b.create(arith::CmpFPredicate::OGT, real, imag),
+absImag, absReal)));
+
 return success();
   }
 };
diff --git a/mlir/test/Conversion/ComplexToStandard/convert-to-standard.mlir 
b/mlir/test/Conversion/ComplexToStandard/convert-to-standard.mlir
index 8fa29ea43854a4b..de519f6a706ab03 100644
--- a/mlir/test/Conversion/ComplexToStandard/convert-to-standard.mlir
+++ b/mlir/test/Conversion/ComplexToStandard/convert-to-standard.mlir
@@ -7,13 +7,30 @@ func.func @complex_abs(%arg: complex) -> f32 {
   %abs = complex.abs %arg: complex
   return %abs : f32
 }
+
+// CHECK: %[[ZERO:.*]] = arith.constant 0.00e+00 : f32
+// CHECK: %[[ONE:.*]] = arith.constant 1.00e+00 : f32
 // CHECK: %[[REAL:.*]] = complex.re %[[ARG]] : complex
 // CHECK: %[[IMAG:.*]] = complex.im %[[ARG]] : complex
-// CHECK-DAG: %[[REAL_SQ:.*]] = arith.mulf %[[REAL]], %[[REAL]] : f32
-// CHECK-DAG: %[[IMAG_SQ:.*]] = arith.mulf %[[IMAG]], %[[IMAG]] : f32
-// CHECK: %[[SQ_NORM:.*]] = arith.addf %[[REAL_SQ]], %[[IMAG_SQ]] : f32
-// CHECK: %[[NORM:.*]] = math.sqrt %[[SQ_NORM]] : f32
-// CHECK: return %[[NORM]] : f32
+// CHECK: %[[IS_REAL_ZERO:.*]] = arith.cmpf oeq, %[[REAL]], %[[ZERO]] : f32
+// CHECK: %[[IS_IMAG_ZERO:.*]] = arith.cmpf oeq, %[[IMAG]], %[[ZERO]] : f32
+// CHECK: %[[IMAG_DIV_REAL:.*]] = arith.divf %[[IMAG]], %[[REAL]] : f32
+// CHECK: %[[IMAG_SQ:.*]] = arith.mulf %[[IMAG_DIV_REAL]], %[[IMAG_DIV_REAL]] 
: f32
+// CHECK: %[[IMAG_SQ_PLUS_ONE:.*]] = arith.addf %[[IMAG_SQ]], %[[ONE]] : f32
+// CHECK: %[[IMAG_SQRT

[lld] [flang] [clang] [llvm] [AMDGPU] Introduce Code Object V6 (PR #76954)

2024-01-28 Thread Pierre van Houtryve via cfe-commits


@@ -44,8 +44,15 @@ constexpr uint32_t VersionMajorV5 = 1;
 /// HSA metadata minor version for code object V5.
 constexpr uint32_t VersionMinorV5 = 2;
 
+/// HSA metadata major version for code object V6.
+constexpr uint32_t VersionMajorV6 = 1;
+/// HSA metadata minor version for code object V6.
+constexpr uint32_t VersionMinorV6 = 3;

Pierre-vh wrote:

Not yet, but I assume we'll want to bundle some changes to the MD with V6 so 
it's better to update the version now, no?

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


[clang] [llvm] [AMDGPU] Emit a waitcnt instruction after each memory instruction (PR #79236)

2024-01-28 Thread Pierre van Houtryve via cfe-commits


@@ -17,13 +17,16 @@
 #include "AMDGPUMachineModuleInfo.h"
 #include "GCNSubtarget.h"
 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
+#include "Utils/AMDGPUBaseInfo.h"
 #include "llvm/ADT/BitmaskEnum.h"
 #include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/Support/AtomicOrdering.h"
 #include "llvm/TargetParser/TargetParser.h"
 
+#include 

Pierre-vh wrote:

I suspect this is a debug leftover but: always use `dbgs` to print, it's easier 
and faster to build than `iostream` :)

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


[llvm] [clang] [AMDGPU] Emit a waitcnt instruction after each memory instruction (PR #79236)

2024-01-28 Thread Pierre van Houtryve via cfe-commits


@@ -0,0 +1,199 @@
+; Testing the -amdgpu-precise-memory-op option

Pierre-vh wrote:

Please generate the test using `update_llc_test_checks`, much easier to update 
if/when things change.

Also I think you don't need `-verify-machineinstrs`. It's expensive and runs 
anyway when EXPENSIVE_CHECKS is on.

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


[clang] [llvm] [AMDGPU] Emit a waitcnt instruction after each memory instruction (PR #79236)

2024-01-28 Thread Pierre van Houtryve via cfe-commits


@@ -2561,6 +2567,70 @@ bool SIMemoryLegalizer::expandAtomicCmpxchgOrRmw(const 
SIMemOpInfo &MOI,
   return Changed;
 }
 
+bool SIMemoryLegalizer::GFX9InsertWaitcntForPreciseMem(MachineFunction &MF) {
+  const GCNSubtarget &ST = MF.getSubtarget();
+  const SIInstrInfo *TII = ST.getInstrInfo();
+  IsaVersion IV = getIsaVersion(ST.getCPU());
+
+  bool Changed = false;
+
+  for (auto &MBB : MF) {
+for (auto MI = MBB.begin(); MI != MBB.end();) {
+  MachineInstr &Inst = *MI;
+  ++MI;
+  if (Inst.mayLoadOrStore() == false)
+continue;
+
+  // Todo: if next insn is an s_waitcnt
+  AMDGPU::Waitcnt Wait;
+
+  if (!(Inst.getDesc().TSFlags & SIInstrFlags::maybeAtomic)) {
+if (TII->isSMRD(Inst)) {  // scalar

Pierre-vh wrote:

Can we have a shared helper, e.g. in `SIInstrInfo`  for both? It's a lot of 
logic to duplicate

> The counter values in SIInsertWaitcnt are precise, while in this features the 
> counters are simply set to 0.
That could just be a boolean switch in a shared helper

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


[llvm] [clang] [AMDGPU] Emit a waitcnt instruction after each memory instruction (PR #79236)

2024-01-28 Thread Pierre van Houtryve via cfe-commits


@@ -0,0 +1,199 @@
+; Testing the -amdgpu-precise-memory-op option
+; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -mattr=+amdgpu-precise-memory-op 
-verify-machineinstrs < %s | FileCheck %s -check-prefixes=GFX9
+; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -mattr=+amdgpu-precise-memory-op 
-verify-machineinstrs < %s | FileCheck %s -check-prefixes=GFX90A
+; COM: llc -mtriple=amdgcn -mcpu=gfx1010 -mattr=+amdgpu-precise-memory-op 
-verify-machineinstrs < %s | FileCheck %s -check-prefixes=GFX10
+; RUN: llc -mtriple=amdgcn-- -mcpu=gfx900 
-mattr=-flat-for-global,+enable-flat-scratch,+amdgpu-precise-memory-op 
-amdgpu-use-divergent-register-indexing -verify-machineinstrs < %s | FileCheck 
--check-prefixes=GFX9-FLATSCR %s
+
+; from atomicrmw-expand.ll
+; covers flat_load, flat_atomic
+define void @syncscope_workgroup_nortn(ptr %addr, float %val) {
+; GFX90A-LABEL: syncscope_workgroup_nortn:
+; GFX90A:  ; %bb.0:
+; GFX90A: flat_load_dword v5, v[0:1]
+; GFX90A-NEXT:s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX90A:  .LBB0_1: ; %atomicrmw.start
+; GFX90A: flat_atomic_cmpswap v3, v[0:1], v[4:5] glc
+; GFX90A-NEXT:s_waitcnt vmcnt(0) lgkmcnt(0)
+  %res = atomicrmw fadd ptr %addr, float %val syncscope("workgroup") seq_cst
+  ret void
+}
+
+; from atomicrmw-nand.ll
+; covers global_atomic, global_load
+define i32 @atomic_nand_i32_global(ptr addrspace(1) %ptr) nounwind {
+; GFX9-LABEL: atomic_nand_i32_global:
+; GFX9:   ; %bb.0:
+; GFX9-NEXT:s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:global_load_dword v2, v[0:1], off
+; GFX9-NEXT:s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX9-NEXT:s_mov_b64 s[4:5], 0
+; GFX9-NEXT:  .LBB1_1: ; %atomicrmw.start
+; GFX9-NEXT:; =>This Inner Loop Header: Depth=1
+; GFX9-NOT: s_waitcnt vmcnt(0)
+; GFX9-NEXT:v_mov_b32_e32 v3, v2
+; GFX9-NEXT:v_not_b32_e32 v2, v3
+; GFX9-NEXT:v_or_b32_e32 v2, -5, v2
+; GFX9-NEXT:global_atomic_cmpswap v2, v[0:1], v[2:3], off glc
+; GFX9-NEXT:s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX9-NEXT:buffer_wbinvl1_vol
+; GFX9-NEXT:v_cmp_eq_u32_e32 vcc, v2, v3
+; GFX9-NEXT:s_or_b64 s[4:5], vcc, s[4:5]
+; GFX9-NEXT:s_andn2_b64 exec, exec, s[4:5]
+; GFX9-NEXT:s_cbranch_execnz .LBB1_1
+; GFX9-NEXT:  ; %bb.2: ; %atomicrmw.end
+; GFX9-NEXT:s_or_b64 exec, exec, s[4:5]
+; GFX9-NEXT:v_mov_b32_e32 v0, v2
+; GFX9-NEXT:s_setpc_b64 s[30:31]
+  %result = atomicrmw nand ptr addrspace(1) %ptr, i32 4 seq_cst
+  ret i32 %result
+}
+
+; from bf16.ll
+; covers buffer_load, buffer_store, flat_load, flat_store, global_load, 
global_store
+define void @test_load_store(ptr addrspace(1) %in, ptr addrspace(1) %out) {
+;
+; GFX9-LABEL: test_load_store:
+; GFX9:   ; %bb.0:
+; GFX9-NEXT:s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:global_load_ushort v0, v[0:1], off
+; GFX9-NEXT:s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX9-NEXT:global_store_short v[2:3], v0, off
+; GFX9-NEXT:s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX9-NEXT:s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: test_load_store:
+; GFX10:   ; %bb.0:
+; GFX10-NEXT:s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT:global_load_ushort v0, v[0:1], off
+; GFX10-NEXT:s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT:s_waitcnt_vscnt null, 0x0
+; GFX10-NEXT:global_store_short v[2:3], v0, off
+; GFX10-NEXT:s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT:s_waitcnt_vscnt null, 0x0
+; GFX10-NEXT:s_setpc_b64 s[30:31]
+  %val = load bfloat, ptr addrspace(1) %in
+  store bfloat %val, ptr addrspace(1) %out
+  ret void
+}
+
+; from scratch-simple.ll
+; covers scratch_load, scratch_store
+;
+; GFX9-FLATSCR-LABEL: {{^}}vs_main:
+; GFX9-FLATSCR:scratch_store_dwordx4 off, v[{{[0-9:]+}}],
+; GFX9-FLATSCR-NEXT:   s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX9-FLATSCR:scratch_load_dword {{v[0-9]+}}, {{v[0-9]+}}, off
+; GFX9-FLATSCR-NEXT:   s_waitcnt vmcnt(0) lgkmcnt(0)
+define amdgpu_vs float @vs_main(i32 %idx) {
+  %v1 = extractelement <81 x float> , i32 %idx

Pierre-vh wrote:

what is that test for/why does it need such a big vector?
if it's to force a spill to stack I think you can do that by playing with the 
number of available v/sgprs, IIRC there is an attribute or CL opt for that

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


[clang] [llvm] [AMDGPU] Emit a waitcnt instruction after each memory instruction (PR #79236)

2024-01-28 Thread Pierre van Houtryve via cfe-commits


@@ -641,6 +644,9 @@ class SIMemoryLegalizer final : public MachineFunctionPass {
   bool expandAtomicCmpxchgOrRmw(const SIMemOpInfo &MOI,
 MachineBasicBlock::iterator &MI);
 
+  bool GFX9InsertWaitcntForPreciseMem(MachineFunction &MF);

Pierre-vh wrote:

Agreed, this should definitely be a virtual function such as 
`insertWaitcntForPreciseMem` and let the CacheControl implementation do what is 
needed. This is just emulating what `CacheControl` already does

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


[llvm] [clang] [AMDGPU] Emit a waitcnt instruction after each memory instruction (PR #79236)

2024-01-28 Thread Pierre van Houtryve via cfe-commits


@@ -167,6 +167,10 @@ def FeatureCuMode : SubtargetFeature<"cumode",
   "Enable CU wavefront execution mode"
 >;
 
+def FeaturePreciseMemory

Pierre-vh wrote:

I'm not a fan of using a feature for this, I think we should have a backend CL 
option instead. After all this isn't an architecture feature but just a 
behavior change for SIMemoryLegalizer.


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


[clang] 4118082 - [C++20] [Modules] Remove previous workaround for odr hashing enums

2024-01-28 Thread Chuanqi Xu via cfe-commits

Author: Chuanqi Xu
Date: 2024-01-29T14:35:23+08:00
New Revision: 4118082f651a05cca258c684ab1199578b57afac

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

LOG: [C++20] [Modules] Remove previous workaround for odr hashing enums

Previosly we land
https://github.com/llvm/llvm-project/commit/085eae6b863881fb9fda323e5b672b04a00ed19e
to workaround the false positive ODR violations in
https://github.com/llvm/llvm-project/issues/76638.

However, we decided to not perform ODR checks for decls from GMF in
https://github.com/llvm/llvm-project/issues/79240 and we land the
corresponding change. So we should be able to remove the workaround now.

The original tests get remained.

Added: 
clang/test/Modules/cxx20-modules-enum-odr.cppm

Modified: 
clang/lib/AST/ODRHash.cpp

Removed: 




diff  --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp
index 5b98646a1e8dc0d..2dbc259138a897d 100644
--- a/clang/lib/AST/ODRHash.cpp
+++ b/clang/lib/AST/ODRHash.cpp
@@ -745,55 +745,8 @@ void ODRHash::AddEnumDecl(const EnumDecl *Enum) {
   if (Enum->isScoped())
 AddBoolean(Enum->isScopedUsingClassTag());
 
-  if (Enum->getIntegerTypeSourceInfo()) {
-// FIMXE: This allows two enums with 
diff erent spellings to have the same
-// hash.
-//
-//  // mod1.cppm
-//  module;
-//  extern "C" {
-//  typedef unsigned __int64 size_t;
-//  }
-//  namespace std {
-//  using :: size_t;
-//  }
-//
-//  extern "C++" {
-//  namespace std {
-//  enum class align_val_t : std::size_t {};
-//  }
-//  }
-//
-//  export module mod1;
-//  export using std::align_val_t;
-//
-//  // mod2.cppm
-//  module;
-//  extern "C" {
-//  typedef unsigned __int64 size_t;
-//  }
-//
-//  extern "C++" {
-//  namespace std {
-//  enum class align_val_t : size_t {};
-//  }
-//  }
-//
-//  export module mod2;
-//  import mod1;
-//  export using std::align_val_t;
-//
-// The above example should be disallowed since it violates
-// [basic.def.odr]p14:
-//
-//Each such definition shall consist of the same sequence of tokens
-//
-// The definitions of `std::align_val_t` in two module units have 
diff erent
-// spellings but we failed to give an error here.
-//
-// See https://github.com/llvm/llvm-project/issues/76638 for details.
+  if (Enum->getIntegerTypeSourceInfo())
 AddQualType(Enum->getIntegerType().getCanonicalType());
-  }
 
   // Filter out sub-Decls which will not be processed in order to get an
   // accurate count of Decl's.

diff  --git a/clang/test/Modules/cxx20-modules-enum-odr.cppm 
b/clang/test/Modules/cxx20-modules-enum-odr.cppm
new file mode 100644
index 000..831c01143a27ba5
--- /dev/null
+++ b/clang/test/Modules/cxx20-modules-enum-odr.cppm
@@ -0,0 +1,51 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 %t/mod1.cppm -emit-module-interface -o 
%t/mod1.pcm
+// RUN: %clang_cc1 -std=c++20 %t/mod2.cppm -emit-module-interface -o 
%t/mod2.pcm
+// RUN: %clang_cc1 -std=c++20 %t/test.cpp -fprebuilt-module-path=%t -verify 
-fsyntax-only
+
+//--- size_t.h
+
+extern "C" {
+typedef unsigned int size_t;
+}
+
+//--- csize_t
+namespace std {
+using :: size_t;
+}
+
+//--- align.h
+namespace std {
+enum class align_val_t : size_t {};
+}
+
+//--- mod1.cppm
+module;
+#include "size_t.h"
+#include "align.h"
+export module mod1;
+namespace std {
+export using std::align_val_t;
+}
+
+//--- mod2.cppm
+module;
+#include "size_t.h"
+#include "csize_t"
+#include "align.h"
+export module mod2;
+namespace std {
+export using std::align_val_t;
+}
+
+//--- test.cpp
+// expected-no-diagnostics
+import mod1;
+import mod2;
+void test() {
+std::align_val_t v;
+}
+



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


[clang] [clang-tools-extra] [llvm] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,168 @@
+//===--- UseStdMinMaxCheck.cpp - clang-tidy 
---===//
+//
+// 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 "UseStdMinMaxCheck.h"
+#include "../utils/ASTUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Preprocessor.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+static const llvm::StringRef AlgorithmHeader("");
+
+static bool minCondition(const BinaryOperator::Opcode Op, const Expr *CondLhs,
+ const Expr *CondRhs, const Expr *AssignLhs,
+ const Expr *AssignRhs, const ASTContext &Context) {
+  if ((Op == BO_LT || Op == BO_LE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context)))
+return true;
+
+  if ((Op == BO_GT || Op == BO_GE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))
+return true;
+
+  return false;
+}
+
+static bool maxCondition(const BinaryOperator::Opcode Op, const Expr *CondLhs,
+ const Expr *CondRhs, const Expr *AssignLhs,
+ const Expr *AssignRhs, const ASTContext &Context) {
+  if ((Op == BO_LT || Op == BO_LE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))
+return true;
+
+  if ((Op == BO_GT || Op == BO_GE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context)))
+return true;
+
+  return false;
+}
+
+static std::string createReplacement(const Expr *CondLhs, const Expr *CondRhs,
+ const Expr *AssignLhs,
+ const SourceManager &Source,
+ const LangOptions &LO,
+ StringRef FunctionName,
+ const BinaryOperator *BO) {
+  const llvm::StringRef CondLhsStr = Lexer::getSourceText(
+  Source.getExpansionRange(CondLhs->getSourceRange()), Source, LO);
+  const llvm::StringRef CondRhsStr = Lexer::getSourceText(
+  Source.getExpansionRange(CondRhs->getSourceRange()), Source, LO);
+  const llvm::StringRef AssignLhsStr = Lexer::getSourceText(
+  Source.getExpansionRange(AssignLhs->getSourceRange()), Source, LO);
+
+  clang::QualType GlobalImplicitCastType;
+  if (CondLhs->getType()
+  .getCanonicalType()
+  .getNonReferenceType()
+  .getUnqualifiedType() != CondRhs->getType()
+   .getCanonicalType()
+   .getNonReferenceType()
+   .getUnqualifiedType()) {

PiotrZSL wrote:

assign those 2 binary operator types to local variables, to make this shorter.

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


[clang] [llvm] [clang-tools-extra] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,168 @@
+//===--- UseStdMinMaxCheck.cpp - clang-tidy 
---===//
+//
+// 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 "UseStdMinMaxCheck.h"
+#include "../utils/ASTUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Preprocessor.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+static const llvm::StringRef AlgorithmHeader("");
+
+static bool minCondition(const BinaryOperator::Opcode Op, const Expr *CondLhs,
+ const Expr *CondRhs, const Expr *AssignLhs,
+ const Expr *AssignRhs, const ASTContext &Context) {
+  if ((Op == BO_LT || Op == BO_LE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context)))
+return true;
+
+  if ((Op == BO_GT || Op == BO_GE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))
+return true;
+
+  return false;
+}
+
+static bool maxCondition(const BinaryOperator::Opcode Op, const Expr *CondLhs,
+ const Expr *CondRhs, const Expr *AssignLhs,
+ const Expr *AssignRhs, const ASTContext &Context) {
+  if ((Op == BO_LT || Op == BO_LE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))
+return true;
+
+  if ((Op == BO_GT || Op == BO_GE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context)))
+return true;
+
+  return false;
+}
+
+static std::string createReplacement(const Expr *CondLhs, const Expr *CondRhs,
+ const Expr *AssignLhs,
+ const SourceManager &Source,
+ const LangOptions &LO,
+ StringRef FunctionName,
+ const BinaryOperator *BO) {
+  const llvm::StringRef CondLhsStr = Lexer::getSourceText(
+  Source.getExpansionRange(CondLhs->getSourceRange()), Source, LO);
+  const llvm::StringRef CondRhsStr = Lexer::getSourceText(
+  Source.getExpansionRange(CondRhs->getSourceRange()), Source, LO);
+  const llvm::StringRef AssignLhsStr = Lexer::getSourceText(
+  Source.getExpansionRange(AssignLhs->getSourceRange()), Source, LO);
+
+  clang::QualType GlobalImplicitCastType;
+  if (CondLhs->getType()
+  .getCanonicalType()
+  .getNonReferenceType()
+  .getUnqualifiedType() != CondRhs->getType()
+   .getCanonicalType()
+   .getNonReferenceType()
+   .getUnqualifiedType()) {
+GlobalImplicitCastType = BO->getLHS()->getType();
+  }
+
+  return (AssignLhsStr + " = " + FunctionName +
+  (!GlobalImplicitCastType.isNull()
+   ? "<" + GlobalImplicitCastType.getCanonicalType().getAsString() 
+
+ ">("
+   : "(") +
+  CondLhsStr + ", " + CondRhsStr + ");")
+  .str();
+}
+
+UseStdMinMaxCheck::UseStdMinMaxCheck(StringRef Name, ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+  IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+   utils::IncludeSorter::IS_LLVM),
+  areDiagsSelfContained()) {}
+
+void UseStdMinMaxCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+// Ignore if statements that are inside macros.
+AST_MATCHER(IfStmt, isIfInMacro) {
+  return Node.getIfLoc().isMacroID() || Node.getEndLoc().isMacroID();
+}
+
+// Ignore expressions that are of dependent types.
+AST_MATCHER(Expr, isExprDependentType) {
+  return Node.getType()->isDependentType();
+}

PiotrZSL wrote:

put ast matchers in anonymous namespace, just to avoid ODR issues

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


[clang-tools-extra] [llvm] [clang] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Piotr Zegar via cfe-commits

https://github.com/PiotrZSL commented:

Other thing is that reviewer should mark issues as resolved after checking with 
code, not author. Otherwise is hard to figure out what's done and what's not. 
Adding some comment like "Done" is sufficient usually unless issues are simple.

Next thing regarding your 2 comments that somehow cannot find in GitHub and 
exist only in my mail box:

1. vector size
```
  std::vector> a;
unsigned int b = a[0].size();
if(a[0].size() > b)
b = a[0].size();
```
first, you do not have a test for that, like:
```
using my_size = unsigned long long;

template
struct MyVector
{
using size_type = my_size;
size_type size() const;
};

void testVectorSizeType() {
  MyVector v;

  unsigned int value;
  if (v.size() > value)
value = v.size();

  if (value < v.size())
value = v.size();
}
```
Second, in this case check in current state work fine and will put unsigned 
long long as a type, the only problem is that unsigned long long is ugly.
```
ElaboratedType 0x55cfafb2f390 'size_type' sugar
`-TypedefType 0x55cfafb2f360 'MyVector::size_type' sugar
  |-TypeAlias 0x55cfafb2f300 'size_type'
  `-ElaboratedType 0x55cfafb2f2c0 'my_size' sugar
`-TypedefType 0x55cfafb2f290 'my_size' sugar
  |-TypeAlias 0x55cfafb2d900 'my_size'
  `-BuiltinType 0x55cfafabb710 'unsigned long long'
```
This is multi level typedef, proper solution would be to drop elaborated type 
until we get into alias that isn't template instance and isn't in template 
instance and isn't in template.. 
You can look into readability-redundant-casting how to drop some levels of 
elaborated types.  And use that instead of getCanonicalType.

2. `value1 + value2 < valuex`
You should check only that binary operator that check trigger:
```
IfStmt 0x56422decb568 
  |-BinaryOperator 0x56422decb430  'bool' '<'
  | |-ImplicitCastExpr 0x56422decb418  'unsigned int' 

  | | `-BinaryOperator 0x56422decb3c0  'int' '+'
  | |   |-ImplicitCastExpr 0x56422decb378  'int' 
  | |   | `-ImplicitCastExpr 0x56422decb360  'unsigned char' 

  | |   |   `-DeclRefExpr 0x56422decb320  'unsigned char' lvalue Var 
0x56422decb0c8 'value1' 'unsigned char'
  | |   `-ImplicitCastExpr 0x56422decb3a8  'int' 
  | | `-ImplicitCastExpr 0x56422decb390  'short' 

  | |   `-DeclRefExpr 0x56422decb340  'short' lvalue Var 
0x56422decb198 'value2' 'short'
  | `-ImplicitCastExpr 0x56422decb400  'unsigned int' 

  |   `-DeclRefExpr 0x56422decb3e0  'unsigned int' lvalue Var 
0x56422decb268 'valuex' 'unsigned int'
  `-BinaryOperator 0x56422decb548  'unsigned int' 
lvalue '='
|-DeclRefExpr 0x56422decb450  'unsigned int' lvalue Var 
0x56422decb268 'valuex' 'unsigned int'
`-ImplicitCastExpr 0x56422decb530  'unsigned int' 

  `-BinaryOperator 0x56422decb510  'int' '+'
|-ImplicitCastExpr 0x56422decb4c8  'int' 
| `-ImplicitCastExpr 0x56422decb4b0  'unsigned char' 

|   `-DeclRefExpr 0x56422decb470  'unsigned char' lvalue 
Var 0x56422decb0c8 'value1' 'unsigned char'
`-ImplicitCastExpr 0x56422decb4f8  'int' 
  `-ImplicitCastExpr 0x56422decb4e0  'short' 

`-DeclRefExpr 0x56422decb490  'short' lvalue Var 
0x56422decb198 'value2' 'short'
```
in this case we got: `unsigned char + short < unsigned int`, first part will be 
cased to `unsigned int` even if ``unsigned char + short` gives int, and that's 
fine. Current version of check handles that well, `GlobalImplicitCastType = 
BO->getLHS()->getType();` does a trick.

```

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


[llvm] [clang] [clang-tools-extra] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,168 @@
+//===--- UseStdMinMaxCheck.cpp - clang-tidy 
---===//
+//
+// 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 "UseStdMinMaxCheck.h"
+#include "../utils/ASTUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Preprocessor.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+static const llvm::StringRef AlgorithmHeader("");
+
+static bool minCondition(const BinaryOperator::Opcode Op, const Expr *CondLhs,
+ const Expr *CondRhs, const Expr *AssignLhs,
+ const Expr *AssignRhs, const ASTContext &Context) {
+  if ((Op == BO_LT || Op == BO_LE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context)))
+return true;
+
+  if ((Op == BO_GT || Op == BO_GE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))
+return true;
+
+  return false;
+}
+
+static bool maxCondition(const BinaryOperator::Opcode Op, const Expr *CondLhs,
+ const Expr *CondRhs, const Expr *AssignLhs,
+ const Expr *AssignRhs, const ASTContext &Context) {
+  if ((Op == BO_LT || Op == BO_LE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))
+return true;
+
+  if ((Op == BO_GT || Op == BO_GE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context)))
+return true;
+
+  return false;
+}
+
+static std::string createReplacement(const Expr *CondLhs, const Expr *CondRhs,
+ const Expr *AssignLhs,
+ const SourceManager &Source,
+ const LangOptions &LO,
+ StringRef FunctionName,
+ const BinaryOperator *BO) {
+  const llvm::StringRef CondLhsStr = Lexer::getSourceText(
+  Source.getExpansionRange(CondLhs->getSourceRange()), Source, LO);
+  const llvm::StringRef CondRhsStr = Lexer::getSourceText(
+  Source.getExpansionRange(CondRhs->getSourceRange()), Source, LO);
+  const llvm::StringRef AssignLhsStr = Lexer::getSourceText(
+  Source.getExpansionRange(AssignLhs->getSourceRange()), Source, LO);
+
+  clang::QualType GlobalImplicitCastType;
+  if (CondLhs->getType()
+  .getCanonicalType()
+  .getNonReferenceType()
+  .getUnqualifiedType() != CondRhs->getType()
+   .getCanonicalType()
+   .getNonReferenceType()
+   .getUnqualifiedType()) {
+GlobalImplicitCastType = BO->getLHS()->getType();
+  }
+
+  return (AssignLhsStr + " = " + FunctionName +
+  (!GlobalImplicitCastType.isNull()
+   ? "<" + GlobalImplicitCastType.getCanonicalType().getAsString() 
+
+ ">("
+   : "(") +
+  CondLhsStr + ", " + CondRhsStr + ");")
+  .str();
+}
+
+UseStdMinMaxCheck::UseStdMinMaxCheck(StringRef Name, ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+  IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+   utils::IncludeSorter::IS_LLVM),
+  areDiagsSelfContained()) {}
+
+void UseStdMinMaxCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+// Ignore if statements that are inside macros.
+AST_MATCHER(IfStmt, isIfInMacro) {
+  return Node.getIfLoc().isMacroID() || Node.getEndLoc().isMacroID();
+}
+
+// Ignore expressions that are of dependent types.
+AST_MATCHER(Expr, isExprDependentType) {
+  return Node.getType()->isDependentType();
+}
+
+void UseStdMinMaxCheck::registerMatchers(MatchFinder *Finder) {
+  auto AssignOperator =
+  binaryOperator(hasOperatorName("="), hasLHS(expr().bind("AssignLhs")),
+ hasRHS(expr().bind("AssignRhs")));
+  auto BinaryOperator =
+  binaryOperator(

PiotrZSL wrote:

check if using `unless(isTypeDependent())` don't do a trick: 
https://clang.llvm.org/docs/LibASTMatchersReference.html

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

[clang-tools-extra] [llvm] [clang] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Piotr Zegar via cfe-commits

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


[clang] [clang-format] Handle generic selections inside parentheses (PR #79785)

2024-01-28 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-format

Author: None (sstwcw)


Changes

new

```C
while (_Generic(x, //
   long: x)(x) > x) {
}
while (_Generic(x, //
   long: x)(x)) {
}
```

old

```C
while (_Generic(x, //
   long: x)(x) > x) {
}
while (_Generic(x, //
long: x)(x)) {
}
```

In the first case above, the second line previously aligned to the open 
parenthesis.  The 4 spaces did not get added by the fallback line near the end 
of getNewLineColumn because there was already some indentaton. Now the spaces 
get added explicitly.

In the second case above, without the fake parentheses, the second line did not 
respect the outer parentheses.  Because the LastSpace field did not get set 
without the fake parentheses.  Now the indentation of the outer level is used 
instead.

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


2 Files Affected:

- (modified) clang/lib/Format/ContinuationIndenter.cpp (+5-2) 
- (modified) clang/unittests/Format/FormatTest.cpp (+9) 


``diff
diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index a3eb9138b21833..a1c5a297c67c13 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -1694,8 +1694,11 @@ void 
ContinuationIndenter::moveStatePastFakeLParens(LineState &State,
 // Special case for generic selection expressions, its comma-separated
 // expressions are not aligned to the opening paren like regular calls, but
 // rather continuation-indented relative to the _Generic keyword.
-if (Previous && Previous->endsSequence(tok::l_paren, tok::kw__Generic))
-  NewParenState.Indent = CurrentState.LastSpace;
+if (Previous && Previous->endsSequence(tok::l_paren, tok::kw__Generic) &&
+State.Stack.size() >= 2) {
+  NewParenState.Indent =
+  State.Stack.end()[-2].Indent + Style.ContinuationIndentWidth;
+}
 
 if ((shouldUnindentNextOperator(Current) ||
  (Previous &&
diff --git a/clang/unittests/Format/FormatTest.cpp 
b/clang/unittests/Format/FormatTest.cpp
index e5e763edf5b5bf..c066107bebdd73 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -24111,6 +24111,15 @@ TEST_F(FormatTest, C11Generic) {
"double _Complex: dc,\n"
"long double _Complex: ldc)");
 
+  verifyFormat("while (_Generic(x, //\n"
+   "   long: x)(x) > x) {\n"
+   "}");
+  verifyFormat("while (_Generic(x, //\n"
+   "   long: x)(x)) {\n"
+   "}");
+  verifyFormat("x(_Generic(x, //\n"
+   "  long: x)(x));");
+
   FormatStyle Style = getLLVMStyle();
   Style.ColumnLimit = 40;
   verifyFormat("#define LIMIT_MAX(T)   \\\n"

``




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


[clang] [clang-format] Handle generic selections inside parentheses (PR #79785)

2024-01-28 Thread via cfe-commits

https://github.com/sstwcw created 
https://github.com/llvm/llvm-project/pull/79785

new

```C
while (_Generic(x, //
   long: x)(x) > x) {
}
while (_Generic(x, //
   long: x)(x)) {
}
```

old

```C
while (_Generic(x, //
   long: x)(x) > x) {
}
while (_Generic(x, //
long: x)(x)) {
}
```

In the first case above, the second line previously aligned to the open 
parenthesis.  The 4 spaces did not get added by the fallback line near the end 
of getNewLineColumn because there was already some indentaton. Now the spaces 
get added explicitly.

In the second case above, without the fake parentheses, the second line did not 
respect the outer parentheses.  Because the LastSpace field did not get set 
without the fake parentheses.  Now the indentation of the outer level is used 
instead.

>From bf4685e1ebbca1be7258e8fa41a0f5f90fa1e152 Mon Sep 17 00:00:00 2001
From: sstwcw 
Date: Mon, 29 Jan 2024 05:24:51 +
Subject: [PATCH] [clang-format] Handle generic selections inside parentheses

new

```C
while (_Generic(x, //
   long: x)(x) > x) {
}
while (_Generic(x, //
   long: x)(x)) {
}
```

old

```C
while (_Generic(x, //
   long: x)(x) > x) {
}
while (_Generic(x, //
long: x)(x)) {
}
```

In the first case above, the second line previously aligned to the open
parenthesis.  The 4 spaces did not get added by the fallback line near
the end of getNewLineColumn because there was already some indentaton.
Now the spaces get added explicitly.

In the second case above, without the fake parentheses, the second line
did not respect the outer parentheses.  Because the LastSpace field did
not get set without the fake parentheses.  Now the indentation of the
outer level is used instead.
---
 clang/lib/Format/ContinuationIndenter.cpp | 7 +--
 clang/unittests/Format/FormatTest.cpp | 9 +
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Format/ContinuationIndenter.cpp 
b/clang/lib/Format/ContinuationIndenter.cpp
index a3eb9138b21833..a1c5a297c67c13 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -1694,8 +1694,11 @@ void 
ContinuationIndenter::moveStatePastFakeLParens(LineState &State,
 // Special case for generic selection expressions, its comma-separated
 // expressions are not aligned to the opening paren like regular calls, but
 // rather continuation-indented relative to the _Generic keyword.
-if (Previous && Previous->endsSequence(tok::l_paren, tok::kw__Generic))
-  NewParenState.Indent = CurrentState.LastSpace;
+if (Previous && Previous->endsSequence(tok::l_paren, tok::kw__Generic) &&
+State.Stack.size() >= 2) {
+  NewParenState.Indent =
+  State.Stack.end()[-2].Indent + Style.ContinuationIndentWidth;
+}
 
 if ((shouldUnindentNextOperator(Current) ||
  (Previous &&
diff --git a/clang/unittests/Format/FormatTest.cpp 
b/clang/unittests/Format/FormatTest.cpp
index e5e763edf5b5bf..c066107bebdd73 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -24111,6 +24111,15 @@ TEST_F(FormatTest, C11Generic) {
"double _Complex: dc,\n"
"long double _Complex: ldc)");
 
+  verifyFormat("while (_Generic(x, //\n"
+   "   long: x)(x) > x) {\n"
+   "}");
+  verifyFormat("while (_Generic(x, //\n"
+   "   long: x)(x)) {\n"
+   "}");
+  verifyFormat("x(_Generic(x, //\n"
+   "  long: x)(x));");
+
   FormatStyle Style = getLLVMStyle();
   Style.ColumnLimit = 40;
   verifyFormat("#define LIMIT_MAX(T)   \\\n"

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


[clang] [OpenMP][Clang] Handle unsupported inscan modifier for generic types (PR #79431)

2024-01-28 Thread Animesh Kumar via cfe-commits

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


[clang] [OpenMP][Clang] Handle unsupported inscan modifier for generic types (PR #79431)

2024-01-28 Thread Animesh Kumar via cfe-commits


@@ -19520,6 +19520,13 @@ static bool actOnOMPReductionKindClause(
   bool FirstIter = true;
   for (Expr *RefExpr : VarList) {
 assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
+if (ClauseKind == OMPC_reduction &&
+RD.RedModifier == OMPC_REDUCTION_inscan && RefExpr->isTypeDependent()) 
{
+  S.Diag(RefExpr->getExprLoc(),
+ diag::err_omp_inscan_reduction_on_template_type);
+  continue;
+}
+

animeshk-amd wrote:

It should ideally be supported. However, the compiler crashes as per #67002 on 
the latest builds.

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


[clang] [OpenMP][Clang] Handle unsupported inscan modifier for generic types (PR #79431)

2024-01-28 Thread Animesh Kumar via cfe-commits


@@ -12,28 +12,6 @@
 
 void foo() {}
 
-template 

animeshk-amd wrote:

The test was passing because the `for` directive at line:18 is used outside a 
parallel region, in which case the compiler wasn't crashing. Contrary to what 
would happen when used within a parallel region. 
Since the `scan` directive currently doesn't support templates, within or 
without a parallel region, I transferred this test to the scan_messages.cpp 
line:87 with expected errors.

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


[clang-tools-extra] [clangd] Attempt to fix https://github.com/clangd/clangd/issues/1536 (PR #79448)

2024-01-28 Thread Tor Shepherd via cfe-commits

torshepherd wrote:

I'll close this patch and pursue the other things we discussed 

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


[clang-tools-extra] [clangd] Attempt to fix https://github.com/clangd/clangd/issues/1536 (PR #79448)

2024-01-28 Thread Tor Shepherd via cfe-commits

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


[clang] a0b6747 - [C++20] [Modules] Don't perform ODR checks in GMF

2024-01-28 Thread Chuanqi Xu via cfe-commits

Author: Chuanqi Xu
Date: 2024-01-29T11:44:59+08:00
New Revision: a0b6747804e46665ecfd00295b60432bfe1775b6

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

LOG: [C++20] [Modules] Don't perform ODR checks in GMF

Close https://github.com/llvm/llvm-project/issues/79240.

See the linked issue for details. Given the frequency of issue reporting
about false positive ODR checks (I received private issue reports too),
I'd like to backport this to 18.x too.

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
clang/include/clang/Serialization/ASTReader.h
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTReaderDecl.cpp
clang/lib/Serialization/ASTWriter.cpp
clang/lib/Serialization/ASTWriterDecl.cpp
clang/test/Modules/concept.cppm
clang/test/Modules/no-eager-load.cppm
clang/test/Modules/polluted-operator.cppm
clang/test/Modules/pr76638.cppm

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2aa8fea4ad67c0..9d68be469dac39 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -62,6 +62,11 @@ C++ Language Changes
 C++20 Feature Support
 ^
 
+- Clang won't perform ODR checks for decls in the global module fragment any
+  more to ease the implementation and improve the user's using experience.
+  This follows the MSVC's behavior.
+  (`#79240 `_).
+
 C++23 Feature Support
 ^
 

diff  --git a/clang/include/clang/Serialization/ASTReader.h 
b/clang/include/clang/Serialization/ASTReader.h
index dd1451bbf2d2c9..ba06ab0cd45097 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -2452,6 +2452,10 @@ class BitsUnpacker {
   uint32_t CurrentBitsIndex = ~0;
 };
 
+inline bool isFromExplicitGMF(const Decl *D) {
+  return D->getOwningModule() && 
D->getOwningModule()->isExplicitGlobalModule();
+}
+
 } // namespace clang
 
 #endif // LLVM_CLANG_SERIALIZATION_ASTREADER_H

diff  --git a/clang/lib/Serialization/ASTReader.cpp 
b/clang/lib/Serialization/ASTReader.cpp
index 89b044a61a7b15..2abe5e44e2e988 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -9747,6 +9747,9 @@ void ASTReader::finishPendingActions() {
 
 if (!FD->isLateTemplateParsed() &&
 !NonConstDefn->isLateTemplateParsed() &&
+// We only perform ODR checks for decls not in the explicit
+// global module fragment.
+!isFromExplicitGMF(FD) &&
 FD->getODRHash() != NonConstDefn->getODRHash()) {
   if (!isa(FD)) {
 PendingFunctionOdrMergeFailures[FD].push_back(NonConstDefn);

diff  --git a/clang/lib/Serialization/ASTReaderDecl.cpp 
b/clang/lib/Serialization/ASTReaderDecl.cpp
index 867f4c47eaeceb..29ece2a132bf8c 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -804,8 +804,10 @@ void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) {
   ED->setScopedUsingClassTag(EnumDeclBits.getNextBit());
   ED->setFixed(EnumDeclBits.getNextBit());
 
-  ED->setHasODRHash(true);
-  ED->ODRHash = Record.readInt();
+  if (!isFromExplicitGMF(ED)) {
+ED->setHasODRHash(true);
+ED->ODRHash = Record.readInt();
+  }
 
   // If this is a definition subject to the ODR, and we already have a
   // definition, merge this one into it.
@@ -827,7 +829,9 @@ void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) {
   Reader.MergedDeclContexts.insert(std::make_pair(ED, OldDef));
   ED->demoteThisDefinitionToDeclaration();
   Reader.mergeDefinitionVisibility(OldDef, ED);
-  if (OldDef->getODRHash() != ED->getODRHash())
+  // We don't want to check the ODR hash value for declarations from global
+  // module fragment.
+  if (!isFromExplicitGMF(ED) && OldDef->getODRHash() != ED->getODRHash())
 Reader.PendingEnumOdrMergeFailures[OldDef].push_back(ED);
 } else {
   OldDef = ED;
@@ -866,6 +870,9 @@ ASTDeclReader::VisitRecordDeclImpl(RecordDecl *RD) {
 
 void ASTDeclReader::VisitRecordDecl(RecordDecl *RD) {
   VisitRecordDeclImpl(RD);
+  // We should only reach here if we're in C/Objective-C. There is no
+  // global module fragment.
+  assert(!isFromExplicitGMF(RD));
   RD->setODRHash(Record.readInt());
 
   // Maintain the invariant of a redeclaration chain containing only
@@ -1094,8 +1101,10 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
   if (FD->isExplicitlyDefaulted())
 FD->setDefaultLoc(readSourceLocation());
 
-  FD->ODRHash = Record.readInt();
-  FD->setHasODRHash(true);
+  if (!isFromExplicitGMF(FD)) {
+FD->ODRHash = Record.readInt();
+FD->setHasODRHash(true);
+  }
 
   i

[clang] [llvm] [NVPTX] Add 'activemask' builtin and intrinsic support (PR #79768)

2024-01-28 Thread Joseph Huber via cfe-commits

https://github.com/jhuber6 updated 
https://github.com/llvm/llvm-project/pull/79768

>From 2c7049defef3b62de7017640948cccfb07ff756c Mon Sep 17 00:00:00 2001
From: Joseph Huber 
Date: Sun, 28 Jan 2024 14:57:05 -0600
Subject: [PATCH] [NVPTX] Add 'activemask' builtin and intrinsic support

Summary:
This patch adds support for getting the 'activemask' instruction's value
without needing to use inline assembly. See the relevant PTX reference
for details.

https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-activemask
---
 clang/include/clang/Basic/BuiltinsNVPTX.def |  8 -
 clang/test/CodeGen/builtins-nvptx.c | 16 ++---
 llvm/include/llvm/IR/IntrinsicsNVVM.td  |  8 +
 llvm/lib/Target/NVPTX/NVPTX.td  |  4 +--
 llvm/lib/Target/NVPTX/NVPTXIntrinsics.td|  6 
 llvm/test/CodeGen/NVPTX/activemask.ll   | 38 +
 6 files changed, 73 insertions(+), 7 deletions(-)
 create mode 100644 llvm/test/CodeGen/NVPTX/activemask.ll

diff --git a/clang/include/clang/Basic/BuiltinsNVPTX.def 
b/clang/include/clang/Basic/BuiltinsNVPTX.def
index 0f2e8260143be78..506288547a15822 100644
--- a/clang/include/clang/Basic/BuiltinsNVPTX.def
+++ b/clang/include/clang/Basic/BuiltinsNVPTX.def
@@ -44,6 +44,7 @@
 #pragma push_macro("PTX42")
 #pragma push_macro("PTX60")
 #pragma push_macro("PTX61")
+#pragma push_macro("PTX62")
 #pragma push_macro("PTX63")
 #pragma push_macro("PTX64")
 #pragma push_macro("PTX65")
@@ -76,7 +77,8 @@
 #define PTX65 "ptx65|" PTX70
 #define PTX64 "ptx64|" PTX65
 #define PTX63 "ptx63|" PTX64
-#define PTX61 "ptx61|" PTX63
+#define PTX62 "ptx62|" PTX63
+#define PTX61 "ptx61|" PTX62
 #define PTX60 "ptx60|" PTX61
 #define PTX42 "ptx42|" PTX60
 
@@ -632,6 +634,9 @@ TARGET_BUILTIN(__nvvm_vote_any_sync, "bUib", "", PTX60)
 TARGET_BUILTIN(__nvvm_vote_uni_sync, "bUib", "", PTX60)
 TARGET_BUILTIN(__nvvm_vote_ballot_sync, "UiUib", "", PTX60)
 
+// Mask
+TARGET_BUILTIN(__nvvm_activemask, "i", "n", PTX62)
+
 // Match
 TARGET_BUILTIN(__nvvm_match_any_sync_i32, "UiUiUi", "", AND(SM_70,PTX60))
 TARGET_BUILTIN(__nvvm_match_any_sync_i64, "UiUiWi", "", AND(SM_70,PTX60))
@@ -1065,6 +1070,7 @@ TARGET_BUILTIN(__nvvm_getctarank_shared_cluster, "iv*3", 
"", AND(SM_90,PTX78))
 #pragma pop_macro("PTX42")
 #pragma pop_macro("PTX60")
 #pragma pop_macro("PTX61")
+#pragma pop_macro("PTX62")
 #pragma pop_macro("PTX63")
 #pragma pop_macro("PTX64")
 #pragma pop_macro("PTX65")
diff --git a/clang/test/CodeGen/builtins-nvptx.c 
b/clang/test/CodeGen/builtins-nvptx.c
index 353f3ebb608c2b1..a2e73eb1d268bd1 100644
--- a/clang/test/CodeGen/builtins-nvptx.c
+++ b/clang/test/CodeGen/builtins-nvptx.c
@@ -5,16 +5,16 @@
 // RUN: %clang_cc1 -ffp-contract=off -triple nvptx64-unknown-unknown 
-target-cpu sm_80 -target-feature +ptx70 \
 // RUN:-fcuda-is-device -S -emit-llvm -o - -x cuda %s \
 // RUN:   | FileCheck -check-prefix=CHECK -check-prefix=CHECK_PTX70_SM80 
-check-prefix=LP64 %s
-// RUN: %clang_cc1 -ffp-contract=off -triple nvptx-unknown-unknown -target-cpu 
sm_60 \
+// RUN: %clang_cc1 -ffp-contract=off -triple nvptx-unknown-unknown -target-cpu 
sm_60 -target-feature +ptx62 \
 // RUN:-fcuda-is-device -S -emit-llvm -o - -x cuda %s \
 // RUN:   | FileCheck -check-prefix=CHECK -check-prefix=LP32 %s
-// RUN: %clang_cc1 -ffp-contract=off -triple nvptx64-unknown-unknown 
-target-cpu sm_60 \
+// RUN: %clang_cc1 -ffp-contract=off -triple nvptx64-unknown-unknown 
-target-cpu sm_60 -target-feature +ptx62 \
 // RUN:-fcuda-is-device -S -emit-llvm -o - -x cuda %s \
 // RUN:   | FileCheck -check-prefix=CHECK -check-prefix=LP64 %s
-// RUN: %clang_cc1 -ffp-contract=off -triple nvptx64-unknown-unknown 
-target-cpu sm_61 \
+// RUN: %clang_cc1 -ffp-contract=off -triple nvptx64-unknown-unknown 
-target-cpu sm_61 -target-feature +ptx62 \
 // RUN:-fcuda-is-device -S -emit-llvm -o - -x cuda %s \
 // RUN:   | FileCheck -check-prefix=CHECK -check-prefix=LP64 %s
-// RUN: %clang_cc1 -triple nvptx-unknown-unknown -target-cpu sm_53 \
+// RUN: %clang_cc1 -triple nvptx-unknown-unknown -target-cpu sm_53 
-target-feature +ptx62 \
 // RUN:   -DERROR_CHECK -fcuda-is-device -S -o /dev/null -x cuda -verify %s
 // RUN: %clang_cc1 -ffp-contract=off -triple nvptx-unknown-unknown -target-cpu 
sm_86 -target-feature +ptx72 \
 // RUN:-fcuda-is-device -S -emit-llvm -o - -x cuda %s \
@@ -165,6 +165,14 @@ __device__ void sync() {
 
 }
 
+__device__ void activemask() {
+
+// CHECK: call i32 @llvm.nvvm.activemask()
+
+  __nvvm_activemask();
+
+}
+
 
 // NVVM intrinsics
 
diff --git a/llvm/include/llvm/IR/IntrinsicsNVVM.td 
b/llvm/include/llvm/IR/IntrinsicsNVVM.td
index 5a5ba2592e1467e..0640fb1f74aa5eb 100644
--- a/llvm/include/llvm/IR/IntrinsicsNVVM.td
+++ b/llvm/include/llvm/IR/IntrinsicsNVVM.td
@@ -4599,6 +4599,14 @@ def int_nvvm_vote_ballot_sync :
 [IntrInaccessibleMemOnly, IntrConvergent, IntrNoCallback],

[clang] [llvm] [NVPTX} Add builtin support for 'globaltimer' (PR #79765)

2024-01-28 Thread Joseph Huber via cfe-commits

https://github.com/jhuber6 updated 
https://github.com/llvm/llvm-project/pull/79765

>From cb2503ee6c10a3d03548b6bd44d6800ed67b2753 Mon Sep 17 00:00:00 2001
From: Joseph Huber 
Date: Mon, 29 Jan 2024 08:12:35 -0600
Subject: [PATCH] [NVPTX} Add builtin support for 'globaltimer'

Summary:
This patch adds support for `globaltimer` to match `clock` and
`clock64`. See the PTX ISA reference fro details. This patch does not
implement the `hi` or `lo` variants for brevity as they can be obtained
from this with the cost of an additional register.
https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#special-registers-globaltimer-globaltimer-lo-globaltimer-hi
---
 clang/include/clang/Basic/BuiltinsNVPTX.def |  1 +
 clang/test/CodeGen/builtins-nvptx.c |  4 +++-
 llvm/include/llvm/IR/IntrinsicsNVVM.td  |  2 ++
 llvm/lib/Target/NVPTX/NVPTXIntrinsics.td|  2 ++
 llvm/test/CodeGen/NVPTX/intrinsics.ll   | 12 
 5 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Basic/BuiltinsNVPTX.def 
b/clang/include/clang/Basic/BuiltinsNVPTX.def
index 0f2e8260143be78..57a229ded49f886 100644
--- a/clang/include/clang/Basic/BuiltinsNVPTX.def
+++ b/clang/include/clang/Basic/BuiltinsNVPTX.def
@@ -146,6 +146,7 @@ BUILTIN(__nvvm_read_ptx_sreg_lanemask_gt, "i", "nc")
 
 BUILTIN(__nvvm_read_ptx_sreg_clock, "i", "n")
 BUILTIN(__nvvm_read_ptx_sreg_clock64, "LLi", "n")
+BUILTIN(__nvvm_read_ptx_sreg_globaltimer, "LLi", "n")
 
 BUILTIN(__nvvm_read_ptx_sreg_pm0, "i", "n")
 BUILTIN(__nvvm_read_ptx_sreg_pm1, "i", "n")
diff --git a/clang/test/CodeGen/builtins-nvptx.c 
b/clang/test/CodeGen/builtins-nvptx.c
index 353f3ebb608c2b1..5aab6bee5b1cc1d 100644
--- a/clang/test/CodeGen/builtins-nvptx.c
+++ b/clang/test/CodeGen/builtins-nvptx.c
@@ -134,11 +134,13 @@ __device__ long long read_clocks() {
 
 // CHECK: call i32 @llvm.nvvm.read.ptx.sreg.clock()
 // CHECK: call i64 @llvm.nvvm.read.ptx.sreg.clock64()
+// CHECK: call i64 @llvm.nvvm.read.ptx.sreg.globaltimer()
 
   int a = __nvvm_read_ptx_sreg_clock();
   long long b = __nvvm_read_ptx_sreg_clock64();
+  long long c = __nvvm_read_ptx_sreg_globaltimer();
 
-  return a + b;
+  return a + b + c;
 }
 
 __device__ int read_pms() {
diff --git a/llvm/include/llvm/IR/IntrinsicsNVVM.td 
b/llvm/include/llvm/IR/IntrinsicsNVVM.td
index 5a5ba2592e1467e..8c9ed4a349ba998 100644
--- a/llvm/include/llvm/IR/IntrinsicsNVVM.td
+++ b/llvm/include/llvm/IR/IntrinsicsNVVM.td
@@ -4506,6 +4506,8 @@ def int_nvvm_read_ptx_sreg_lanemask_gt :
 def int_nvvm_read_ptx_sreg_clock : PTXReadNCSRegIntrinsic_r32<"clock">;
 def int_nvvm_read_ptx_sreg_clock64 : PTXReadNCSRegIntrinsic_r64<"clock64">;
 
+def int_nvvm_read_ptx_sreg_globaltimer : 
PTXReadNCSRegIntrinsic_r64<"globaltimer">;
+
 def int_nvvm_read_ptx_sreg_pm0 : PTXReadNCSRegIntrinsic_r32<"pm0">;
 def int_nvvm_read_ptx_sreg_pm1 : PTXReadNCSRegIntrinsic_r32<"pm1">;
 def int_nvvm_read_ptx_sreg_pm2 : PTXReadNCSRegIntrinsic_r32<"pm2">;
diff --git a/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td 
b/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td
index 33f1e4a43e072af..5c509b50411701a 100644
--- a/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td
+++ b/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td
@@ -6364,6 +6364,8 @@ def INT_PTX_SREG_CLOCK :
 PTX_READ_SREG_R32<"clock", int_nvvm_read_ptx_sreg_clock>;
 def INT_PTX_SREG_CLOCK64 :
 PTX_READ_SREG_R64<"clock64", int_nvvm_read_ptx_sreg_clock64>;
+def INT_PTX_SREG_GLOBALTIMER :
+PTX_READ_SREG_R64<"globaltimer", int_nvvm_read_ptx_sreg_globaltimer>;
 
 def INT_PTX_SREG_PM0 : PTX_READ_SREG_R32<"pm0", int_nvvm_read_ptx_sreg_pm0>;
 def INT_PTX_SREG_PM1 : PTX_READ_SREG_R32<"pm1", int_nvvm_read_ptx_sreg_pm1>;
diff --git a/llvm/test/CodeGen/NVPTX/intrinsics.ll 
b/llvm/test/CodeGen/NVPTX/intrinsics.ll
index c09c7a72fd10181..26900543d922ba3 100644
--- a/llvm/test/CodeGen/NVPTX/intrinsics.ll
+++ b/llvm/test/CodeGen/NVPTX/intrinsics.ll
@@ -133,6 +133,17 @@ define i64 @test_clock64() {
   ret i64 %ret
 }
 
+; CHECK-LABEL: test_globaltimer
+define i64 @test_globaltimer() {
+; CHECK: mov.u64 %r{{.*}}, %globaltimer;
+  %a = tail call i64 @llvm.nvvm.read.ptx.sreg.globaltimer()
+; CHECK: mov.u64 %r{{.*}}, %globaltimer;
+  %b = tail call i64 @llvm.nvvm.read.ptx.sreg.globaltimer()
+  %ret = add i64 %a, %b
+; CHECK: ret
+  ret i64 %ret
+}
+
 declare float @llvm.fabs.f32(float)
 declare double @llvm.fabs.f64(double)
 declare float @llvm.nvvm.sqrt.f(float)
@@ -146,3 +157,4 @@ declare i64 @llvm.ctpop.i64(i64)
 declare i32 @llvm.nvvm.read.ptx.sreg.tid.x()
 declare i32 @llvm.nvvm.read.ptx.sreg.clock()
 declare i64 @llvm.nvvm.read.ptx.sreg.clock64()
+declare i64 @llvm.nvvm.read.ptx.sreg.globaltimer()

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


[clang] [llvm] [NVPTX] Add builtin for 'exit' handling (PR #79777)

2024-01-28 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-llvm-ir

@llvm/pr-subscribers-clang

Author: Joseph Huber (jhuber6)


Changes

Summary:
The PTX ISA has always supported the 'exit' instruction to terminate
individual threads. This patch adds a builtin to handle it. See the PTX
documentation for further details.
https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-exit


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


5 Files Affected:

- (modified) clang/include/clang/Basic/BuiltinsNVPTX.def (+1) 
- (modified) clang/test/CodeGen/builtins-nvptx.c (+8) 
- (modified) llvm/include/llvm/IR/IntrinsicsNVVM.td (+4) 
- (modified) llvm/lib/Target/NVPTX/NVPTXIntrinsics.td (+3) 
- (modified) llvm/test/CodeGen/NVPTX/intrinsics.ll (+8) 


``diff
diff --git a/clang/include/clang/Basic/BuiltinsNVPTX.def 
b/clang/include/clang/Basic/BuiltinsNVPTX.def
index 0f2e8260143be78..1ae23a32c2adcf0 100644
--- a/clang/include/clang/Basic/BuiltinsNVPTX.def
+++ b/clang/include/clang/Basic/BuiltinsNVPTX.def
@@ -155,6 +155,7 @@ BUILTIN(__nvvm_read_ptx_sreg_pm3, "i", "n")
 // MISC
 
 BUILTIN(__nvvm_prmt, "UiUiUiUi", "")
+BUILTIN(__nvvm_exit, "v", "r")
 
 // Min Max
 
diff --git a/clang/test/CodeGen/builtins-nvptx.c 
b/clang/test/CodeGen/builtins-nvptx.c
index 353f3ebb608c2b1..0a19e40a01aedb1 100644
--- a/clang/test/CodeGen/builtins-nvptx.c
+++ b/clang/test/CodeGen/builtins-nvptx.c
@@ -165,6 +165,14 @@ __device__ void sync() {
 
 }
 
+__device__ void exit() {
+
+// CHECK: call void @llvm.nvvm.exit()
+
+  __nvvm_exit();
+
+}
+
 
 // NVVM intrinsics
 
diff --git a/llvm/include/llvm/IR/IntrinsicsNVVM.td 
b/llvm/include/llvm/IR/IntrinsicsNVVM.td
index 5a5ba2592e1467e..b751ffa27e0203d 100644
--- a/llvm/include/llvm/IR/IntrinsicsNVVM.td
+++ b/llvm/include/llvm/IR/IntrinsicsNVVM.td
@@ -4801,4 +4801,8 @@ def int_nvvm_setmaxnreg_dec_sync_aligned_u32
   [IntrConvergent, IntrNoMem, IntrHasSideEffects, 
ImmArg>],
   "llvm.nvvm.setmaxnreg.dec.sync.aligned.u32">;
 
+// Exit
+def int_nvvm_exit : ClangBuiltin<"__nvvm_exit">,
+Intrinsic<[], [], [IntrConvergent, IntrInaccessibleMemOnly, IntrNoReturn]>;
+
 } // let TargetPrefix = "nvvm"
diff --git a/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td 
b/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td
index 33f1e4a43e072af..0db351a33f2a6d5 100644
--- a/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td
+++ b/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td
@@ -6832,4 +6832,7 @@ multiclass SET_MAXNREG {
 
 defm INT_SET_MAXNREG_INC : SET_MAXNREG<"inc", 
int_nvvm_setmaxnreg_inc_sync_aligned_u32>;
 defm INT_SET_MAXNREG_DEC : SET_MAXNREG<"dec", 
int_nvvm_setmaxnreg_dec_sync_aligned_u32>;
+
 } // isConvergent
+
+def INT_EXIT : NVPTXInst<(outs), (ins), "exit;", [(int_nvvm_exit)]>;
diff --git a/llvm/test/CodeGen/NVPTX/intrinsics.ll 
b/llvm/test/CodeGen/NVPTX/intrinsics.ll
index c09c7a72fd10181..4b7d5c8f2390769 100644
--- a/llvm/test/CodeGen/NVPTX/intrinsics.ll
+++ b/llvm/test/CodeGen/NVPTX/intrinsics.ll
@@ -133,6 +133,13 @@ define i64 @test_clock64() {
   ret i64 %ret
 }
 
+; CHECK-LABEL: test_exit
+define void @test_exit() {
+; CHECK: exit;
+  call void @llvm.nvvm.exit()
+  ret void
+}
+
 declare float @llvm.fabs.f32(float)
 declare double @llvm.fabs.f64(double)
 declare float @llvm.nvvm.sqrt.f(float)
@@ -146,3 +153,4 @@ declare i64 @llvm.ctpop.i64(i64)
 declare i32 @llvm.nvvm.read.ptx.sreg.tid.x()
 declare i32 @llvm.nvvm.read.ptx.sreg.clock()
 declare i64 @llvm.nvvm.read.ptx.sreg.clock64()
+declare void @llvm.nvvm.exit()

``




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


[llvm] [clang] [NVPTX] Add builtin for 'exit' handling (PR #79777)

2024-01-28 Thread Joseph Huber via cfe-commits

https://github.com/jhuber6 created 
https://github.com/llvm/llvm-project/pull/79777

Summary:
The PTX ISA has always supported the 'exit' instruction to terminate
individual threads. This patch adds a builtin to handle it. See the PTX
documentation for further details.
https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-exit


>From 3586acbc3eeb793ab3159c585071bdc8c54da672 Mon Sep 17 00:00:00 2001
From: Joseph Huber 
Date: Sun, 28 Jan 2024 21:27:37 -0600
Subject: [PATCH] [NVPTX] Add builtin for 'exit' handling

Summary:
The PTX ISA has always supported the 'exit' instruction to terminate
individual threads. This patch adds a builtin to handle it. See the PTX
documentation for further details.
https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-exit
---
 clang/include/clang/Basic/BuiltinsNVPTX.def | 1 +
 clang/test/CodeGen/builtins-nvptx.c | 8 
 llvm/include/llvm/IR/IntrinsicsNVVM.td  | 4 
 llvm/lib/Target/NVPTX/NVPTXIntrinsics.td| 3 +++
 llvm/test/CodeGen/NVPTX/intrinsics.ll   | 8 
 5 files changed, 24 insertions(+)

diff --git a/clang/include/clang/Basic/BuiltinsNVPTX.def 
b/clang/include/clang/Basic/BuiltinsNVPTX.def
index 0f2e8260143be78..1ae23a32c2adcf0 100644
--- a/clang/include/clang/Basic/BuiltinsNVPTX.def
+++ b/clang/include/clang/Basic/BuiltinsNVPTX.def
@@ -155,6 +155,7 @@ BUILTIN(__nvvm_read_ptx_sreg_pm3, "i", "n")
 // MISC
 
 BUILTIN(__nvvm_prmt, "UiUiUiUi", "")
+BUILTIN(__nvvm_exit, "v", "r")
 
 // Min Max
 
diff --git a/clang/test/CodeGen/builtins-nvptx.c 
b/clang/test/CodeGen/builtins-nvptx.c
index 353f3ebb608c2b1..0a19e40a01aedb1 100644
--- a/clang/test/CodeGen/builtins-nvptx.c
+++ b/clang/test/CodeGen/builtins-nvptx.c
@@ -165,6 +165,14 @@ __device__ void sync() {
 
 }
 
+__device__ void exit() {
+
+// CHECK: call void @llvm.nvvm.exit()
+
+  __nvvm_exit();
+
+}
+
 
 // NVVM intrinsics
 
diff --git a/llvm/include/llvm/IR/IntrinsicsNVVM.td 
b/llvm/include/llvm/IR/IntrinsicsNVVM.td
index 5a5ba2592e1467e..b751ffa27e0203d 100644
--- a/llvm/include/llvm/IR/IntrinsicsNVVM.td
+++ b/llvm/include/llvm/IR/IntrinsicsNVVM.td
@@ -4801,4 +4801,8 @@ def int_nvvm_setmaxnreg_dec_sync_aligned_u32
   [IntrConvergent, IntrNoMem, IntrHasSideEffects, 
ImmArg>],
   "llvm.nvvm.setmaxnreg.dec.sync.aligned.u32">;
 
+// Exit
+def int_nvvm_exit : ClangBuiltin<"__nvvm_exit">,
+Intrinsic<[], [], [IntrConvergent, IntrInaccessibleMemOnly, IntrNoReturn]>;
+
 } // let TargetPrefix = "nvvm"
diff --git a/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td 
b/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td
index 33f1e4a43e072af..0db351a33f2a6d5 100644
--- a/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td
+++ b/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td
@@ -6832,4 +6832,7 @@ multiclass SET_MAXNREG {
 
 defm INT_SET_MAXNREG_INC : SET_MAXNREG<"inc", 
int_nvvm_setmaxnreg_inc_sync_aligned_u32>;
 defm INT_SET_MAXNREG_DEC : SET_MAXNREG<"dec", 
int_nvvm_setmaxnreg_dec_sync_aligned_u32>;
+
 } // isConvergent
+
+def INT_EXIT : NVPTXInst<(outs), (ins), "exit;", [(int_nvvm_exit)]>;
diff --git a/llvm/test/CodeGen/NVPTX/intrinsics.ll 
b/llvm/test/CodeGen/NVPTX/intrinsics.ll
index c09c7a72fd10181..4b7d5c8f2390769 100644
--- a/llvm/test/CodeGen/NVPTX/intrinsics.ll
+++ b/llvm/test/CodeGen/NVPTX/intrinsics.ll
@@ -133,6 +133,13 @@ define i64 @test_clock64() {
   ret i64 %ret
 }
 
+; CHECK-LABEL: test_exit
+define void @test_exit() {
+; CHECK: exit;
+  call void @llvm.nvvm.exit()
+  ret void
+}
+
 declare float @llvm.fabs.f32(float)
 declare double @llvm.fabs.f64(double)
 declare float @llvm.nvvm.sqrt.f(float)
@@ -146,3 +153,4 @@ declare i64 @llvm.ctpop.i64(i64)
 declare i32 @llvm.nvvm.read.ptx.sreg.tid.x()
 declare i32 @llvm.nvvm.read.ptx.sreg.clock()
 declare i64 @llvm.nvvm.read.ptx.sreg.clock64()
+declare void @llvm.nvvm.exit()

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


[clang] [CLANG][NFC] Modify test cases to suit assigned default sysroot path (PR #77075)

2024-01-28 Thread via cfe-commits

Yunzezhu94 wrote:

Gentle Ping.

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


[clang-tools-extra] [clangd] Fix is spelled in source bug (PR #76668)

2024-01-28 Thread Nathan Ridge via cfe-commits

HighCommander4 wrote:

> (A drive-by comment: I stumbled on the commit message of this PR and found it 
> surprising that I'm the co-author of it! I'm not entirely clear on GitHub's 
> schemas, but IMO shouldn't the co-author be the one who clicks the "merge" 
> button?)

The reason is that one of the four commits that were squashed had you as a 
co-author:

![image](https://github.com/llvm/llvm-project/assets/1751085/1d228d15-0c16-4e54-bb86-84bfdeed342e)

(I'm not sure how that happened in the first place.)

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


[clang-tools-extra] [clangd] Fix is spelled in source bug (PR #76668)

2024-01-28 Thread Younan Zhang via cfe-commits

zyn0217 wrote:

(A drive-by comment: I stumbled on the commit message of this PR and found it 
surprising that I'm the co-author of it! I'm not entirely clear on GitHub's 
schemas, but IMO shouldn't the co-author be the one who clicks the "merge" 
button?)

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


[clang] a3f379e - [Frontend] Use StringRef::consume_back (NFC)

2024-01-28 Thread Kazu Hirata via cfe-commits

Author: Kazu Hirata
Date: 2024-01-28T18:03:33-08:00
New Revision: a3f379e4e9db9d88265e6dfc464fc3a5be3ae315

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

LOG: [Frontend] Use StringRef::consume_back (NFC)

Added: 


Modified: 
clang/lib/Frontend/VerifyDiagnosticConsumer.cpp

Removed: 




diff  --git a/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp 
b/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp
index f508408ba7062c3..304935a0a90b8e9 100644
--- a/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp
+++ b/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp
@@ -445,10 +445,9 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, 
SourceManager &SM,
 // others.
 
 // Regex in initial directive token: -re
-if (DToken.ends_with("-re")) {
+if (DToken.consume_back("-re")) {
   D.RegexKind = true;
   KindStr = "regex";
-  DToken = DToken.substr(0, DToken.size()-3);
 }
 
 // Type in initial directive token: -{error|warning|note|no-diagnostics}



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


[clang] [clang-scan-deps] Fix check for empty `Compilation` (PR #75545)

2024-01-28 Thread Chuanqi Xu via cfe-commits

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


[clang] [clang-scan-deps] Fix check for empty `Compilation` (PR #75545)

2024-01-28 Thread Chuanqi Xu via cfe-commits


@@ -728,7 +728,7 @@ getCompilationDataBase(int argc, char **argv, std::string 
&ErrorMessage) {
*Diags);
   std::unique_ptr C(
   TheDriver.BuildCompilation(CommandLine));
-  if (!C)
+  if (C->getJobs().empty())

ChuanqiXu9 wrote:

```suggestion
  if (!C || C->getJobs().empty())
```

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


[clang] [clang-scan-deps] Fix check for empty `Compilation` (PR #75545)

2024-01-28 Thread Chuanqi Xu via cfe-commits

https://github.com/ChuanqiXu9 commented:

It will be better to have a test for this.

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


[flang] [mlir] [lldb] [libcxxabi] [llvm] [clang-tools-extra] [libcxx] [libc] [clang] [lld] [compiler-rt] [mlir][complex] Prevent underflow in complex.abs (PR #76316)

2024-01-28 Thread Kai Sasaki via cfe-commits

Lewuathe wrote:

@joker-eph Oh, sorry for bothering you. I'll check what's going on.

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


[clang] [llvm] [clang-tools-extra] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Bhuminjay Soni via cfe-commits


@@ -0,0 +1,240 @@
+//===--- UseStdMinMaxCheck.cpp - clang-tidy 
---===//
+//
+// 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 "UseStdMinMaxCheck.h"
+#include "../utils/ASTUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Preprocessor.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+static bool isImplicitCastType(const clang::CastKind castKind) {

11happy wrote:

Thanks a lot for your guidnace, It was so simple I made it so complex,

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


[clang-tools-extra] [clangd] Attempt to fix https://github.com/clangd/clangd/issues/1536 (PR #79448)

2024-01-28 Thread Nathan Ridge via cfe-commits

HighCommander4 wrote:

I read up on this a bit; https://github.com/Microsoft/vscode/issues/62110 seems 
particularly relevant.

Based on [this 
comment](https://github.com/Microsoft/vscode/issues/62110#issuecomment-456240329):

> [...] we have an `auto fix` action in the editor that fixes individual errors

it seems that I did misunderstand the purpose of the "Auto fix" command in 
vscode; it looks like it's only intended to fix a single a error.

The proposal in that thread (which has since been implemented in vscode) does 
include a way to apply all quick-fixes in a file: it's the `"source.fixAll"` 
protocol described in https://github.com/clangd/clangd/issues/1446. It doesn't 
have to be invoked automatically on file-save, it can be invoked manually via a 
command (which in vscode is called "Fix all", and seems to only be enabled if 
the server advertises support for `"source.fixAll"`).

Conclusion: there's probably not much point proceeding with this patch (the 
slight behaviour change described in the previous comment doesn't seem very 
helpful), but instead we should fix 
https://github.com/clangd/clangd/issues/1446 and then the desired scenario 
should work using the "Fix all" command (and as an added bonus, there is no 
need to select the entire file contents, "Fix all" automatically applies to the 
whole file).

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


[llvm] [clang] [RISCV] Add experimental support of Zaamo and Zalrsc (PR #77424)

2024-01-28 Thread Ved Shanbhogue via cfe-commits

ved-rivos wrote:

> > > I guess Zaamo + Zacas is technically a way one could implement atomics 
> > > without LR/SC?
> > 
> > 
> > The Zacas extension depends upon the A extension.
> 
> I filed an issue asking about that 
> [riscv/riscv-zaamo-zalrsc#5](https://github.com/riscv/riscv-zaamo-zalrsc/issues/5)

The spec now clarifies that with Zaamo, Zacas depends on Zaamo.

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


[clang-tools-extra] [llvm] [clang] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Bhuminjay Soni via cfe-commits

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


[clang] [llvm] [clang-tools-extra] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Bhuminjay Soni via cfe-commits

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


[clang] [llvm] [clang-tools-extra] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Bhuminjay Soni via cfe-commits

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


[clang] [llvm] [clang-tools-extra] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Bhuminjay Soni via cfe-commits

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


[clang] [llvm] [clang-tools-extra] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Bhuminjay Soni via cfe-commits


@@ -0,0 +1,240 @@
+//===--- UseStdMinMaxCheck.cpp - clang-tidy 
---===//
+//
+// 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 "UseStdMinMaxCheck.h"
+#include "../utils/ASTUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Preprocessor.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+static bool isImplicitCastType(const clang::CastKind castKind) {
+  switch (castKind) {
+  case clang::CK_CPointerToObjCPointerCast:
+  case clang::CK_BlockPointerToObjCPointerCast:
+  case clang::CK_BitCast:
+  case clang::CK_AnyPointerToBlockPointerCast:
+  case clang::CK_NullToMemberPointer:
+  case clang::CK_NullToPointer:
+  case clang::CK_IntegralToPointer:
+  case clang::CK_PointerToIntegral:
+  case clang::CK_IntegralCast:
+  case clang::CK_BooleanToSignedIntegral:
+  case clang::CK_IntegralToFloating:
+  case clang::CK_FloatingToIntegral:
+  case clang::CK_FloatingCast:
+  case clang::CK_ObjCObjectLValueCast:
+  case clang::CK_FloatingRealToComplex:
+  case clang::CK_FloatingComplexToReal:
+  case clang::CK_FloatingComplexCast:
+  case clang::CK_FloatingComplexToIntegralComplex:
+  case clang::CK_IntegralRealToComplex:
+  case clang::CK_IntegralComplexToReal:
+  case clang::CK_IntegralComplexCast:
+  case clang::CK_IntegralComplexToFloatingComplex:
+  case clang::CK_FloatingToFixedPoint:
+  case clang::CK_FixedPointToFloating:
+  case clang::CK_FixedPointCast:
+  case clang::CK_FixedPointToIntegral:
+  case clang::CK_IntegralToFixedPoint:
+  case clang::CK_MatrixCast:
+  case clang::CK_PointerToBoolean:
+  case clang::CK_IntegralToBoolean:
+  case clang::CK_FloatingToBoolean:
+  case clang::CK_MemberPointerToBoolean:
+  case clang::CK_FloatingComplexToBoolean:
+  case clang::CK_IntegralComplexToBoolean:
+  case clang::CK_UserDefinedConversion:
+return true;
+  default:
+return false;
+  }
+}
+
+class ExprVisitor : public clang::RecursiveASTVisitor {

11happy wrote:

I am not sure how to proceed further with this , could you please guide me or 
tell somewhere its been implemented in easy way,
also reason why I choose this method:
in my initial experment I tried changing the matchers and traversing the binary 
operator via `TK_AsIs` method was able to get some simple implicit cast types 
but it was getting to specific
just as simple example where that was not working:
```
if(value1 + value2 < valuex) // basically more that 1 declarations on either 
lhs/rhs
```


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


[clang] [llvm] [clang-tools-extra] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Bhuminjay Soni via cfe-commits


@@ -0,0 +1,240 @@
+//===--- UseStdMinMaxCheck.cpp - clang-tidy 
---===//
+//
+// 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 "UseStdMinMaxCheck.h"
+#include "../utils/ASTUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Preprocessor.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+static bool isImplicitCastType(const clang::CastKind castKind) {

11happy wrote:

this is to filter out some unnecessary Implicitcast types:
example:
```
class Foo{};

int main()
{
  std::vector> a;
unsigned int b = a[0].size();
if(a[0].size() > b)
b = a[0].size();
  return 0 ;
  
}

```


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


[clang] [Clang][Sema] fix deducing auto& from const int in template parameters is impossible in partial specializations (PR #79733)

2024-01-28 Thread Qizhi Hu via cfe-commits

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


[clang] c34aa78 - [Clang][Sema] fix deducing auto& from const int in template parameters is impossible in partial specializations (#79733)

2024-01-28 Thread via cfe-commits

Author: Qizhi Hu
Date: 2024-01-29T06:42:52+08:00
New Revision: c34aa784f8867517315d8ef32a8038ee9dbb7165

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

LOG: [Clang][Sema] fix deducing auto& from const int in template parameters is 
impossible in partial specializations (#79733)

Fix [issue](https://github.com/llvm/llvm-project/issues/77189)
AutoType is possible cv qualified.

Co-authored-by: huqizhi <836744...@qq.com>

Added: 
clang/test/SemaTemplate/PR77189.cpp

Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaTemplateDeduction.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 254e0a9cb72979d..2aa8fea4ad67c02 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -130,6 +130,9 @@ Bug Fixes to C++ Support
 - Fixed a bug where variables referenced by requires-clauses inside
   nested generic lambdas were not properly injected into the constraint scope.
   (`#73418 `_)
+- Fixed deducing auto& from const int in template parameters of partial
+  specializations.
+  (`#77189 `_)
 
 Bug Fixes to AST Handling
 ^

diff  --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 25e58f7bdd953d1..f08577febcd3e80 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -649,6 +649,7 @@ static bool IsPossiblyOpaquelyQualifiedTypeInternal(const 
Type *T) {
   case Type::PackIndexing:
   case Type::UnresolvedUsing:
   case Type::TemplateTypeParm:
+  case Type::Auto:
 return true;
 
   case Type::ConstantArray:

diff  --git a/clang/test/SemaTemplate/PR77189.cpp 
b/clang/test/SemaTemplate/PR77189.cpp
new file mode 100644
index 000..1e9cc7984163c06
--- /dev/null
+++ b/clang/test/SemaTemplate/PR77189.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
+// expected-no-diagnostics
+
+struct false_type {
+   static constexpr bool value = false;
+};
+
+struct true_type {
+   static constexpr bool value = true;
+};
+
+template 
+struct test : false_type {};
+
+template 
+struct test : true_type {};
+
+int main() {
+static constexpr int v = 42;
+static_assert(test::value);
+}



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


[polly] [clang] [clang-format] Add AllowShortType option for AlwaysBreakAfterReturnType. (PR #78011)

2024-01-28 Thread Owen Pan via cfe-commits


@@ -587,7 +590,7 @@ bool ContinuationIndenter::mustBreak(const LineState 
&State) {
   !State.Line->ReturnTypeWrapped &&
   // Don't break before a C# function when no break after return type.
   (!Style.isCSharp() ||
-   Style.AlwaysBreakAfterReturnType != FormatStyle::RTBS_None) &&
+   Style.AlwaysBreakAfterReturnType > FormatStyle::RTBS_AllowShortType) &&

owenca wrote:

What I suggested is more consistent with the existing code in clang-format. 
Also, explicitly including/excluding every enum value is cumbersome and doesn't 
provide any real advantage, IMO.

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


[polly] [clang] [clang-format] Add AllowShortType option for AlwaysBreakAfterReturnType. (PR #78011)

2024-01-28 Thread Owen Pan via cfe-commits

owenca wrote:

> @mydeveloperday @HazardyKnusperkeks @rymiel this patch fixes a very old bug 
> and will cause behavior changes whether the default is changed to the new 
> `AllowShortType` or left at `None`. Which way should we go?

Now I'm leaning toward keeping the existing (buggy) behavior of `None` and 
using the new `AllowShortType` to allow wrapping after short return types.

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


[polly] [clang] [clang-format] Add AllowShortType option for AlwaysBreakAfterReturnType. (PR #78011)

2024-01-28 Thread Owen Pan via cfe-commits

owenca wrote:

> What would change if the default was kept at `None`? I don't see it.

See https://github.com/llvm/llvm-project/pull/78011#issuecomment-1913052884.

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


[clang] [clang] Improved isSimpleTypeSpecifier (PR #79037)

2024-01-28 Thread Owen Pan via cfe-commits

owenca wrote:

LGTM, but please rebase and resolve conflicts.

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


[clang] Fix analyzer crash on 'StructuralValue' (PR #79764)

2024-01-28 Thread via cfe-commits

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

Thanks!

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


[clang] [clang-tools-extra] [llvm] [LV] Improve AnyOf reduction codegen. (PR #78304)

2024-01-28 Thread Florian Hahn via cfe-commits

https://github.com/fhahn updated https://github.com/llvm/llvm-project/pull/78304

>From 9846f970b6b394ccc3af25b92f238377a8ae7807 Mon Sep 17 00:00:00 2001
From: Florian Hahn 
Date: Sun, 14 Jan 2024 18:06:36 +
Subject: [PATCH] [LV] Improve AnyOf reduction codegen.

Update AnyOf reduction code generation to only keep track of the AnyOf
property in a boolean vector in the loop, only selecting either the new
or start value in the middle block.

This fixes the #62565, as now there aren't multiple uses of the
start/new values.

Fixes https://github.com/llvm/llvm-project/issues/62565
---
 .../include/llvm/Transforms/Utils/LoopUtils.h |   9 --
 llvm/lib/Transforms/Utils/LoopUtils.cpp   |  24 +--
 .../Vectorize/LoopVectorizationPlanner.h  |   1 +
 .../Transforms/Vectorize/LoopVectorize.cpp|  44 +-
 .../lib/Transforms/Vectorize/VPlanRecipes.cpp |   7 +-
 .../LoopVectorize/AArch64/sve-select-cmp.ll   |  38 ++---
 .../RISCV/select-cmp-reduction.ll | 120 ++
 .../LoopVectorize/select-cmp-predicated.ll|  29 ++--
 .../Transforms/LoopVectorize/select-cmp.ll| 146 +-
 ...tion-start-value-may-be-undef-or-poison.ll |  43 +++---
 10 files changed, 218 insertions(+), 243 deletions(-)

diff --git a/llvm/include/llvm/Transforms/Utils/LoopUtils.h 
b/llvm/include/llvm/Transforms/Utils/LoopUtils.h
index 5a1385d01d8e44d..3bad7b616d9d756 100644
--- a/llvm/include/llvm/Transforms/Utils/LoopUtils.h
+++ b/llvm/include/llvm/Transforms/Utils/LoopUtils.h
@@ -363,15 +363,6 @@ Intrinsic::ID getMinMaxReductionIntrinsicOp(RecurKind RK);
 /// Returns the comparison predicate used when expanding a min/max reduction.
 CmpInst::Predicate getMinMaxReductionPredicate(RecurKind RK);
 
-/// See RecurrenceDescriptor::isAnyOfPattern for a description of the pattern 
we
-/// are trying to match. In this pattern, we are only ever selecting between 
two
-/// values: 1) an initial start value \p StartVal of the reduction PHI, and 2) 
a
-/// loop invariant value. If any of lane value in \p Left, \p Right is not 
equal
-/// to \p StartVal, select the loop invariant value. This is done by selecting
-/// \p Right iff \p Left is equal to \p StartVal.
-Value *createAnyOfOp(IRBuilderBase &Builder, Value *StartVal, RecurKind RK,
- Value *Left, Value *Right);
-
 /// Returns a Min/Max operation corresponding to MinMaxRecurrenceKind.
 /// The Builder's fast-math-flags must be set to propagate the expected values.
 Value *createMinMaxOp(IRBuilderBase &Builder, RecurKind RK, Value *Left,
diff --git a/llvm/lib/Transforms/Utils/LoopUtils.cpp 
b/llvm/lib/Transforms/Utils/LoopUtils.cpp
index 59485126b280abf..c0582fb7d7e1505 100644
--- a/llvm/lib/Transforms/Utils/LoopUtils.cpp
+++ b/llvm/lib/Transforms/Utils/LoopUtils.cpp
@@ -962,15 +962,6 @@ CmpInst::Predicate 
llvm::getMinMaxReductionPredicate(RecurKind RK) {
   }
 }
 
-Value *llvm::createAnyOfOp(IRBuilderBase &Builder, Value *StartVal,
-   RecurKind RK, Value *Left, Value *Right) {
-  if (auto VTy = dyn_cast(Left->getType()))
-StartVal = Builder.CreateVectorSplat(VTy->getElementCount(), StartVal);
-  Value *Cmp =
-  Builder.CreateCmp(CmpInst::ICMP_NE, Left, StartVal, "rdx.select.cmp");
-  return Builder.CreateSelect(Cmp, Left, Right, "rdx.select");
-}
-
 Value *llvm::createMinMaxOp(IRBuilderBase &Builder, RecurKind RK, Value *Left,
 Value *Right) {
   Type *Ty = Left->getType();
@@ -1079,16 +1070,13 @@ Value *llvm::createAnyOfTargetReduction(IRBuilderBase 
&Builder, Value *Src,
 NewVal = SI->getTrueValue();
   }
 
-  // Create a splat vector with the new value and compare this to the vector
-  // we want to reduce.
-  ElementCount EC = cast(Src->getType())->getElementCount();
-  Value *Right = Builder.CreateVectorSplat(EC, InitVal);
-  Value *Cmp =
-  Builder.CreateCmp(CmpInst::ICMP_NE, Src, Right, "rdx.select.cmp");
-
   // If any predicate is true it means that we want to select the new value.
-  Cmp = Builder.CreateOrReduce(Cmp);
-  return Builder.CreateSelect(Cmp, NewVal, InitVal, "rdx.select");
+  Value *AnyOf =
+  Src->getType()->isVectorTy() ? Builder.CreateOrReduce(Src) : Src;
+  // The compares in the loop may yield poison, which propagates through the
+  // bitwise ORs. Freeze it here before the condition is used.
+  AnyOf = Builder.CreateFreeze(AnyOf);
+  return Builder.CreateSelect(AnyOf, NewVal, InitVal, "rdx.select");
 }
 
 Value *llvm::createSimpleTargetReduction(IRBuilderBase &Builder, Value *Src,
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h 
b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h
index a7ebf78e54ceb61..9d3ef5b96c72fbe 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h
@@ -68,6 +68,7 @@ class VPBuilder {
 public:
   VPBuilder() = default;
   VPBuilder(VPBasicBlock *InsertBB) { setInsertPoint(InsertBB); }
+  VPBuilder(VPRecipeB

[clang] [clang-tools-extra] [llvm] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,230 @@
+// RUN: %check_clang_tidy %s readability-use-std-min-max %t

PiotrZSL wrote:

Add `-- -- -fno-delayed-template-parsing` this is why windows tests is falling.
Additionally explicitly set c++ standard with `-std=c++11-or-later` like in 
other checks

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


[clang] [clang-tools-extra] [llvm] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,240 @@
+//===--- UseStdMinMaxCheck.cpp - clang-tidy 
---===//
+//
+// 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 "UseStdMinMaxCheck.h"
+#include "../utils/ASTUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Preprocessor.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+static bool isImplicitCastType(const clang::CastKind castKind) {
+  switch (castKind) {
+  case clang::CK_CPointerToObjCPointerCast:
+  case clang::CK_BlockPointerToObjCPointerCast:
+  case clang::CK_BitCast:
+  case clang::CK_AnyPointerToBlockPointerCast:
+  case clang::CK_NullToMemberPointer:
+  case clang::CK_NullToPointer:
+  case clang::CK_IntegralToPointer:
+  case clang::CK_PointerToIntegral:
+  case clang::CK_IntegralCast:
+  case clang::CK_BooleanToSignedIntegral:
+  case clang::CK_IntegralToFloating:
+  case clang::CK_FloatingToIntegral:
+  case clang::CK_FloatingCast:
+  case clang::CK_ObjCObjectLValueCast:
+  case clang::CK_FloatingRealToComplex:
+  case clang::CK_FloatingComplexToReal:
+  case clang::CK_FloatingComplexCast:
+  case clang::CK_FloatingComplexToIntegralComplex:
+  case clang::CK_IntegralRealToComplex:
+  case clang::CK_IntegralComplexToReal:
+  case clang::CK_IntegralComplexCast:
+  case clang::CK_IntegralComplexToFloatingComplex:
+  case clang::CK_FloatingToFixedPoint:
+  case clang::CK_FixedPointToFloating:
+  case clang::CK_FixedPointCast:
+  case clang::CK_FixedPointToIntegral:
+  case clang::CK_IntegralToFixedPoint:
+  case clang::CK_MatrixCast:
+  case clang::CK_PointerToBoolean:
+  case clang::CK_IntegralToBoolean:
+  case clang::CK_FloatingToBoolean:
+  case clang::CK_MemberPointerToBoolean:
+  case clang::CK_FloatingComplexToBoolean:
+  case clang::CK_IntegralComplexToBoolean:
+  case clang::CK_UserDefinedConversion:
+return true;
+  default:
+return false;
+  }
+}
+
+class ExprVisitor : public clang::RecursiveASTVisitor {
+public:
+  bool visitStmt(const clang::Stmt *S, bool &found,
+ clang::QualType &GlobalImplicitCastType) {
+
+if (isa(S) && !found) {
+  const auto CastKind = cast(S)->getCastKind();
+  if (isImplicitCastType(CastKind)) {
+found = true;
+const clang::ImplicitCastExpr *ImplicitCast =
+cast(S);
+GlobalImplicitCastType = ImplicitCast->getType();
+// Stop visiting children.
+return false;
+  }
+}
+// Continue visiting children.
+for (const clang::Stmt *Child : S->children()) {
+  if (Child) {
+this->visitStmt(Child, found, GlobalImplicitCastType);
+  }
+}
+
+return true; // Continue visiting other nodes.
+  }
+};
+
+static const llvm::StringRef AlgorithmHeader("");
+
+static bool minCondition(const BinaryOperator::Opcode Op, const Expr *CondLhs,
+ const Expr *CondRhs, const Expr *AssignLhs,
+ const Expr *AssignRhs, const ASTContext &Context) {
+  if ((Op == BO_LT || Op == BO_LE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context)))
+return true;
+
+  if ((Op == BO_GT || Op == BO_GE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))
+return true;
+
+  return false;
+}
+
+static bool maxCondition(const BinaryOperator::Opcode Op, const Expr *CondLhs,
+ const Expr *CondRhs, const Expr *AssignLhs,
+ const Expr *AssignRhs, const ASTContext &Context) {
+  if ((Op == BO_LT || Op == BO_LE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))
+return true;
+
+  if ((Op == BO_GT || Op == BO_GE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context)))
+return true;
+
+  return false;
+}
+
+static std::string createReplacement(const BinaryOperator::Opcode Op,
+ const Expr *CondLhs, const Expr *CondRhs,
+ const Expr *AssignLhs,
+ const SourceManager &Source,
+ const LangOptions &LO,
+ StringRef FunctionName, const IfStmt *If) 
{
+  const llvm::StringRef CondLhsStr = Lexer::getSourceText(
+  Source.getExpansionRange(CondLhs->getSourceRange()), Sourc

[clang] [llvm] [clang-tools-extra] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,240 @@
+//===--- UseStdMinMaxCheck.cpp - clang-tidy 
---===//
+//
+// 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 "UseStdMinMaxCheck.h"
+#include "../utils/ASTUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Preprocessor.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+static bool isImplicitCastType(const clang::CastKind castKind) {
+  switch (castKind) {
+  case clang::CK_CPointerToObjCPointerCast:
+  case clang::CK_BlockPointerToObjCPointerCast:
+  case clang::CK_BitCast:
+  case clang::CK_AnyPointerToBlockPointerCast:
+  case clang::CK_NullToMemberPointer:
+  case clang::CK_NullToPointer:
+  case clang::CK_IntegralToPointer:
+  case clang::CK_PointerToIntegral:
+  case clang::CK_IntegralCast:
+  case clang::CK_BooleanToSignedIntegral:
+  case clang::CK_IntegralToFloating:
+  case clang::CK_FloatingToIntegral:
+  case clang::CK_FloatingCast:
+  case clang::CK_ObjCObjectLValueCast:
+  case clang::CK_FloatingRealToComplex:
+  case clang::CK_FloatingComplexToReal:
+  case clang::CK_FloatingComplexCast:
+  case clang::CK_FloatingComplexToIntegralComplex:
+  case clang::CK_IntegralRealToComplex:
+  case clang::CK_IntegralComplexToReal:
+  case clang::CK_IntegralComplexCast:
+  case clang::CK_IntegralComplexToFloatingComplex:
+  case clang::CK_FloatingToFixedPoint:
+  case clang::CK_FixedPointToFloating:
+  case clang::CK_FixedPointCast:
+  case clang::CK_FixedPointToIntegral:
+  case clang::CK_IntegralToFixedPoint:
+  case clang::CK_MatrixCast:
+  case clang::CK_PointerToBoolean:
+  case clang::CK_IntegralToBoolean:
+  case clang::CK_FloatingToBoolean:
+  case clang::CK_MemberPointerToBoolean:
+  case clang::CK_FloatingComplexToBoolean:
+  case clang::CK_IntegralComplexToBoolean:
+  case clang::CK_UserDefinedConversion:
+return true;
+  default:
+return false;
+  }
+}
+
+class ExprVisitor : public clang::RecursiveASTVisitor {
+public:
+  bool visitStmt(const clang::Stmt *S, bool &found,
+ clang::QualType &GlobalImplicitCastType) {
+
+if (isa(S) && !found) {
+  const auto CastKind = cast(S)->getCastKind();
+  if (isImplicitCastType(CastKind)) {
+found = true;
+const clang::ImplicitCastExpr *ImplicitCast =
+cast(S);
+GlobalImplicitCastType = ImplicitCast->getType();
+// Stop visiting children.
+return false;
+  }
+}
+// Continue visiting children.
+for (const clang::Stmt *Child : S->children()) {
+  if (Child) {
+this->visitStmt(Child, found, GlobalImplicitCastType);
+  }
+}
+
+return true; // Continue visiting other nodes.
+  }
+};
+
+static const llvm::StringRef AlgorithmHeader("");
+
+static bool minCondition(const BinaryOperator::Opcode Op, const Expr *CondLhs,
+ const Expr *CondRhs, const Expr *AssignLhs,
+ const Expr *AssignRhs, const ASTContext &Context) {
+  if ((Op == BO_LT || Op == BO_LE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context)))
+return true;
+
+  if ((Op == BO_GT || Op == BO_GE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))
+return true;
+
+  return false;
+}
+
+static bool maxCondition(const BinaryOperator::Opcode Op, const Expr *CondLhs,
+ const Expr *CondRhs, const Expr *AssignLhs,
+ const Expr *AssignRhs, const ASTContext &Context) {
+  if ((Op == BO_LT || Op == BO_LE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))
+return true;
+
+  if ((Op == BO_GT || Op == BO_GE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context)))
+return true;
+
+  return false;
+}
+
+static std::string createReplacement(const BinaryOperator::Opcode Op,
+ const Expr *CondLhs, const Expr *CondRhs,
+ const Expr *AssignLhs,
+ const SourceManager &Source,
+ const LangOptions &LO,
+ StringRef FunctionName, const IfStmt *If) 
{
+  const llvm::StringRef CondLhsStr = Lexer::getSourceText(
+  Source.getExpansionRange(CondLhs->getSourceRange()), Sourc

[clang-tools-extra] [clang] [llvm] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,240 @@
+//===--- UseStdMinMaxCheck.cpp - clang-tidy 
---===//
+//
+// 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 "UseStdMinMaxCheck.h"
+#include "../utils/ASTUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Preprocessor.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+static bool isImplicitCastType(const clang::CastKind castKind) {
+  switch (castKind) {
+  case clang::CK_CPointerToObjCPointerCast:
+  case clang::CK_BlockPointerToObjCPointerCast:
+  case clang::CK_BitCast:
+  case clang::CK_AnyPointerToBlockPointerCast:
+  case clang::CK_NullToMemberPointer:
+  case clang::CK_NullToPointer:
+  case clang::CK_IntegralToPointer:
+  case clang::CK_PointerToIntegral:
+  case clang::CK_IntegralCast:
+  case clang::CK_BooleanToSignedIntegral:
+  case clang::CK_IntegralToFloating:
+  case clang::CK_FloatingToIntegral:
+  case clang::CK_FloatingCast:
+  case clang::CK_ObjCObjectLValueCast:
+  case clang::CK_FloatingRealToComplex:
+  case clang::CK_FloatingComplexToReal:
+  case clang::CK_FloatingComplexCast:
+  case clang::CK_FloatingComplexToIntegralComplex:
+  case clang::CK_IntegralRealToComplex:
+  case clang::CK_IntegralComplexToReal:
+  case clang::CK_IntegralComplexCast:
+  case clang::CK_IntegralComplexToFloatingComplex:
+  case clang::CK_FloatingToFixedPoint:
+  case clang::CK_FixedPointToFloating:
+  case clang::CK_FixedPointCast:
+  case clang::CK_FixedPointToIntegral:
+  case clang::CK_IntegralToFixedPoint:
+  case clang::CK_MatrixCast:
+  case clang::CK_PointerToBoolean:
+  case clang::CK_IntegralToBoolean:
+  case clang::CK_FloatingToBoolean:
+  case clang::CK_MemberPointerToBoolean:
+  case clang::CK_FloatingComplexToBoolean:
+  case clang::CK_IntegralComplexToBoolean:
+  case clang::CK_UserDefinedConversion:
+return true;
+  default:
+return false;
+  }
+}
+
+class ExprVisitor : public clang::RecursiveASTVisitor {
+public:
+  bool visitStmt(const clang::Stmt *S, bool &found,
+ clang::QualType &GlobalImplicitCastType) {
+
+if (isa(S) && !found) {
+  const auto CastKind = cast(S)->getCastKind();
+  if (isImplicitCastType(CastKind)) {
+found = true;
+const clang::ImplicitCastExpr *ImplicitCast =
+cast(S);
+GlobalImplicitCastType = ImplicitCast->getType();
+// Stop visiting children.
+return false;
+  }
+}
+// Continue visiting children.
+for (const clang::Stmt *Child : S->children()) {
+  if (Child) {
+this->visitStmt(Child, found, GlobalImplicitCastType);
+  }
+}
+
+return true; // Continue visiting other nodes.
+  }
+};
+
+static const llvm::StringRef AlgorithmHeader("");
+
+static bool minCondition(const BinaryOperator::Opcode Op, const Expr *CondLhs,
+ const Expr *CondRhs, const Expr *AssignLhs,
+ const Expr *AssignRhs, const ASTContext &Context) {
+  if ((Op == BO_LT || Op == BO_LE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context)))
+return true;
+
+  if ((Op == BO_GT || Op == BO_GE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))
+return true;
+
+  return false;
+}
+
+static bool maxCondition(const BinaryOperator::Opcode Op, const Expr *CondLhs,
+ const Expr *CondRhs, const Expr *AssignLhs,
+ const Expr *AssignRhs, const ASTContext &Context) {
+  if ((Op == BO_LT || Op == BO_LE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))
+return true;
+
+  if ((Op == BO_GT || Op == BO_GE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context)))
+return true;
+
+  return false;
+}
+
+static std::string createReplacement(const BinaryOperator::Opcode Op,
+ const Expr *CondLhs, const Expr *CondRhs,
+ const Expr *AssignLhs,
+ const SourceManager &Source,
+ const LangOptions &LO,
+ StringRef FunctionName, const IfStmt *If) 
{
+  const llvm::StringRef CondLhsStr = Lexer::getSourceText(
+  Source.getExpansionRange(CondLhs->getSourceRange()), Sourc

[clang] [clang-tools-extra] [llvm] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,240 @@
+//===--- UseStdMinMaxCheck.cpp - clang-tidy 
---===//
+//
+// 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 "UseStdMinMaxCheck.h"
+#include "../utils/ASTUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Preprocessor.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+static bool isImplicitCastType(const clang::CastKind castKind) {
+  switch (castKind) {
+  case clang::CK_CPointerToObjCPointerCast:
+  case clang::CK_BlockPointerToObjCPointerCast:
+  case clang::CK_BitCast:
+  case clang::CK_AnyPointerToBlockPointerCast:
+  case clang::CK_NullToMemberPointer:
+  case clang::CK_NullToPointer:
+  case clang::CK_IntegralToPointer:
+  case clang::CK_PointerToIntegral:
+  case clang::CK_IntegralCast:
+  case clang::CK_BooleanToSignedIntegral:
+  case clang::CK_IntegralToFloating:
+  case clang::CK_FloatingToIntegral:
+  case clang::CK_FloatingCast:
+  case clang::CK_ObjCObjectLValueCast:
+  case clang::CK_FloatingRealToComplex:
+  case clang::CK_FloatingComplexToReal:
+  case clang::CK_FloatingComplexCast:
+  case clang::CK_FloatingComplexToIntegralComplex:
+  case clang::CK_IntegralRealToComplex:
+  case clang::CK_IntegralComplexToReal:
+  case clang::CK_IntegralComplexCast:
+  case clang::CK_IntegralComplexToFloatingComplex:
+  case clang::CK_FloatingToFixedPoint:
+  case clang::CK_FixedPointToFloating:
+  case clang::CK_FixedPointCast:
+  case clang::CK_FixedPointToIntegral:
+  case clang::CK_IntegralToFixedPoint:
+  case clang::CK_MatrixCast:
+  case clang::CK_PointerToBoolean:
+  case clang::CK_IntegralToBoolean:
+  case clang::CK_FloatingToBoolean:
+  case clang::CK_MemberPointerToBoolean:
+  case clang::CK_FloatingComplexToBoolean:
+  case clang::CK_IntegralComplexToBoolean:
+  case clang::CK_UserDefinedConversion:
+return true;
+  default:
+return false;
+  }
+}
+
+class ExprVisitor : public clang::RecursiveASTVisitor {
+public:
+  bool visitStmt(const clang::Stmt *S, bool &found,
+ clang::QualType &GlobalImplicitCastType) {
+
+if (isa(S) && !found) {
+  const auto CastKind = cast(S)->getCastKind();
+  if (isImplicitCastType(CastKind)) {
+found = true;
+const clang::ImplicitCastExpr *ImplicitCast =
+cast(S);
+GlobalImplicitCastType = ImplicitCast->getType();
+// Stop visiting children.
+return false;
+  }
+}
+// Continue visiting children.
+for (const clang::Stmt *Child : S->children()) {
+  if (Child) {
+this->visitStmt(Child, found, GlobalImplicitCastType);
+  }
+}
+
+return true; // Continue visiting other nodes.
+  }
+};
+
+static const llvm::StringRef AlgorithmHeader("");
+
+static bool minCondition(const BinaryOperator::Opcode Op, const Expr *CondLhs,
+ const Expr *CondRhs, const Expr *AssignLhs,
+ const Expr *AssignRhs, const ASTContext &Context) {
+  if ((Op == BO_LT || Op == BO_LE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context)))
+return true;
+
+  if ((Op == BO_GT || Op == BO_GE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))
+return true;
+
+  return false;
+}
+
+static bool maxCondition(const BinaryOperator::Opcode Op, const Expr *CondLhs,
+ const Expr *CondRhs, const Expr *AssignLhs,
+ const Expr *AssignRhs, const ASTContext &Context) {
+  if ((Op == BO_LT || Op == BO_LE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))
+return true;
+
+  if ((Op == BO_GT || Op == BO_GE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context)))
+return true;
+
+  return false;
+}
+
+static std::string createReplacement(const BinaryOperator::Opcode Op,
+ const Expr *CondLhs, const Expr *CondRhs,
+ const Expr *AssignLhs,
+ const SourceManager &Source,
+ const LangOptions &LO,
+ StringRef FunctionName, const IfStmt *If) 
{
+  const llvm::StringRef CondLhsStr = Lexer::getSourceText(
+  Source.getExpansionRange(CondLhs->getSourceRange()), Sourc

[llvm] [clang-tools-extra] [clang] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,240 @@
+//===--- UseStdMinMaxCheck.cpp - clang-tidy 
---===//
+//
+// 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 "UseStdMinMaxCheck.h"
+#include "../utils/ASTUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Preprocessor.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+static bool isImplicitCastType(const clang::CastKind castKind) {
+  switch (castKind) {
+  case clang::CK_CPointerToObjCPointerCast:
+  case clang::CK_BlockPointerToObjCPointerCast:
+  case clang::CK_BitCast:
+  case clang::CK_AnyPointerToBlockPointerCast:
+  case clang::CK_NullToMemberPointer:
+  case clang::CK_NullToPointer:
+  case clang::CK_IntegralToPointer:
+  case clang::CK_PointerToIntegral:
+  case clang::CK_IntegralCast:
+  case clang::CK_BooleanToSignedIntegral:
+  case clang::CK_IntegralToFloating:
+  case clang::CK_FloatingToIntegral:
+  case clang::CK_FloatingCast:
+  case clang::CK_ObjCObjectLValueCast:
+  case clang::CK_FloatingRealToComplex:
+  case clang::CK_FloatingComplexToReal:
+  case clang::CK_FloatingComplexCast:
+  case clang::CK_FloatingComplexToIntegralComplex:
+  case clang::CK_IntegralRealToComplex:
+  case clang::CK_IntegralComplexToReal:
+  case clang::CK_IntegralComplexCast:
+  case clang::CK_IntegralComplexToFloatingComplex:
+  case clang::CK_FloatingToFixedPoint:
+  case clang::CK_FixedPointToFloating:
+  case clang::CK_FixedPointCast:
+  case clang::CK_FixedPointToIntegral:
+  case clang::CK_IntegralToFixedPoint:
+  case clang::CK_MatrixCast:
+  case clang::CK_PointerToBoolean:
+  case clang::CK_IntegralToBoolean:
+  case clang::CK_FloatingToBoolean:
+  case clang::CK_MemberPointerToBoolean:
+  case clang::CK_FloatingComplexToBoolean:
+  case clang::CK_IntegralComplexToBoolean:
+  case clang::CK_UserDefinedConversion:
+return true;
+  default:
+return false;
+  }
+}
+
+class ExprVisitor : public clang::RecursiveASTVisitor {
+public:
+  bool visitStmt(const clang::Stmt *S, bool &found,
+ clang::QualType &GlobalImplicitCastType) {
+
+if (isa(S) && !found) {
+  const auto CastKind = cast(S)->getCastKind();
+  if (isImplicitCastType(CastKind)) {
+found = true;
+const clang::ImplicitCastExpr *ImplicitCast =
+cast(S);
+GlobalImplicitCastType = ImplicitCast->getType();
+// Stop visiting children.
+return false;
+  }
+}
+// Continue visiting children.
+for (const clang::Stmt *Child : S->children()) {
+  if (Child) {
+this->visitStmt(Child, found, GlobalImplicitCastType);
+  }
+}
+
+return true; // Continue visiting other nodes.
+  }
+};
+
+static const llvm::StringRef AlgorithmHeader("");
+
+static bool minCondition(const BinaryOperator::Opcode Op, const Expr *CondLhs,
+ const Expr *CondRhs, const Expr *AssignLhs,
+ const Expr *AssignRhs, const ASTContext &Context) {
+  if ((Op == BO_LT || Op == BO_LE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context)))
+return true;
+
+  if ((Op == BO_GT || Op == BO_GE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))
+return true;
+
+  return false;
+}
+
+static bool maxCondition(const BinaryOperator::Opcode Op, const Expr *CondLhs,
+ const Expr *CondRhs, const Expr *AssignLhs,
+ const Expr *AssignRhs, const ASTContext &Context) {
+  if ((Op == BO_LT || Op == BO_LE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))
+return true;
+
+  if ((Op == BO_GT || Op == BO_GE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context)))
+return true;
+
+  return false;
+}
+
+static std::string createReplacement(const BinaryOperator::Opcode Op,
+ const Expr *CondLhs, const Expr *CondRhs,
+ const Expr *AssignLhs,
+ const SourceManager &Source,
+ const LangOptions &LO,
+ StringRef FunctionName, const IfStmt *If) 
{
+  const llvm::StringRef CondLhsStr = Lexer::getSourceText(
+  Source.getExpansionRange(CondLhs->getSourceRange()), Sourc

[clang] [clang-tools-extra] [llvm] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,240 @@
+//===--- UseStdMinMaxCheck.cpp - clang-tidy 
---===//
+//
+// 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 "UseStdMinMaxCheck.h"
+#include "../utils/ASTUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Preprocessor.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+static bool isImplicitCastType(const clang::CastKind castKind) {
+  switch (castKind) {
+  case clang::CK_CPointerToObjCPointerCast:
+  case clang::CK_BlockPointerToObjCPointerCast:
+  case clang::CK_BitCast:
+  case clang::CK_AnyPointerToBlockPointerCast:
+  case clang::CK_NullToMemberPointer:
+  case clang::CK_NullToPointer:
+  case clang::CK_IntegralToPointer:
+  case clang::CK_PointerToIntegral:
+  case clang::CK_IntegralCast:
+  case clang::CK_BooleanToSignedIntegral:
+  case clang::CK_IntegralToFloating:
+  case clang::CK_FloatingToIntegral:
+  case clang::CK_FloatingCast:
+  case clang::CK_ObjCObjectLValueCast:
+  case clang::CK_FloatingRealToComplex:
+  case clang::CK_FloatingComplexToReal:
+  case clang::CK_FloatingComplexCast:
+  case clang::CK_FloatingComplexToIntegralComplex:
+  case clang::CK_IntegralRealToComplex:
+  case clang::CK_IntegralComplexToReal:
+  case clang::CK_IntegralComplexCast:
+  case clang::CK_IntegralComplexToFloatingComplex:
+  case clang::CK_FloatingToFixedPoint:
+  case clang::CK_FixedPointToFloating:
+  case clang::CK_FixedPointCast:
+  case clang::CK_FixedPointToIntegral:
+  case clang::CK_IntegralToFixedPoint:
+  case clang::CK_MatrixCast:
+  case clang::CK_PointerToBoolean:
+  case clang::CK_IntegralToBoolean:
+  case clang::CK_FloatingToBoolean:
+  case clang::CK_MemberPointerToBoolean:
+  case clang::CK_FloatingComplexToBoolean:
+  case clang::CK_IntegralComplexToBoolean:
+  case clang::CK_UserDefinedConversion:
+return true;
+  default:
+return false;
+  }
+}
+
+class ExprVisitor : public clang::RecursiveASTVisitor {

PiotrZSL wrote:

This is overengineered and not needed.
There are easier ways to read implicit cast types.

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


[llvm] [clang] [clang-tools-extra] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Piotr Zegar via cfe-commits

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


[llvm] [clang-tools-extra] [clang] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,240 @@
+//===--- UseStdMinMaxCheck.cpp - clang-tidy 
---===//
+//
+// 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 "UseStdMinMaxCheck.h"
+#include "../utils/ASTUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Preprocessor.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+static bool isImplicitCastType(const clang::CastKind castKind) {
+  switch (castKind) {
+  case clang::CK_CPointerToObjCPointerCast:
+  case clang::CK_BlockPointerToObjCPointerCast:
+  case clang::CK_BitCast:
+  case clang::CK_AnyPointerToBlockPointerCast:
+  case clang::CK_NullToMemberPointer:
+  case clang::CK_NullToPointer:
+  case clang::CK_IntegralToPointer:
+  case clang::CK_PointerToIntegral:
+  case clang::CK_IntegralCast:
+  case clang::CK_BooleanToSignedIntegral:
+  case clang::CK_IntegralToFloating:
+  case clang::CK_FloatingToIntegral:
+  case clang::CK_FloatingCast:
+  case clang::CK_ObjCObjectLValueCast:
+  case clang::CK_FloatingRealToComplex:
+  case clang::CK_FloatingComplexToReal:
+  case clang::CK_FloatingComplexCast:
+  case clang::CK_FloatingComplexToIntegralComplex:
+  case clang::CK_IntegralRealToComplex:
+  case clang::CK_IntegralComplexToReal:
+  case clang::CK_IntegralComplexCast:
+  case clang::CK_IntegralComplexToFloatingComplex:
+  case clang::CK_FloatingToFixedPoint:
+  case clang::CK_FixedPointToFloating:
+  case clang::CK_FixedPointCast:
+  case clang::CK_FixedPointToIntegral:
+  case clang::CK_IntegralToFixedPoint:
+  case clang::CK_MatrixCast:
+  case clang::CK_PointerToBoolean:
+  case clang::CK_IntegralToBoolean:
+  case clang::CK_FloatingToBoolean:
+  case clang::CK_MemberPointerToBoolean:
+  case clang::CK_FloatingComplexToBoolean:
+  case clang::CK_IntegralComplexToBoolean:
+  case clang::CK_UserDefinedConversion:
+return true;
+  default:
+return false;
+  }
+}
+
+class ExprVisitor : public clang::RecursiveASTVisitor {
+public:
+  bool visitStmt(const clang::Stmt *S, bool &found,
+ clang::QualType &GlobalImplicitCastType) {
+
+if (isa(S) && !found) {
+  const auto CastKind = cast(S)->getCastKind();
+  if (isImplicitCastType(CastKind)) {
+found = true;
+const clang::ImplicitCastExpr *ImplicitCast =
+cast(S);
+GlobalImplicitCastType = ImplicitCast->getType();
+// Stop visiting children.
+return false;
+  }
+}
+// Continue visiting children.
+for (const clang::Stmt *Child : S->children()) {
+  if (Child) {
+this->visitStmt(Child, found, GlobalImplicitCastType);
+  }
+}
+
+return true; // Continue visiting other nodes.
+  }
+};
+
+static const llvm::StringRef AlgorithmHeader("");
+
+static bool minCondition(const BinaryOperator::Opcode Op, const Expr *CondLhs,
+ const Expr *CondRhs, const Expr *AssignLhs,
+ const Expr *AssignRhs, const ASTContext &Context) {
+  if ((Op == BO_LT || Op == BO_LE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context)))
+return true;
+
+  if ((Op == BO_GT || Op == BO_GE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))
+return true;
+
+  return false;
+}
+
+static bool maxCondition(const BinaryOperator::Opcode Op, const Expr *CondLhs,
+ const Expr *CondRhs, const Expr *AssignLhs,
+ const Expr *AssignRhs, const ASTContext &Context) {
+  if ((Op == BO_LT || Op == BO_LE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))
+return true;
+
+  if ((Op == BO_GT || Op == BO_GE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context)))
+return true;
+
+  return false;
+}
+
+static std::string createReplacement(const BinaryOperator::Opcode Op,
+ const Expr *CondLhs, const Expr *CondRhs,
+ const Expr *AssignLhs,
+ const SourceManager &Source,
+ const LangOptions &LO,
+ StringRef FunctionName, const IfStmt *If) 
{
+  const llvm::StringRef CondLhsStr = Lexer::getSourceText(
+  Source.getExpansionRange(CondLhs->getSourceRange()), Sourc

[llvm] [clang-tools-extra] [clang] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,240 @@
+//===--- UseStdMinMaxCheck.cpp - clang-tidy 
---===//
+//
+// 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 "UseStdMinMaxCheck.h"
+#include "../utils/ASTUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Preprocessor.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+static bool isImplicitCastType(const clang::CastKind castKind) {
+  switch (castKind) {
+  case clang::CK_CPointerToObjCPointerCast:
+  case clang::CK_BlockPointerToObjCPointerCast:
+  case clang::CK_BitCast:
+  case clang::CK_AnyPointerToBlockPointerCast:
+  case clang::CK_NullToMemberPointer:
+  case clang::CK_NullToPointer:
+  case clang::CK_IntegralToPointer:
+  case clang::CK_PointerToIntegral:
+  case clang::CK_IntegralCast:
+  case clang::CK_BooleanToSignedIntegral:
+  case clang::CK_IntegralToFloating:
+  case clang::CK_FloatingToIntegral:
+  case clang::CK_FloatingCast:
+  case clang::CK_ObjCObjectLValueCast:
+  case clang::CK_FloatingRealToComplex:
+  case clang::CK_FloatingComplexToReal:
+  case clang::CK_FloatingComplexCast:
+  case clang::CK_FloatingComplexToIntegralComplex:
+  case clang::CK_IntegralRealToComplex:
+  case clang::CK_IntegralComplexToReal:
+  case clang::CK_IntegralComplexCast:
+  case clang::CK_IntegralComplexToFloatingComplex:
+  case clang::CK_FloatingToFixedPoint:
+  case clang::CK_FixedPointToFloating:
+  case clang::CK_FixedPointCast:
+  case clang::CK_FixedPointToIntegral:
+  case clang::CK_IntegralToFixedPoint:
+  case clang::CK_MatrixCast:
+  case clang::CK_PointerToBoolean:
+  case clang::CK_IntegralToBoolean:
+  case clang::CK_FloatingToBoolean:
+  case clang::CK_MemberPointerToBoolean:
+  case clang::CK_FloatingComplexToBoolean:
+  case clang::CK_IntegralComplexToBoolean:
+  case clang::CK_UserDefinedConversion:
+return true;
+  default:
+return false;
+  }
+}
+
+class ExprVisitor : public clang::RecursiveASTVisitor {
+public:
+  bool visitStmt(const clang::Stmt *S, bool &found,
+ clang::QualType &GlobalImplicitCastType) {
+
+if (isa(S) && !found) {
+  const auto CastKind = cast(S)->getCastKind();
+  if (isImplicitCastType(CastKind)) {
+found = true;
+const clang::ImplicitCastExpr *ImplicitCast =
+cast(S);
+GlobalImplicitCastType = ImplicitCast->getType();
+// Stop visiting children.
+return false;
+  }
+}
+// Continue visiting children.
+for (const clang::Stmt *Child : S->children()) {
+  if (Child) {
+this->visitStmt(Child, found, GlobalImplicitCastType);
+  }
+}
+
+return true; // Continue visiting other nodes.
+  }
+};
+
+static const llvm::StringRef AlgorithmHeader("");
+
+static bool minCondition(const BinaryOperator::Opcode Op, const Expr *CondLhs,
+ const Expr *CondRhs, const Expr *AssignLhs,
+ const Expr *AssignRhs, const ASTContext &Context) {
+  if ((Op == BO_LT || Op == BO_LE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context)))
+return true;
+
+  if ((Op == BO_GT || Op == BO_GE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))
+return true;
+
+  return false;
+}
+
+static bool maxCondition(const BinaryOperator::Opcode Op, const Expr *CondLhs,
+ const Expr *CondRhs, const Expr *AssignLhs,
+ const Expr *AssignRhs, const ASTContext &Context) {
+  if ((Op == BO_LT || Op == BO_LE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))
+return true;
+
+  if ((Op == BO_GT || Op == BO_GE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context)))
+return true;
+
+  return false;
+}
+
+static std::string createReplacement(const BinaryOperator::Opcode Op,
+ const Expr *CondLhs, const Expr *CondRhs,
+ const Expr *AssignLhs,
+ const SourceManager &Source,
+ const LangOptions &LO,
+ StringRef FunctionName, const IfStmt *If) 
{
+  const llvm::StringRef CondLhsStr = Lexer::getSourceText(
+  Source.getExpansionRange(CondLhs->getSourceRange()), Sourc

[llvm] [clang-tools-extra] [clang] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,240 @@
+//===--- UseStdMinMaxCheck.cpp - clang-tidy 
---===//
+//
+// 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 "UseStdMinMaxCheck.h"
+#include "../utils/ASTUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Preprocessor.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+static bool isImplicitCastType(const clang::CastKind castKind) {

PiotrZSL wrote:

this function shouldn't exist, as cast kind doesn't mean that this is implicit 
cast.

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


[clang-tools-extra] [llvm] [clang] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,240 @@
+//===--- UseStdMinMaxCheck.cpp - clang-tidy 
---===//
+//
+// 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 "UseStdMinMaxCheck.h"
+#include "../utils/ASTUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Preprocessor.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+static bool isImplicitCastType(const clang::CastKind castKind) {
+  switch (castKind) {
+  case clang::CK_CPointerToObjCPointerCast:
+  case clang::CK_BlockPointerToObjCPointerCast:
+  case clang::CK_BitCast:
+  case clang::CK_AnyPointerToBlockPointerCast:
+  case clang::CK_NullToMemberPointer:
+  case clang::CK_NullToPointer:
+  case clang::CK_IntegralToPointer:
+  case clang::CK_PointerToIntegral:
+  case clang::CK_IntegralCast:
+  case clang::CK_BooleanToSignedIntegral:
+  case clang::CK_IntegralToFloating:
+  case clang::CK_FloatingToIntegral:
+  case clang::CK_FloatingCast:
+  case clang::CK_ObjCObjectLValueCast:
+  case clang::CK_FloatingRealToComplex:
+  case clang::CK_FloatingComplexToReal:
+  case clang::CK_FloatingComplexCast:
+  case clang::CK_FloatingComplexToIntegralComplex:
+  case clang::CK_IntegralRealToComplex:
+  case clang::CK_IntegralComplexToReal:
+  case clang::CK_IntegralComplexCast:
+  case clang::CK_IntegralComplexToFloatingComplex:
+  case clang::CK_FloatingToFixedPoint:
+  case clang::CK_FixedPointToFloating:
+  case clang::CK_FixedPointCast:
+  case clang::CK_FixedPointToIntegral:
+  case clang::CK_IntegralToFixedPoint:
+  case clang::CK_MatrixCast:
+  case clang::CK_PointerToBoolean:
+  case clang::CK_IntegralToBoolean:
+  case clang::CK_FloatingToBoolean:
+  case clang::CK_MemberPointerToBoolean:
+  case clang::CK_FloatingComplexToBoolean:
+  case clang::CK_IntegralComplexToBoolean:
+  case clang::CK_UserDefinedConversion:
+return true;
+  default:
+return false;
+  }
+}
+
+class ExprVisitor : public clang::RecursiveASTVisitor {
+public:
+  bool visitStmt(const clang::Stmt *S, bool &found,
+ clang::QualType &GlobalImplicitCastType) {
+
+if (isa(S) && !found) {
+  const auto CastKind = cast(S)->getCastKind();
+  if (isImplicitCastType(CastKind)) {
+found = true;
+const clang::ImplicitCastExpr *ImplicitCast =
+cast(S);
+GlobalImplicitCastType = ImplicitCast->getType();
+// Stop visiting children.
+return false;
+  }
+}
+// Continue visiting children.
+for (const clang::Stmt *Child : S->children()) {
+  if (Child) {
+this->visitStmt(Child, found, GlobalImplicitCastType);
+  }
+}
+
+return true; // Continue visiting other nodes.
+  }
+};
+
+static const llvm::StringRef AlgorithmHeader("");
+
+static bool minCondition(const BinaryOperator::Opcode Op, const Expr *CondLhs,
+ const Expr *CondRhs, const Expr *AssignLhs,
+ const Expr *AssignRhs, const ASTContext &Context) {
+  if ((Op == BO_LT || Op == BO_LE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context)))
+return true;
+
+  if ((Op == BO_GT || Op == BO_GE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))
+return true;
+
+  return false;
+}
+
+static bool maxCondition(const BinaryOperator::Opcode Op, const Expr *CondLhs,
+ const Expr *CondRhs, const Expr *AssignLhs,
+ const Expr *AssignRhs, const ASTContext &Context) {
+  if ((Op == BO_LT || Op == BO_LE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))
+return true;
+
+  if ((Op == BO_GT || Op == BO_GE) &&
+  (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+   tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context)))
+return true;
+
+  return false;
+}
+
+static std::string createReplacement(const BinaryOperator::Opcode Op,
+ const Expr *CondLhs, const Expr *CondRhs,
+ const Expr *AssignLhs,
+ const SourceManager &Source,
+ const LangOptions &LO,
+ StringRef FunctionName, const IfStmt *If) 
{
+  const llvm::StringRef CondLhsStr = Lexer::getSourceText(
+  Source.getExpansionRange(CondLhs->getSourceRange()), Sourc

[clang] [clang-tools-extra] [llvm] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,230 @@
+// RUN: %check_clang_tidy %s readability-use-std-min-max %t
+#define MY_MACRO_MIN(a, b) ((a) < (b) ? (a) : (b))
+
+constexpr int myConstexprMin(int a, int b) {
+  return a < b ? a : b;
+}
+
+constexpr int myConstexprMax(int a, int b) {
+  return a > b ? a : b;
+}
+
+#define MY_IF_MACRO(condition, statement) \
+  if (condition) {\
+statement \
+  }
+
+class MyClass {
+public:
+  int member1;
+  int member2;
+};
+
+template
+
+void foo(T value7) {
+  int value1,value2,value3;
+  short value4;
+  unsigned int value5;
+  unsigned char value6;
+  const int value8 = 5;
+  volatile int value9 = 6;
+  MyClass obj;
+

PiotrZSL wrote:

This isn't C, put variables closer to usage...

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


[clang] [clang-tools-extra] [llvm] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

2024-01-28 Thread Piotr Zegar via cfe-commits

https://github.com/PiotrZSL requested changes to this pull request.

Too overengineered. There are easier ways, just check comments.
Except that, looks +- fine.

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


[clang] [compiler-rt] [flang] [llvm] [clang-tools-extra] [VPlan] Replace VPRecipeOrVPValue with VP2VP recipe simplification. (PR #76090)

2024-01-28 Thread via cfe-commits


@@ -827,6 +827,16 @@ static unsigned getOpcodeForRecipe(VPRecipeBase &R) {
 
 /// Try to simplify recipe \p R.
 static void simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
+  // Try to remove redundant blend recipes.
+  if (auto *Blend = dyn_cast(&R)) {

ayalz wrote:

nit: may be worth defining and reusing `IncomingValue0 = 
Blend->getIncomingValue(0);`

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


[clang-tools-extra] [llvm] [compiler-rt] [flang] [clang] [VPlan] Replace VPRecipeOrVPValue with VP2VP recipe simplification. (PR #76090)

2024-01-28 Thread via cfe-commits


@@ -9027,7 +8994,8 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
 // the phi until LoopExitValue. We keep track of the previous item
 // (PreviousLink) to tell which of the two operands of a Link will remain
 // scalar and which will be reduced. For minmax by select(cmp), Link will 
be
-// the select instructions.
+// the select instructions. Blend recipes will get folded to their non-phi

ayalz wrote:

```suggestion
// the select instructions. Blend recipes of in-loop reduction phi's will 
get folded to their non-phi
```

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


[clang] [flang] [llvm] [clang-tools-extra] [compiler-rt] [VPlan] Replace VPRecipeOrVPValue with VP2VP recipe simplification. (PR #76090)

2024-01-28 Thread via cfe-commits


@@ -100,11 +99,8 @@ class VPRecipeBuilder {
   /// Check if \p I has an opcode that can be widened and return a 
VPWidenRecipe

ayalz wrote:

(Indeed back to returning VPWidenRecipe as documented...)

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


[llvm] [flang] [clang] [clang-tools-extra] [compiler-rt] [VPlan] Replace VPRecipeOrVPValue with VP2VP recipe simplification. (PR #76090)

2024-01-28 Thread via cfe-commits


@@ -9058,6 +9026,20 @@ void 
LoopVectorizationPlanner::adjustRecipesForReductions(
 LinkVPBB->insert(FMulRecipe, CurrentLink->getIterator());
 VecOp = FMulRecipe;
   } else {
+auto *Blend = dyn_cast(CurrentLink);
+if (PhiR->isInLoop() && Blend) {
+  assert(Blend->getNumIncomingValues() == 2 &&
+ "Blend must have 2 incoming values");
+  if (Blend->getIncomingValue(0) == PhiR)
+Blend->replaceAllUsesWith(Blend->getIncomingValue(1));
+  else {
+Blend->replaceAllUsesWith(Blend->getIncomingValue(0));
+assert(Blend->getIncomingValue(1) == PhiR &&
+   "PhiR must be an operand of the blend");

ayalz wrote:

nit: may be slightly more consistent to have the assert first.

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


[llvm] [clang-tools-extra] [compiler-rt] [clang] [flang] [VPlan] Replace VPRecipeOrVPValue with VP2VP recipe simplification. (PR #76090)

2024-01-28 Thread via cfe-commits

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


[clang-tools-extra] [flang] [llvm] [compiler-rt] [clang] [VPlan] Replace VPRecipeOrVPValue with VP2VP recipe simplification. (PR #76090)

2024-01-28 Thread via cfe-commits

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

Looks good to me, thanks for cleaning this up!
Adding a couple of minor nits.

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


[llvm] [clang] [NVPTX] Add 'activemask' builtin and intrinsic support (PR #79768)

2024-01-28 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Joseph Huber (jhuber6)


Changes

Summary:
This patch adds support for getting the 'activemask' instruction's value
without needing to use inline assembly. See the relevant PTX reference
for details.

https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-activemask


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


6 Files Affected:

- (modified) clang/include/clang/Basic/BuiltinsNVPTX.def (+7-1) 
- (modified) clang/test/CodeGen/builtins-nvptx.c (+8) 
- (modified) llvm/include/llvm/IR/IntrinsicsNVVM.td (+8) 
- (modified) llvm/lib/Target/NVPTX/NVPTX.td (+2-2) 
- (modified) llvm/lib/Target/NVPTX/NVPTXIntrinsics.td (+6) 
- (added) llvm/test/CodeGen/NVPTX/activemask.ll (+38) 


``diff
diff --git a/clang/include/clang/Basic/BuiltinsNVPTX.def 
b/clang/include/clang/Basic/BuiltinsNVPTX.def
index 0f2e8260143be78..506288547a15822 100644
--- a/clang/include/clang/Basic/BuiltinsNVPTX.def
+++ b/clang/include/clang/Basic/BuiltinsNVPTX.def
@@ -44,6 +44,7 @@
 #pragma push_macro("PTX42")
 #pragma push_macro("PTX60")
 #pragma push_macro("PTX61")
+#pragma push_macro("PTX62")
 #pragma push_macro("PTX63")
 #pragma push_macro("PTX64")
 #pragma push_macro("PTX65")
@@ -76,7 +77,8 @@
 #define PTX65 "ptx65|" PTX70
 #define PTX64 "ptx64|" PTX65
 #define PTX63 "ptx63|" PTX64
-#define PTX61 "ptx61|" PTX63
+#define PTX62 "ptx62|" PTX63
+#define PTX61 "ptx61|" PTX62
 #define PTX60 "ptx60|" PTX61
 #define PTX42 "ptx42|" PTX60
 
@@ -632,6 +634,9 @@ TARGET_BUILTIN(__nvvm_vote_any_sync, "bUib", "", PTX60)
 TARGET_BUILTIN(__nvvm_vote_uni_sync, "bUib", "", PTX60)
 TARGET_BUILTIN(__nvvm_vote_ballot_sync, "UiUib", "", PTX60)
 
+// Mask
+TARGET_BUILTIN(__nvvm_activemask, "i", "n", PTX62)
+
 // Match
 TARGET_BUILTIN(__nvvm_match_any_sync_i32, "UiUiUi", "", AND(SM_70,PTX60))
 TARGET_BUILTIN(__nvvm_match_any_sync_i64, "UiUiWi", "", AND(SM_70,PTX60))
@@ -1065,6 +1070,7 @@ TARGET_BUILTIN(__nvvm_getctarank_shared_cluster, "iv*3", 
"", AND(SM_90,PTX78))
 #pragma pop_macro("PTX42")
 #pragma pop_macro("PTX60")
 #pragma pop_macro("PTX61")
+#pragma pop_macro("PTX62")
 #pragma pop_macro("PTX63")
 #pragma pop_macro("PTX64")
 #pragma pop_macro("PTX65")
diff --git a/clang/test/CodeGen/builtins-nvptx.c 
b/clang/test/CodeGen/builtins-nvptx.c
index 353f3ebb608c2b1..e571d1cd61c41d9 100644
--- a/clang/test/CodeGen/builtins-nvptx.c
+++ b/clang/test/CodeGen/builtins-nvptx.c
@@ -165,6 +165,14 @@ __device__ void sync() {
 
 }
 
+__device__ void activemask() {
+
+// CHECK: call i32 @llvm.nvvm.activemask()
+
+  __nvvm_activemask(0);
+
+}
+
 
 // NVVM intrinsics
 
diff --git a/llvm/include/llvm/IR/IntrinsicsNVVM.td 
b/llvm/include/llvm/IR/IntrinsicsNVVM.td
index 5a5ba2592e1467e..0640fb1f74aa5eb 100644
--- a/llvm/include/llvm/IR/IntrinsicsNVVM.td
+++ b/llvm/include/llvm/IR/IntrinsicsNVVM.td
@@ -4599,6 +4599,14 @@ def int_nvvm_vote_ballot_sync :
 [IntrInaccessibleMemOnly, IntrConvergent, IntrNoCallback], 
"llvm.nvvm.vote.ballot.sync">,
   ClangBuiltin<"__nvvm_vote_ballot_sync">;
 
+//
+// ACTIVEMASK
+//
+def int_nvvm_activemask :
+  Intrinsic<[llvm_i32_ty], [],
+[IntrInaccessibleMemOnly, IntrConvergent, IntrNoCallback], 
"llvm.nvvm.activemask">,
+  ClangBuiltin<"__nvvm_activemask">;
+
 //
 // MATCH.SYNC
 //
diff --git a/llvm/lib/Target/NVPTX/NVPTX.td b/llvm/lib/Target/NVPTX/NVPTX.td
index f2a4ce381b40b48..a2233d3882b236d 100644
--- a/llvm/lib/Target/NVPTX/NVPTX.td
+++ b/llvm/lib/Target/NVPTX/NVPTX.td
@@ -40,7 +40,7 @@ foreach sm = [20, 21, 30, 32, 35, 37, 50, 52, 53,
 
 def SM90a: FeatureSM<"90a", 901>;
 
-foreach version = [32, 40, 41, 42, 43, 50, 60, 61, 63, 64, 65,
+foreach version = [32, 40, 41, 42, 43, 50, 60, 61, 62, 63, 64, 65,
70, 71, 72, 73, 74, 75, 76, 77, 78, 80, 81, 82, 83] in
   def PTX#version: FeaturePTX;
 
@@ -65,7 +65,7 @@ def : Proc<"sm_61", [SM61, PTX50]>;
 def : Proc<"sm_62", [SM62, PTX50]>;
 def : Proc<"sm_70", [SM70, PTX60]>;
 def : Proc<"sm_72", [SM72, PTX61]>;
-def : Proc<"sm_75", [SM75, PTX63]>;
+def : Proc<"sm_75", [SM75, PTX62, PTX63]>;
 def : Proc<"sm_80", [SM80, PTX70]>;
 def : Proc<"sm_86", [SM86, PTX71]>;
 def : Proc<"sm_87", [SM87, PTX74]>;
diff --git a/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td 
b/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td
index 33f1e4a43e072af..2df931597616566 100644
--- a/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td
+++ b/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td
@@ -263,6 +263,12 @@ multiclass MATCH_ANY_SYNC, hasSM<70>]>;
 }
 
+// activemask.b32
+def ACTIVEMASK : NVPTXInst<(outs Int32Regs:$dest), (ins),
+"activemask.b32 \t$dest;", 
+[(set Int32Regs:$dest, (int_nvvm_activemask))]>,
+ Requires<[hasPTX<62>, hasSM<30>]>;
+
 defm MATCH_ANY_SYNC_32 : MATCH_ANY_SYNC;
 defm MATCH_ANY_SYNC_64 : MATCH_ANY_SYNC


https://github.com/llvm/llvm-project/pull/79768

[clang] [llvm] [NVPTX] Add 'activemask' builtin and intrinsic support (PR #79768)

2024-01-28 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-llvm-ir

Author: Joseph Huber (jhuber6)


Changes

Summary:
This patch adds support for getting the 'activemask' instruction's value
without needing to use inline assembly. See the relevant PTX reference
for details.

https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-activemask


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


6 Files Affected:

- (modified) clang/include/clang/Basic/BuiltinsNVPTX.def (+7-1) 
- (modified) clang/test/CodeGen/builtins-nvptx.c (+8) 
- (modified) llvm/include/llvm/IR/IntrinsicsNVVM.td (+8) 
- (modified) llvm/lib/Target/NVPTX/NVPTX.td (+2-2) 
- (modified) llvm/lib/Target/NVPTX/NVPTXIntrinsics.td (+6) 
- (added) llvm/test/CodeGen/NVPTX/activemask.ll (+38) 


``diff
diff --git a/clang/include/clang/Basic/BuiltinsNVPTX.def 
b/clang/include/clang/Basic/BuiltinsNVPTX.def
index 0f2e8260143be78..506288547a15822 100644
--- a/clang/include/clang/Basic/BuiltinsNVPTX.def
+++ b/clang/include/clang/Basic/BuiltinsNVPTX.def
@@ -44,6 +44,7 @@
 #pragma push_macro("PTX42")
 #pragma push_macro("PTX60")
 #pragma push_macro("PTX61")
+#pragma push_macro("PTX62")
 #pragma push_macro("PTX63")
 #pragma push_macro("PTX64")
 #pragma push_macro("PTX65")
@@ -76,7 +77,8 @@
 #define PTX65 "ptx65|" PTX70
 #define PTX64 "ptx64|" PTX65
 #define PTX63 "ptx63|" PTX64
-#define PTX61 "ptx61|" PTX63
+#define PTX62 "ptx62|" PTX63
+#define PTX61 "ptx61|" PTX62
 #define PTX60 "ptx60|" PTX61
 #define PTX42 "ptx42|" PTX60
 
@@ -632,6 +634,9 @@ TARGET_BUILTIN(__nvvm_vote_any_sync, "bUib", "", PTX60)
 TARGET_BUILTIN(__nvvm_vote_uni_sync, "bUib", "", PTX60)
 TARGET_BUILTIN(__nvvm_vote_ballot_sync, "UiUib", "", PTX60)
 
+// Mask
+TARGET_BUILTIN(__nvvm_activemask, "i", "n", PTX62)
+
 // Match
 TARGET_BUILTIN(__nvvm_match_any_sync_i32, "UiUiUi", "", AND(SM_70,PTX60))
 TARGET_BUILTIN(__nvvm_match_any_sync_i64, "UiUiWi", "", AND(SM_70,PTX60))
@@ -1065,6 +1070,7 @@ TARGET_BUILTIN(__nvvm_getctarank_shared_cluster, "iv*3", 
"", AND(SM_90,PTX78))
 #pragma pop_macro("PTX42")
 #pragma pop_macro("PTX60")
 #pragma pop_macro("PTX61")
+#pragma pop_macro("PTX62")
 #pragma pop_macro("PTX63")
 #pragma pop_macro("PTX64")
 #pragma pop_macro("PTX65")
diff --git a/clang/test/CodeGen/builtins-nvptx.c 
b/clang/test/CodeGen/builtins-nvptx.c
index 353f3ebb608c2b1..e571d1cd61c41d9 100644
--- a/clang/test/CodeGen/builtins-nvptx.c
+++ b/clang/test/CodeGen/builtins-nvptx.c
@@ -165,6 +165,14 @@ __device__ void sync() {
 
 }
 
+__device__ void activemask() {
+
+// CHECK: call i32 @llvm.nvvm.activemask()
+
+  __nvvm_activemask(0);
+
+}
+
 
 // NVVM intrinsics
 
diff --git a/llvm/include/llvm/IR/IntrinsicsNVVM.td 
b/llvm/include/llvm/IR/IntrinsicsNVVM.td
index 5a5ba2592e1467e..0640fb1f74aa5eb 100644
--- a/llvm/include/llvm/IR/IntrinsicsNVVM.td
+++ b/llvm/include/llvm/IR/IntrinsicsNVVM.td
@@ -4599,6 +4599,14 @@ def int_nvvm_vote_ballot_sync :
 [IntrInaccessibleMemOnly, IntrConvergent, IntrNoCallback], 
"llvm.nvvm.vote.ballot.sync">,
   ClangBuiltin<"__nvvm_vote_ballot_sync">;
 
+//
+// ACTIVEMASK
+//
+def int_nvvm_activemask :
+  Intrinsic<[llvm_i32_ty], [],
+[IntrInaccessibleMemOnly, IntrConvergent, IntrNoCallback], 
"llvm.nvvm.activemask">,
+  ClangBuiltin<"__nvvm_activemask">;
+
 //
 // MATCH.SYNC
 //
diff --git a/llvm/lib/Target/NVPTX/NVPTX.td b/llvm/lib/Target/NVPTX/NVPTX.td
index f2a4ce381b40b48..a2233d3882b236d 100644
--- a/llvm/lib/Target/NVPTX/NVPTX.td
+++ b/llvm/lib/Target/NVPTX/NVPTX.td
@@ -40,7 +40,7 @@ foreach sm = [20, 21, 30, 32, 35, 37, 50, 52, 53,
 
 def SM90a: FeatureSM<"90a", 901>;
 
-foreach version = [32, 40, 41, 42, 43, 50, 60, 61, 63, 64, 65,
+foreach version = [32, 40, 41, 42, 43, 50, 60, 61, 62, 63, 64, 65,
70, 71, 72, 73, 74, 75, 76, 77, 78, 80, 81, 82, 83] in
   def PTX#version: FeaturePTX;
 
@@ -65,7 +65,7 @@ def : Proc<"sm_61", [SM61, PTX50]>;
 def : Proc<"sm_62", [SM62, PTX50]>;
 def : Proc<"sm_70", [SM70, PTX60]>;
 def : Proc<"sm_72", [SM72, PTX61]>;
-def : Proc<"sm_75", [SM75, PTX63]>;
+def : Proc<"sm_75", [SM75, PTX62, PTX63]>;
 def : Proc<"sm_80", [SM80, PTX70]>;
 def : Proc<"sm_86", [SM86, PTX71]>;
 def : Proc<"sm_87", [SM87, PTX74]>;
diff --git a/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td 
b/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td
index 33f1e4a43e072af..2df931597616566 100644
--- a/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td
+++ b/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td
@@ -263,6 +263,12 @@ multiclass MATCH_ANY_SYNC, hasSM<70>]>;
 }
 
+// activemask.b32
+def ACTIVEMASK : NVPTXInst<(outs Int32Regs:$dest), (ins),
+"activemask.b32 \t$dest;", 
+[(set Int32Regs:$dest, (int_nvvm_activemask))]>,
+ Requires<[hasPTX<62>, hasSM<30>]>;
+
 defm MATCH_ANY_SYNC_32 : MATCH_ANY_SYNC;
 defm MATCH_ANY_SYNC_64 : MATCH_ANY_SYNC


https://github.com/llvm/llvm-project/pull/79768
__

[clang] [llvm] [NVPTX] Add 'activemask' builtin and intrinsic support (PR #79768)

2024-01-28 Thread Joseph Huber via cfe-commits

https://github.com/jhuber6 created 
https://github.com/llvm/llvm-project/pull/79768

Summary:
This patch adds support for getting the 'activemask' instruction's value
without needing to use inline assembly. See the relevant PTX reference
for details.

https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-activemask


>From ea5305eef0a5a956f8dab055e23d693a21506050 Mon Sep 17 00:00:00 2001
From: Joseph Huber 
Date: Sun, 28 Jan 2024 14:57:05 -0600
Subject: [PATCH] [NVPTX] Add 'activemask' builtin and intrinsic support

Summary:
This patch adds support for getting the 'activemask' instruction's value
without needing to use inline assembly. See the relevant PTX reference
for details.

https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-activemask
---
 clang/include/clang/Basic/BuiltinsNVPTX.def |  8 -
 clang/test/CodeGen/builtins-nvptx.c |  8 +
 llvm/include/llvm/IR/IntrinsicsNVVM.td  |  8 +
 llvm/lib/Target/NVPTX/NVPTX.td  |  4 +--
 llvm/lib/Target/NVPTX/NVPTXIntrinsics.td|  6 
 llvm/test/CodeGen/NVPTX/activemask.ll   | 38 +
 6 files changed, 69 insertions(+), 3 deletions(-)
 create mode 100644 llvm/test/CodeGen/NVPTX/activemask.ll

diff --git a/clang/include/clang/Basic/BuiltinsNVPTX.def 
b/clang/include/clang/Basic/BuiltinsNVPTX.def
index 0f2e8260143be78..506288547a15822 100644
--- a/clang/include/clang/Basic/BuiltinsNVPTX.def
+++ b/clang/include/clang/Basic/BuiltinsNVPTX.def
@@ -44,6 +44,7 @@
 #pragma push_macro("PTX42")
 #pragma push_macro("PTX60")
 #pragma push_macro("PTX61")
+#pragma push_macro("PTX62")
 #pragma push_macro("PTX63")
 #pragma push_macro("PTX64")
 #pragma push_macro("PTX65")
@@ -76,7 +77,8 @@
 #define PTX65 "ptx65|" PTX70
 #define PTX64 "ptx64|" PTX65
 #define PTX63 "ptx63|" PTX64
-#define PTX61 "ptx61|" PTX63
+#define PTX62 "ptx62|" PTX63
+#define PTX61 "ptx61|" PTX62
 #define PTX60 "ptx60|" PTX61
 #define PTX42 "ptx42|" PTX60
 
@@ -632,6 +634,9 @@ TARGET_BUILTIN(__nvvm_vote_any_sync, "bUib", "", PTX60)
 TARGET_BUILTIN(__nvvm_vote_uni_sync, "bUib", "", PTX60)
 TARGET_BUILTIN(__nvvm_vote_ballot_sync, "UiUib", "", PTX60)
 
+// Mask
+TARGET_BUILTIN(__nvvm_activemask, "i", "n", PTX62)
+
 // Match
 TARGET_BUILTIN(__nvvm_match_any_sync_i32, "UiUiUi", "", AND(SM_70,PTX60))
 TARGET_BUILTIN(__nvvm_match_any_sync_i64, "UiUiWi", "", AND(SM_70,PTX60))
@@ -1065,6 +1070,7 @@ TARGET_BUILTIN(__nvvm_getctarank_shared_cluster, "iv*3", 
"", AND(SM_90,PTX78))
 #pragma pop_macro("PTX42")
 #pragma pop_macro("PTX60")
 #pragma pop_macro("PTX61")
+#pragma pop_macro("PTX62")
 #pragma pop_macro("PTX63")
 #pragma pop_macro("PTX64")
 #pragma pop_macro("PTX65")
diff --git a/clang/test/CodeGen/builtins-nvptx.c 
b/clang/test/CodeGen/builtins-nvptx.c
index 353f3ebb608c2b1..e571d1cd61c41d9 100644
--- a/clang/test/CodeGen/builtins-nvptx.c
+++ b/clang/test/CodeGen/builtins-nvptx.c
@@ -165,6 +165,14 @@ __device__ void sync() {
 
 }
 
+__device__ void activemask() {
+
+// CHECK: call i32 @llvm.nvvm.activemask()
+
+  __nvvm_activemask(0);
+
+}
+
 
 // NVVM intrinsics
 
diff --git a/llvm/include/llvm/IR/IntrinsicsNVVM.td 
b/llvm/include/llvm/IR/IntrinsicsNVVM.td
index 5a5ba2592e1467e..0640fb1f74aa5eb 100644
--- a/llvm/include/llvm/IR/IntrinsicsNVVM.td
+++ b/llvm/include/llvm/IR/IntrinsicsNVVM.td
@@ -4599,6 +4599,14 @@ def int_nvvm_vote_ballot_sync :
 [IntrInaccessibleMemOnly, IntrConvergent, IntrNoCallback], 
"llvm.nvvm.vote.ballot.sync">,
   ClangBuiltin<"__nvvm_vote_ballot_sync">;
 
+//
+// ACTIVEMASK
+//
+def int_nvvm_activemask :
+  Intrinsic<[llvm_i32_ty], [],
+[IntrInaccessibleMemOnly, IntrConvergent, IntrNoCallback], 
"llvm.nvvm.activemask">,
+  ClangBuiltin<"__nvvm_activemask">;
+
 //
 // MATCH.SYNC
 //
diff --git a/llvm/lib/Target/NVPTX/NVPTX.td b/llvm/lib/Target/NVPTX/NVPTX.td
index f2a4ce381b40b48..a2233d3882b236d 100644
--- a/llvm/lib/Target/NVPTX/NVPTX.td
+++ b/llvm/lib/Target/NVPTX/NVPTX.td
@@ -40,7 +40,7 @@ foreach sm = [20, 21, 30, 32, 35, 37, 50, 52, 53,
 
 def SM90a: FeatureSM<"90a", 901>;
 
-foreach version = [32, 40, 41, 42, 43, 50, 60, 61, 63, 64, 65,
+foreach version = [32, 40, 41, 42, 43, 50, 60, 61, 62, 63, 64, 65,
70, 71, 72, 73, 74, 75, 76, 77, 78, 80, 81, 82, 83] in
   def PTX#version: FeaturePTX;
 
@@ -65,7 +65,7 @@ def : Proc<"sm_61", [SM61, PTX50]>;
 def : Proc<"sm_62", [SM62, PTX50]>;
 def : Proc<"sm_70", [SM70, PTX60]>;
 def : Proc<"sm_72", [SM72, PTX61]>;
-def : Proc<"sm_75", [SM75, PTX63]>;
+def : Proc<"sm_75", [SM75, PTX62, PTX63]>;
 def : Proc<"sm_80", [SM80, PTX70]>;
 def : Proc<"sm_86", [SM86, PTX71]>;
 def : Proc<"sm_87", [SM87, PTX74]>;
diff --git a/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td 
b/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td
index 33f1e4a43e072af..2df931597616566 100644
--- a/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td
+++ b/llvm/lib/Targ

[clang] [llvm] [NVPTX} Add builtin support for 'globaltimer' (PR #79765)

2024-01-28 Thread Joseph Huber via cfe-commits

https://github.com/jhuber6 updated 
https://github.com/llvm/llvm-project/pull/79765

>From 9a07e319274f4ec2f7b12a174b7664af118de4e9 Mon Sep 17 00:00:00 2001
From: Joseph Huber 
Date: Mon, 29 Jan 2024 08:12:35 -0600
Subject: [PATCH] [NVPTX} Add builtin support for 'globaltimer'

Summary:
This patch adds support for `globaltimer` to match `clock` and
`clock64`. See the PTX ISA reference fro details. This patch does not
implement the `hi` or `lo` variants for brevity as they can be obtained
from this with the cost of an additional register.
https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#special-registers-globaltimer-globaltimer-lo-globaltimer-hi
---
 clang/include/clang/Basic/BuiltinsNVPTX.def |  1 +
 clang/test/CodeGen/builtins-nvptx.c |  4 +++-
 llvm/include/llvm/IR/IntrinsicsNVVM.td  |  2 ++
 llvm/lib/Target/NVPTX/NVPTXIntrinsics.td|  2 ++
 llvm/test/CodeGen/NVPTX/intrinsics.ll   | 12 
 5 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Basic/BuiltinsNVPTX.def 
b/clang/include/clang/Basic/BuiltinsNVPTX.def
index 0f2e8260143be78..57a229ded49f886 100644
--- a/clang/include/clang/Basic/BuiltinsNVPTX.def
+++ b/clang/include/clang/Basic/BuiltinsNVPTX.def
@@ -146,6 +146,7 @@ BUILTIN(__nvvm_read_ptx_sreg_lanemask_gt, "i", "nc")
 
 BUILTIN(__nvvm_read_ptx_sreg_clock, "i", "n")
 BUILTIN(__nvvm_read_ptx_sreg_clock64, "LLi", "n")
+BUILTIN(__nvvm_read_ptx_sreg_globaltimer, "LLi", "n")
 
 BUILTIN(__nvvm_read_ptx_sreg_pm0, "i", "n")
 BUILTIN(__nvvm_read_ptx_sreg_pm1, "i", "n")
diff --git a/clang/test/CodeGen/builtins-nvptx.c 
b/clang/test/CodeGen/builtins-nvptx.c
index 353f3ebb608c2b1..5aab6bee5b1cc1d 100644
--- a/clang/test/CodeGen/builtins-nvptx.c
+++ b/clang/test/CodeGen/builtins-nvptx.c
@@ -134,11 +134,13 @@ __device__ long long read_clocks() {
 
 // CHECK: call i32 @llvm.nvvm.read.ptx.sreg.clock()
 // CHECK: call i64 @llvm.nvvm.read.ptx.sreg.clock64()
+// CHECK: call i64 @llvm.nvvm.read.ptx.sreg.globaltimer()
 
   int a = __nvvm_read_ptx_sreg_clock();
   long long b = __nvvm_read_ptx_sreg_clock64();
+  long long c = __nvvm_read_ptx_sreg_globaltimer();
 
-  return a + b;
+  return a + b + c;
 }
 
 __device__ int read_pms() {
diff --git a/llvm/include/llvm/IR/IntrinsicsNVVM.td 
b/llvm/include/llvm/IR/IntrinsicsNVVM.td
index 5a5ba2592e1467e..8c9ed4a349ba998 100644
--- a/llvm/include/llvm/IR/IntrinsicsNVVM.td
+++ b/llvm/include/llvm/IR/IntrinsicsNVVM.td
@@ -4506,6 +4506,8 @@ def int_nvvm_read_ptx_sreg_lanemask_gt :
 def int_nvvm_read_ptx_sreg_clock : PTXReadNCSRegIntrinsic_r32<"clock">;
 def int_nvvm_read_ptx_sreg_clock64 : PTXReadNCSRegIntrinsic_r64<"clock64">;
 
+def int_nvvm_read_ptx_sreg_globaltimer : 
PTXReadNCSRegIntrinsic_r64<"globaltimer">;
+
 def int_nvvm_read_ptx_sreg_pm0 : PTXReadNCSRegIntrinsic_r32<"pm0">;
 def int_nvvm_read_ptx_sreg_pm1 : PTXReadNCSRegIntrinsic_r32<"pm1">;
 def int_nvvm_read_ptx_sreg_pm2 : PTXReadNCSRegIntrinsic_r32<"pm2">;
diff --git a/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td 
b/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td
index 33f1e4a43e072af..5c509b50411701a 100644
--- a/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td
+++ b/llvm/lib/Target/NVPTX/NVPTXIntrinsics.td
@@ -6364,6 +6364,8 @@ def INT_PTX_SREG_CLOCK :
 PTX_READ_SREG_R32<"clock", int_nvvm_read_ptx_sreg_clock>;
 def INT_PTX_SREG_CLOCK64 :
 PTX_READ_SREG_R64<"clock64", int_nvvm_read_ptx_sreg_clock64>;
+def INT_PTX_SREG_GLOBALTIMER :
+PTX_READ_SREG_R64<"globaltimer", int_nvvm_read_ptx_sreg_globaltimer>;
 
 def INT_PTX_SREG_PM0 : PTX_READ_SREG_R32<"pm0", int_nvvm_read_ptx_sreg_pm0>;
 def INT_PTX_SREG_PM1 : PTX_READ_SREG_R32<"pm1", int_nvvm_read_ptx_sreg_pm1>;
diff --git a/llvm/test/CodeGen/NVPTX/intrinsics.ll 
b/llvm/test/CodeGen/NVPTX/intrinsics.ll
index c09c7a72fd10181..26900543d922ba3 100644
--- a/llvm/test/CodeGen/NVPTX/intrinsics.ll
+++ b/llvm/test/CodeGen/NVPTX/intrinsics.ll
@@ -133,6 +133,17 @@ define i64 @test_clock64() {
   ret i64 %ret
 }
 
+; CHECK-LABEL: test_globaltimer
+define i64 @test_globaltimer() {
+; CHECK: mov.u64 %r{{.*}}, %globaltimer;
+  %a = tail call i64 @llvm.nvvm.read.ptx.sreg.globaltimer()
+; CHECK: mov.u64 %r{{.*}}, %globaltimer;
+  %b = tail call i64 @llvm.nvvm.read.ptx.sreg.globaltimer()
+  %ret = add i64 %a, %b
+; CHECK: ret
+  ret i64 %ret
+}
+
 declare float @llvm.fabs.f32(float)
 declare double @llvm.fabs.f64(double)
 declare float @llvm.nvvm.sqrt.f(float)
@@ -146,3 +157,4 @@ declare i64 @llvm.ctpop.i64(i64)
 declare i32 @llvm.nvvm.read.ptx.sreg.tid.x()
 declare i32 @llvm.nvvm.read.ptx.sreg.clock()
 declare i64 @llvm.nvvm.read.ptx.sreg.clock64()
+declare i64 @llvm.nvvm.read.ptx.sreg.globaltimer()

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


[clang] [clang] emit an error when the same identifier appears with both internal and external linkage in a translation unit (PR #78064)

2024-01-28 Thread via cfe-commits


@@ -4754,6 +4754,11 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult 
&Previous) {
 return New->setInvalidDecl();
   }
 
+  if (Old->getFormalLinkage() != New->getFormalLinkage()) {
+Diag(New->getLocation(), diag::err_multiple_linkage) << New->getDeclName();
+return New->setInvalidDecl();
+  }

elhewaty wrote:

@AaronBallman
> If the prior declaration specifies internal or external linkage, the linkage 
> of the identifier at the later declaration is the same as the linkage 
> specified at the prior declaration.

Then when should the declaration be an issue (https://godbolt.org/z/roE9xh76d)?
[Note: the diagnostic of clang and GCC is different.]
If the external linkage follows the previous linkage, when could the error 
happen?




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


[clang] [clang] Improved isSimpleTypeSpecifier (PR #79037)

2024-01-28 Thread Carl Peto via cfe-commits

https://github.com/carlos4242 updated 
https://github.com/llvm/llvm-project/pull/79037

>From fdc1e0dbec6821e292ba3da7770dbae22923db20 Mon Sep 17 00:00:00 2001
From: Carl Peto 
Date: Fri, 26 Jan 2024 14:20:48 +
Subject: [PATCH 1/2] [clang] - Sema::isSimpleTypeSpecifier return true
 for _Bool in c99 (currently returns false for _Bool, regardless of C
 dialect). (Fixes #72203) - replace the logic with a check for simple
 types and a proper check for a valid keyword in the appropriate dialect

---
 clang/include/clang/Lex/Token.h |  7 +++
 clang/include/clang/Sema/Sema.h |  2 +-
 clang/lib/Parse/ParseExpr.cpp   |  2 +-
 clang/lib/Parse/ParseObjc.cpp   |  2 +-
 clang/lib/Sema/SemaDecl.cpp | 26 +-
 5 files changed, 23 insertions(+), 16 deletions(-)

diff --git a/clang/include/clang/Lex/Token.h b/clang/include/clang/Lex/Token.h
index 1409e2c58b550df..3c707d469322139 100644
--- a/clang/include/clang/Lex/Token.h
+++ b/clang/include/clang/Lex/Token.h
@@ -196,6 +196,13 @@ class Token {
 PtrData = (void*) II;
   }
 
+  bool hasIdentifierInfo() {
+if (is(tok::raw_identifier) || isAnnotation() || isLiteral() ||
+is(tok::eof))
+  return false;
+return true;
+  }
+
   const void *getEofData() const {
 assert(is(tok::eof));
 return reinterpret_cast(PtrData);
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1f1cbd11ff73581..dc8797b2f12106f 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -2636,7 +2636,7 @@ class Sema final {
 
   void DiagnoseUseOfUnimplementedSelectors();
 
-  bool isSimpleTypeSpecifier(tok::TokenKind Kind) const;
+  bool isSimpleTypeSpecifier(Token &Tok) const;
 
   ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
  Scope *S, CXXScopeSpec *SS = nullptr,
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index e862856a08ca117..034d56c6b0e300a 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -1597,7 +1597,7 @@ ExprResult Parser::ParseCastExpression(CastParseKind 
ParseKind,
   if (TryAnnotateTypeOrScopeToken())
 return ExprError();
 
-  if (!Actions.isSimpleTypeSpecifier(Tok.getKind()))
+  if (!Actions.isSimpleTypeSpecifier(Tok))
 // We are trying to parse a simple-type-specifier but might not get 
such
 // a token after error recovery.
 return ExprError();
diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp
index 849fd1ac95a442e..4771b69eadb34b9 100644
--- a/clang/lib/Parse/ParseObjc.cpp
+++ b/clang/lib/Parse/ParseObjc.cpp
@@ -2971,7 +2971,7 @@ bool Parser::ParseObjCXXMessageReceiver(bool &IsExpr, 
void *&TypeOrExpr) {
   tok::annot_cxxscope))
 TryAnnotateTypeOrScopeToken();
 
-  if (!Actions.isSimpleTypeSpecifier(Tok.getKind())) {
+  if (!Actions.isSimpleTypeSpecifier(Tok)) {
 //   objc-receiver:
 // expression
 // Make sure any typos in the receiver are corrected or diagnosed, so that
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index f9bf1d14bdc4f68..4c7b12a53768c01 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -128,10 +128,15 @@ class TypeNameValidatorCCC final : public 
CorrectionCandidateCallback {
 } // end anonymous namespace
 
 /// Determine whether the token kind starts a simple-type-specifier.
-bool Sema::isSimpleTypeSpecifier(tok::TokenKind Kind) const {
+bool Sema::isSimpleTypeSpecifier(Token &Tok) const {
+  auto Kind = Tok.getKind();
+  auto LangOpts = getLangOpts();
+
   switch (Kind) {
-  // FIXME: Take into account the current language when deciding whether a
-  // token kind is a valid type specifier
+  case tok::annot_typename:
+  case tok::annot_decltype:
+return true;
+
   case tok::kw_short:
   case tok::kw_long:
   case tok::kw___int64:
@@ -156,24 +161,19 @@ bool Sema::isSimpleTypeSpecifier(tok::TokenKind Kind) 
const {
 #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
 #include "clang/Basic/TransformTypeTraits.def"
   case tok::kw___auto_type:
-return true;
-
-  case tok::annot_typename:
+  case tok::kw__Bool:
   case tok::kw_char16_t:
   case tok::kw_char32_t:
   case tok::kw_typeof:
-  case tok::annot_decltype:
   case tok::kw_decltype:
-return getLangOpts().CPlusPlus;
-
   case tok::kw_char8_t:
-return getLangOpts().Char8;
+if (!Tok.hasIdentifierInfo())
+  return false;
+return Tok.getIdentifierInfo()->isKeyword(LangOpts);
 
   default:
-break;
+return false;
   }
-
-  return false;
 }
 
 namespace {

>From 986324450006ad6dc761e85e7611a6e93a4ee2fb Mon Sep 17 00:00:00 2001
From: Carl Peto 
Date: Sun, 28 Jan 2024 20:32:17 +
Subject: [PATCH 2/2] PR feedback fixes for owenca

---
 clang/include/clang/Lex/Token.h |  7 ---
 clang/include/clang/Sema/Sema.h |  2 +-
 clang/lib/Sema/SemaDecl.cpp | 13 --

[clang] [polly] [clang-format] Add AllowShortType option for AlwaysBreakAfterReturnType. (PR #78011)

2024-01-28 Thread Björn Schäpers via cfe-commits

HazardyKnusperkeks wrote:

> @mydeveloperday @HazardyKnusperkeks @rymiel this patch fixes a very old bug 
> and will cause behavior changes whether the default is changed to the new 
> `AllowShortType` or left at `None`. Which way should we go?

What would change if the default was kept at `None`? I don't see it.

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


[clang] [polly] [clang-format] Add AllowShortType option for AlwaysBreakAfterReturnType. (PR #78011)

2024-01-28 Thread Björn Schäpers via cfe-commits


@@ -474,7 +474,7 @@ class State:
 opts = sorted(opts, key=lambda x: x.name)
 options_text = "\n\n".join(map(str, opts))
 
-with open(DOC_FILE) as f:
+with open(DOC_FILE, encoding="utf-8") as f:

HazardyKnusperkeks wrote:

Unrelated.

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


[clang] [polly] [clang-format] Add AllowShortType option for AlwaysBreakAfterReturnType. (PR #78011)

2024-01-28 Thread Björn Schäpers via cfe-commits


@@ -922,8 +922,23 @@ struct FormatStyle {
 ///   };
 ///   int f();
 ///   int f() { return 1; }
+///   int f::
+///   bar();
 /// \endcode
 RTBS_None,
+/// Break after return type automatically, while allowing a break after
+/// short return types.

HazardyKnusperkeks wrote:

This should be rephrased, I know what the option means, but I couldn't figure 
it out of the description.

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


[clang] [polly] [clang-format] Add AllowShortType option for AlwaysBreakAfterReturnType. (PR #78011)

2024-01-28 Thread Björn Schäpers via cfe-commits


@@ -922,8 +922,23 @@ struct FormatStyle {
 ///   };
 ///   int f();
 ///   int f() { return 1; }
+///   int f::
+///   bar();
 /// \endcode
 RTBS_None,
+/// Break after return type automatically, while allowing a break after
+/// short return types.
+/// ``PenaltyReturnTypeOnItsOwnLine`` is taken into account.
+/// \code
+///   class A {
+/// int f() { return 0; };
+///   };
+///   int f();
+///   int f() { return 1; }
+///   int
+///   
f::bar();
+/// \endcode
+RTBS_AllowShortType,
 /// Always break after the return type.
 /// \code
 ///   class A {

HazardyKnusperkeks wrote:

Shouldn't it be added in this block also?

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


[polly] [clang] [clang-format] Add AllowShortType option for AlwaysBreakAfterReturnType. (PR #78011)

2024-01-28 Thread Björn Schäpers via cfe-commits


@@ -922,8 +922,23 @@ struct FormatStyle {
 ///   };
 ///   int f();
 ///   int f() { return 1; }
+///   int f::

HazardyKnusperkeks wrote:

I'd go with short names, and just name them like `LongName` or similar and just 
break. This is documentation which should convey the settings, and must not 
break with LLVMs standard column limit.

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


[clang] [polly] [clang-format] Add AllowShortType option for AlwaysBreakAfterReturnType. (PR #78011)

2024-01-28 Thread Björn Schäpers via cfe-commits


@@ -587,7 +590,7 @@ bool ContinuationIndenter::mustBreak(const LineState 
&State) {
   !State.Line->ReturnTypeWrapped &&
   // Don't break before a C# function when no break after return type.
   (!Style.isCSharp() ||
-   Style.AlwaysBreakAfterReturnType != FormatStyle::RTBS_None) &&
+   Style.AlwaysBreakAfterReturnType > FormatStyle::RTBS_AllowShortType) &&

HazardyKnusperkeks wrote:

I know Owen proposed this. But I have to note, that I personally really don't 
like greater or lesser with enums.

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


[clang] [compiler-rt] [clang-tools-extra] [flang] [llvm] [VPlan] Replace VPRecipeOrVPValue with VP2VP recipe simplification. (PR #76090)

2024-01-28 Thread Florian Hahn via cfe-commits


@@ -8292,13 +8271,13 @@ VPRecipeOrVPValueTy VPRecipeBuilder::tryToBlend(PHINode 
*Phi,
   for (unsigned In = 0; In < NumIncoming; In++) {
 VPValue *EdgeMask =
 createEdgeMask(Phi->getIncomingBlock(In), Phi->getParent(), *Plan);
-assert((EdgeMask || NumIncoming == 1) &&
+assert((EdgeMask || NumIncoming == 1 || Operands[In] == Operands[0]) &&

fhahn wrote:

Adjusted, thanks!

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


[clang] [compiler-rt] [clang-tools-extra] [llvm] [flang] [VPlan] Replace VPRecipeOrVPValue with VP2VP recipe simplification. (PR #76090)

2024-01-28 Thread Florian Hahn via cfe-commits


@@ -88,8 +86,8 @@ class VPRecipeBuilder {
   /// or a new VPBlendRecipe otherwise. Currently all such phi nodes are turned

fhahn wrote:

Updated, thanks!

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


[flang] [clang-tools-extra] [llvm] [clang] [compiler-rt] [VPlan] Replace VPRecipeOrVPValue with VP2VP recipe simplification. (PR #76090)

2024-01-28 Thread Florian Hahn via cfe-commits


@@ -116,12 +111,11 @@ class VPRecipeBuilder {
 
   /// Check if an existing VPValue can be used for \p Instr or a recipe can be
   /// create for \p I withing the given VF \p Range. If an existing VPValue can

fhahn wrote:

Updated, thanks!

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


[llvm] [flang] [compiler-rt] [clang] [clang-tools-extra] [VPlan] Replace VPRecipeOrVPValue with VP2VP recipe simplification. (PR #76090)

2024-01-28 Thread Florian Hahn via cfe-commits


@@ -8999,6 +8963,18 @@ void 
LoopVectorizationPlanner::adjustRecipesForReductions(
 LinkVPBB->insert(FMulRecipe, CurrentLink->getIterator());
 VecOp = FMulRecipe;
   } else {
+auto *Blend = dyn_cast(CurrentLink);
+if (PhiR->isInLoop() && Blend) {
+  assert(Blend->getNumIncomingValues() == 2);
+  assert(any_of(Blend->operands(),
+[PhiR](VPValue *Op) { return Op == PhiR; }));
+  if (Blend->getIncomingValue(0) == PhiR)
+Blend->replaceAllUsesWith(Blend->getIncomingValue(1));
+  else

fhahn wrote:

done, thanks!

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


[clang] [llvm] [clang-tools-extra] [flang] [compiler-rt] [VPlan] Replace VPRecipeOrVPValue with VP2VP recipe simplification. (PR #76090)

2024-01-28 Thread Florian Hahn via cfe-commits


@@ -8999,6 +8963,18 @@ void 
LoopVectorizationPlanner::adjustRecipesForReductions(
 LinkVPBB->insert(FMulRecipe, CurrentLink->getIterator());
 VecOp = FMulRecipe;
   } else {
+auto *Blend = dyn_cast(CurrentLink);
+if (PhiR->isInLoop() && Blend) {
+  assert(Blend->getNumIncomingValues() == 2);

fhahn wrote:

added, thanks!

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


  1   2   >