[clang] [X86][test] Added extra cet tests (PR #88736)

2024-04-17 Thread Isha Agarwal via cfe-commits

https://github.com/iagarwa updated 
https://github.com/llvm/llvm-project/pull/88736

>From 821c61fb4905b491176e00ea9ed322aad04c98e3 Mon Sep 17 00:00:00 2001
From: Isha Agarwal 
Date: Mon, 15 Apr 2024 06:22:34 -0700
Subject: [PATCH 1/2] [X86][test] Added extra cet tests

Updated cet test to:
-Check different modules based on different cet options
-Added negative tests also

Signed-off-by: Isha Agarwal 
---
 clang/test/CodeGen/X86/x86-cf-protection.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/clang/test/CodeGen/X86/x86-cf-protection.c 
b/clang/test/CodeGen/X86/x86-cf-protection.c
index ba63b9e17c6f63..abc6ed63d61289 100644
--- a/clang/test/CodeGen/X86/x86-cf-protection.c
+++ b/clang/test/CodeGen/X86/x86-cf-protection.c
@@ -2,6 +2,10 @@
 // RUN: %clang_cc1 -E -triple i386 -dM -o - -fcf-protection=branch %s | 
FileCheck %s --check-prefix=BRANCH
 // RUN: %clang_cc1 -E -triple i386 -dM -o - -fcf-protection=full %s   | 
FileCheck %s --check-prefix=FULL
 // RUN: not %clang_cc1 -emit-llvm-only -triple i386 -target-cpu pentium-mmx 
-fcf-protection=branch %s 2>&1 | FileCheck %s --check-prefix=NOCFPROT
+// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=branch %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROT
+// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=full %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROTF
+// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=none %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROTNONE
+// RUN: %clang_cc1 -E -triple=x86_64 -dM -o - -fcf-protection=none %s | 
FileCheck %s --check-prefix=NOTCET
 
 // RETURN: #define __CET__ 2
 // BRANCH: #define __CET__ 1
@@ -9,5 +13,9 @@
 // CFPROT: !{i32 8, !"cf-protection-branch", i32 1}
 
 // NOCFPROT: error: option 'cf-protection=branch' cannot be specified on this 
target
+// CFPROTF: !{i32 8, !"cf-protection-return", i32 1}
+// CFPROTF-NEXT: !{i32 8, !"cf-protection-branch", i32 1}
+// CFPROTNONE-NOT: cf-protection-branch
+// NOTCET-NOT: #define __CET__
 
 void foo() {}

>From ac2078274b367896aef6840d04e24a72012cf0ba Mon Sep 17 00:00:00 2001
From: Isha Agarwal 
Date: Mon, 15 Apr 2024 21:09:54 -0700
Subject: [PATCH 2/2] Address comments

---
 clang/test/CodeGen/X86/x86-cf-protection.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/clang/test/CodeGen/X86/x86-cf-protection.c 
b/clang/test/CodeGen/X86/x86-cf-protection.c
index abc6ed63d61289..02aee868936b40 100644
--- a/clang/test/CodeGen/X86/x86-cf-protection.c
+++ b/clang/test/CodeGen/X86/x86-cf-protection.c
@@ -1,21 +1,22 @@
 // RUN: %clang_cc1 -E -triple i386 -dM -o - -fcf-protection=return %s | 
FileCheck %s --check-prefix=RETURN
 // RUN: %clang_cc1 -E -triple i386 -dM -o - -fcf-protection=branch %s | 
FileCheck %s --check-prefix=BRANCH
 // RUN: %clang_cc1 -E -triple i386 -dM -o - -fcf-protection=full %s   | 
FileCheck %s --check-prefix=FULL
+// RUN: %clang_cc1 -E -triple=x86_64 -dM -o - -fcf-protection=none %s | 
FileCheck %s --check-prefix=NOTCET
 // RUN: not %clang_cc1 -emit-llvm-only -triple i386 -target-cpu pentium-mmx 
-fcf-protection=branch %s 2>&1 | FileCheck %s --check-prefix=NOCFPROT
-// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=branch %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROT
+// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=return %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROTR
+// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=branch %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROTB
 // RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=full %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROTF
 // RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=none %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROTNONE
-// RUN: %clang_cc1 -E -triple=x86_64 -dM -o - -fcf-protection=none %s | 
FileCheck %s --check-prefix=NOTCET
 
 // RETURN: #define __CET__ 2
 // BRANCH: #define __CET__ 1
 // FULL: #define __CET__ 3
-// CFPROT: !{i32 8, !"cf-protection-branch", i32 1}
-
+// NOTCET-NOT: #define __CET__
 // NOCFPROT: error: option 'cf-protection=branch' cannot be specified on this 
target
+// CFPROTR: !{i32 8, !"cf-protection-return", i32 1}
+// CFPROTB: !{i32 8, !"cf-protection-branch", i32 1}
 // CFPROTF: !{i32 8, !"cf-protection-return", i32 1}
 // CFPROTF-NEXT: !{i32 8, !"cf-protection-branch", i32 1}
-// CFPROTNONE-NOT: cf-protection-branch
-// NOTCET-NOT: #define __CET__
+// CFPROTNONE-NOT: cf-protection-
 
 void foo() {}

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


[clang] [llvm] [InstCombine] Add canonicalization of `sitofp` -> `uitofp nneg` (PR #88299)

2024-04-17 Thread Yingwei Zheng via cfe-commits


@@ -1964,11 +1964,25 @@ Instruction *InstCombinerImpl::visitFPToSI(FPToSIInst 
&FI) {
 }
 
 Instruction *InstCombinerImpl::visitUIToFP(CastInst &CI) {
-  return commonCastTransforms(CI);
+  if (Instruction *R = commonCastTransforms(CI))
+return R;
+  if (!CI.hasNonNeg() && isKnownNonNegative(CI.getOperand(0), SQ)) {
+CI.setNonNeg();
+return &CI;
+  }
+  return nullptr;
 }
 
 Instruction *InstCombinerImpl::visitSIToFP(CastInst &CI) {
-  return commonCastTransforms(CI);
+  if (Instruction *R = commonCastTransforms(CI))
+return R;
+  if (isKnownNonNegative(CI.getOperand(0), SQ)) {
+auto UI =

dtcxzyw wrote:

@goldsteinn We always use `auto *` for pointers.

https://llvm.org/docs/CodingStandards.html#beware-unnecessary-copies-with-auto

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


[clang] [Clang][Parse] Diagnose requires expressions with explicit object parameters (PR #88974)

2024-04-17 Thread via cfe-commits

https://github.com/cor3ntin commented:

Thanks for spotting that. I think there are further cases that I'm not sure we 
protect against

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


[clang] [Clang][Parse] Diagnose requires expressions with explicit object parameters (PR #88974)

2024-04-17 Thread via cfe-commits

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


[clang] [Clang][Parse] Diagnose requires expressions with explicit object parameters (PR #88974)

2024-04-17 Thread via cfe-commits


@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s
+
+auto x0 = requires (this int) { true; }; // expected-error {{a requires clause 
cannot have an explicit object parameter}}
+auto x1 = requires (int, this int) { true; }; // expected-error {{a requires 
clause cannot have an explicit object parameter}}

cor3ntin wrote:

Can you add a test for `template  void f()` ?

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


[clang] [clang]Treat arguments to builtin type traits as template type arguments (PR #87132)

2024-04-17 Thread via cfe-commits

cor3ntin wrote:

@AMP999 Feel free to merge!

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


[clang] [clang-rel] Clone the llvm::Modules to avoid invalid memory access. (PR #89031)

2024-04-17 Thread Vassil Vassilev via cfe-commits

https://github.com/vgvassilev created 
https://github.com/llvm/llvm-project/pull/89031

Clang's CodeGen is designed to work with a single llvm::Module. In many cases 
for convenience various CodeGen parts have a reference to the llvm::Module 
(TheModule or Module) which does not change when a new module is pushed. 
However, the execution engine wants to take ownership of the module which does 
not map well to CodeGen's design. To work this around we clone the module and 
pass it down.

With some effort it is possible to teach CodeGen to ask the CodeGenModule for 
its current module and that would have an overall positive impact on CodeGen 
improving the encapsulation of various parts but that's not resilient to future 
regression.

This patch takes a more conservative approach and clones the llvm::Module 
before passing it to the Jit. That's also not bullet proof because we have to 
guarantee that CodeGen does not write on the blueprint. At that stage that 
seems more consistent to what clang-repl already does to map each partial 
translation unit to a new Module.

This change will fixes a long-standing invalid memory access reported by 
valgrind when we enable the TBAA optimization passes. It also unblock progress 
on llvm/llvm-project#84758.

>From 4805b4b11fc57bb7523b620c0a770d082e1dde2a Mon Sep 17 00:00:00 2001
From: Vassil Vassilev 
Date: Wed, 17 Apr 2024 07:12:40 +
Subject: [PATCH] [clang-rel] Clone the llvm::Modules to avoid invalid memory
 access.

Clang's CodeGen is designed to work with a single llvm::Module. In many cases
for convenience various CodeGen parts have a reference to the llvm::Module
(TheModule or Module) which does not change when a new module is pushed.
However, the execution engine wants to take ownership of the module which does
not map well to CodeGen's design. To work this around we clone the module and
pass it down.

With some effort it is possible to teach CodeGen to ask the CodeGenModule for
its current module and that would have an overall positive impact on CodeGen
improving the encapsulation of various parts but that's not resilient to future
regression.

This patch takes a more conservative approach and clones the llvm::Module before
passing it to the Jit. That's also not bullet proof because we have to guarantee
that CodeGen does not write on the blueprint. At that stage that seems more
consistent to what clang-repl already does to map each partial translation unit
to a new Module.

This change will fixes a long-standing invalid memory access reported by
valgrind when we enable the TBAA optimization passes. It also unblock progress
on llvm/llvm-project#84758.
---
 clang/lib/Interpreter/IncrementalExecutor.cpp | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Interpreter/IncrementalExecutor.cpp 
b/clang/lib/Interpreter/IncrementalExecutor.cpp
index 6f036107c14a9c..e87f43f077f379 100644
--- a/clang/lib/Interpreter/IncrementalExecutor.cpp
+++ b/clang/lib/Interpreter/IncrementalExecutor.cpp
@@ -28,6 +28,7 @@
 #include "llvm/IR/Module.h"
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/TargetSelect.h"
+#include "llvm/Transforms/Utils/Cloning.h"
 
 // Force linking some of the runtimes that helps attaching to a debugger.
 LLVM_ATTRIBUTE_USED void linkComponents() {
@@ -73,7 +74,15 @@ llvm::Error 
IncrementalExecutor::addModule(PartialTranslationUnit &PTU) {
   Jit->getMainJITDylib().createResourceTracker();
   ResourceTrackers[&PTU] = RT;
 
-  return Jit->addIRModule(RT, {std::move(PTU.TheModule), TSCtx});
+  // Clang's CodeGen is designed to work with a single llvm::Module. In many
+  // cases for convenience various CodeGen parts have a reference to the
+  // llvm::Module (TheModule or Module) which does not change when a new module
+  // is pushed. However, the execution engine wants to take ownership of the
+  // module which does not map well to CodeGen's design. To work this around
+  // we clone the module and pass it down.
+  std::unique_ptr ModuleClone = 
llvm::CloneModule(*PTU.TheModule);
+
+  return Jit->addIRModule(RT, {std::move(ModuleClone), TSCtx});
 }
 
 llvm::Error IncrementalExecutor::removeModule(PartialTranslationUnit &PTU) {

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


[clang] [clang-rel] Clone the llvm::Modules to avoid invalid memory access. (PR #89031)

2024-04-17 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Vassil Vassilev (vgvassilev)


Changes

Clang's CodeGen is designed to work with a single llvm::Module. In many cases 
for convenience various CodeGen parts have a reference to the llvm::Module 
(TheModule or Module) which does not change when a new module is pushed. 
However, the execution engine wants to take ownership of the module which does 
not map well to CodeGen's design. To work this around we clone the module and 
pass it down.

With some effort it is possible to teach CodeGen to ask the CodeGenModule for 
its current module and that would have an overall positive impact on CodeGen 
improving the encapsulation of various parts but that's not resilient to future 
regression.

This patch takes a more conservative approach and clones the llvm::Module 
before passing it to the Jit. That's also not bullet proof because we have to 
guarantee that CodeGen does not write on the blueprint. At that stage that 
seems more consistent to what clang-repl already does to map each partial 
translation unit to a new Module.

This change will fixes a long-standing invalid memory access reported by 
valgrind when we enable the TBAA optimization passes. It also unblock progress 
on llvm/llvm-project#84758.

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


1 Files Affected:

- (modified) clang/lib/Interpreter/IncrementalExecutor.cpp (+10-1) 


``diff
diff --git a/clang/lib/Interpreter/IncrementalExecutor.cpp 
b/clang/lib/Interpreter/IncrementalExecutor.cpp
index 6f036107c14a9c..e87f43f077f379 100644
--- a/clang/lib/Interpreter/IncrementalExecutor.cpp
+++ b/clang/lib/Interpreter/IncrementalExecutor.cpp
@@ -28,6 +28,7 @@
 #include "llvm/IR/Module.h"
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/TargetSelect.h"
+#include "llvm/Transforms/Utils/Cloning.h"
 
 // Force linking some of the runtimes that helps attaching to a debugger.
 LLVM_ATTRIBUTE_USED void linkComponents() {
@@ -73,7 +74,15 @@ llvm::Error 
IncrementalExecutor::addModule(PartialTranslationUnit &PTU) {
   Jit->getMainJITDylib().createResourceTracker();
   ResourceTrackers[&PTU] = RT;
 
-  return Jit->addIRModule(RT, {std::move(PTU.TheModule), TSCtx});
+  // Clang's CodeGen is designed to work with a single llvm::Module. In many
+  // cases for convenience various CodeGen parts have a reference to the
+  // llvm::Module (TheModule or Module) which does not change when a new module
+  // is pushed. However, the execution engine wants to take ownership of the
+  // module which does not map well to CodeGen's design. To work this around
+  // we clone the module and pass it down.
+  std::unique_ptr ModuleClone = 
llvm::CloneModule(*PTU.TheModule);
+
+  return Jit->addIRModule(RT, {std::move(ModuleClone), TSCtx});
 }
 
 llvm::Error IncrementalExecutor::removeModule(PartialTranslationUnit &PTU) {

``




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


[clang] [clang-rel] Clone the llvm::Modules to avoid invalid memory access. (PR #89031)

2024-04-17 Thread Vassil Vassilev via cfe-commits


@@ -73,7 +74,15 @@ llvm::Error 
IncrementalExecutor::addModule(PartialTranslationUnit &PTU) {
   Jit->getMainJITDylib().createResourceTracker();
   ResourceTrackers[&PTU] = RT;
 
-  return Jit->addIRModule(RT, {std::move(PTU.TheModule), TSCtx});

vgvassilev wrote:

Even if we are attaching a resource tracker (`RT`) the Jit decides to destroy 
the `ThreadSafeModule`.

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


[clang] [clang-repl] Set up executor implicitly to account for init PTUs (PR #84758)

2024-04-17 Thread Vassil Vassilev via cfe-commits
Stefan =?utf-8?q?Gr=C3=A4nitz?= 
Message-ID:
In-Reply-To: 



@@ -14,7 +14,7 @@ struct A { int a; A(int a) : a(a) {} virtual ~A(); };
 // PartialTranslationUnit.
 inline A::~A() { printf("~A(%d)\n", a); }
 
-// Create one instance with new and delete it.
+// Create one instance with new and delete it. We crash here now:
 A *a1 = new A(1);

vgvassilev wrote:

https://github.com/llvm/llvm-project/pull/89031 should unblock this PR.

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


[clang] [clang-rel] Clone the llvm::Modules to avoid invalid memory access. (PR #89031)

2024-04-17 Thread Vassil Vassilev via cfe-commits

https://github.com/vgvassilev updated 
https://github.com/llvm/llvm-project/pull/89031

>From d396330fd004db50b3808e491cb45847888bb651 Mon Sep 17 00:00:00 2001
From: Vassil Vassilev 
Date: Wed, 17 Apr 2024 07:12:40 +
Subject: [PATCH] [clang-repl] Clone the llvm::Modules to avoid invalid memory
 access.

Clang's CodeGen is designed to work with a single llvm::Module. In many cases
for convenience various CodeGen parts have a reference to the llvm::Module
(TheModule or Module) which does not change when a new module is pushed.
However, the execution engine wants to take ownership of the module which does
not map well to CodeGen's design. To work this around we clone the module and
pass it down.

With some effort it is possible to teach CodeGen to ask the CodeGenModule for
its current module and that would have an overall positive impact on CodeGen
improving the encapsulation of various parts but that's not resilient to future
regression.

This patch takes a more conservative approach and clones the llvm::Module before
passing it to the Jit. That's also not bullet proof because we have to guarantee
that CodeGen does not write on the blueprint. At that stage that seems more
consistent to what clang-repl already does to map each partial translation unit
to a new Module.

This change will fixes a long-standing invalid memory access reported by
valgrind when we enable the TBAA optimization passes. It also unblock progress
on llvm/llvm-project#84758.
---
 clang/lib/Interpreter/IncrementalExecutor.cpp | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Interpreter/IncrementalExecutor.cpp 
b/clang/lib/Interpreter/IncrementalExecutor.cpp
index 6f036107c14a9c..e87f43f077f379 100644
--- a/clang/lib/Interpreter/IncrementalExecutor.cpp
+++ b/clang/lib/Interpreter/IncrementalExecutor.cpp
@@ -28,6 +28,7 @@
 #include "llvm/IR/Module.h"
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/TargetSelect.h"
+#include "llvm/Transforms/Utils/Cloning.h"
 
 // Force linking some of the runtimes that helps attaching to a debugger.
 LLVM_ATTRIBUTE_USED void linkComponents() {
@@ -73,7 +74,15 @@ llvm::Error 
IncrementalExecutor::addModule(PartialTranslationUnit &PTU) {
   Jit->getMainJITDylib().createResourceTracker();
   ResourceTrackers[&PTU] = RT;
 
-  return Jit->addIRModule(RT, {std::move(PTU.TheModule), TSCtx});
+  // Clang's CodeGen is designed to work with a single llvm::Module. In many
+  // cases for convenience various CodeGen parts have a reference to the
+  // llvm::Module (TheModule or Module) which does not change when a new module
+  // is pushed. However, the execution engine wants to take ownership of the
+  // module which does not map well to CodeGen's design. To work this around
+  // we clone the module and pass it down.
+  std::unique_ptr ModuleClone = 
llvm::CloneModule(*PTU.TheModule);
+
+  return Jit->addIRModule(RT, {std::move(ModuleClone), TSCtx});
 }
 
 llvm::Error IncrementalExecutor::removeModule(PartialTranslationUnit &PTU) {

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


[clang] [clang-repl] Clone the llvm::Modules to avoid invalid memory access. (PR #89031)

2024-04-17 Thread Vassil Vassilev via cfe-commits

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


[clang] Fix the double space and double attribute printing of the final keyword. (PR #88600)

2024-04-17 Thread Vassil Vassilev via cfe-commits


@@ -275,13 +278,15 @@ void DeclPrinter::prettyPrintAttributes(const Decl *D,
   if (Pos != AttrPosAsWritten::Left)
 Out << ' ';
   A->printPretty(Out, Policy);
+  hasPrinted = true;
   if (Pos == AttrPosAsWritten::Left)
 Out << ' ';
 }
 break;
   }
 }
   }
+  return hasPrinted;

vgvassilev wrote:

I was thinking to use something like that but I believe the boolean flag is 
more readable. I'd like to keep it the way it is.

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


[clang] Fix the double space and double attribute printing of the final keyword. (PR #88600)

2024-04-17 Thread Vassil Vassilev via cfe-commits

https://github.com/vgvassilev updated 
https://github.com/llvm/llvm-project/pull/88600

>From 9b2bb9068cbefcfffd0931fbbee46b1a0f536a4f Mon Sep 17 00:00:00 2001
From: Vassil Vassilev 
Date: Sat, 13 Apr 2024 06:39:34 +
Subject: [PATCH 1/2] Fix the double space and double attribute printing of the
 final keyword.

Fixes #56517.
---
 clang/lib/AST/DeclPrinter.cpp   | 36 +++-
 clang/test/SemaCXX/cxx11-attr-print.cpp |  5 +++
 clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl |  4 +--
 clang/unittests/AST/DeclPrinterTest.cpp | 37 -
 clang/utils/TableGen/ClangAttrEmitter.cpp   |  2 +-
 5 files changed, 57 insertions(+), 27 deletions(-)

diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp
index 6afdb6cfccb142..444780947f2075 100644
--- a/clang/lib/AST/DeclPrinter.cpp
+++ b/clang/lib/AST/DeclPrinter.cpp
@@ -119,7 +119,7 @@ namespace {
 void printTemplateArguments(llvm::ArrayRef Args,
 const TemplateParameterList *Params);
 enum class AttrPosAsWritten { Default = 0, Left, Right };
-void
+bool
 prettyPrintAttributes(const Decl *D,
   AttrPosAsWritten Pos = AttrPosAsWritten::Default);
 void prettyPrintPragmas(Decl *D);
@@ -252,16 +252,19 @@ static DeclPrinter::AttrPosAsWritten 
getPosAsWritten(const Attr *A,
   return DeclPrinter::AttrPosAsWritten::Right;
 }
 
-void DeclPrinter::prettyPrintAttributes(const Decl *D,
+// returns true if an attribute was printed.
+bool DeclPrinter::prettyPrintAttributes(const Decl *D,
 AttrPosAsWritten Pos /*=Default*/) {
-  if (Policy.PolishForDeclaration)
-return;
+  bool hasPrinted = false;
 
   if (D->hasAttrs()) {
 const AttrVec &Attrs = D->getAttrs();
 for (auto *A : Attrs) {
   if (A->isInherited() || A->isImplicit())
 continue;
+  // Don't strip out the keyword attributes, they aren't regular 
attributes.
+  if (Policy.PolishForDeclaration && !A->isKeywordAttribute())
+continue;
   switch (A->getKind()) {
 #define ATTR(X)
 #define PRAGMA_SPELLING_ATTR(X) case attr::X:
@@ -275,6 +278,7 @@ void DeclPrinter::prettyPrintAttributes(const Decl *D,
   if (Pos != AttrPosAsWritten::Left)
 Out << ' ';
   A->printPretty(Out, Policy);
+  hasPrinted = true;
   if (Pos == AttrPosAsWritten::Left)
 Out << ' ';
 }
@@ -282,6 +286,7 @@ void DeclPrinter::prettyPrintAttributes(const Decl *D,
   }
 }
   }
+  return hasPrinted;
 }
 
 void DeclPrinter::prettyPrintPragmas(Decl *D) {
@@ -1060,12 +1065,15 @@ void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) {
   // FIXME: add printing of pragma attributes if required.
   if (!Policy.SuppressSpecifiers && D->isModulePrivate())
 Out << "__module_private__ ";
-  Out << D->getKindName();
 
-  prettyPrintAttributes(D);
+  Out << D->getKindName() << ' ';
 
-  if (D->getIdentifier()) {
+  // FIXME: Move before printing the decl kind to match the behavior of the
+  // attribute printing for variables and function where they are printed 
first.
+  if (prettyPrintAttributes(D, AttrPosAsWritten::Left))
 Out << ' ';
+
+  if (D->getIdentifier()) {
 if (auto *NNS = D->getQualifier())
   NNS->print(Out, Policy);
 Out << *D;
@@ -1082,16 +1090,13 @@ void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) {
 }
   }
 
-  if (D->hasDefinition()) {
-if (D->hasAttr()) {
-  Out << " final";
-}
-  }
+  prettyPrintAttributes(D, AttrPosAsWritten::Right);
 
   if (D->isCompleteDefinition()) {
+Out << ' ';
 // Print the base classes
 if (D->getNumBases()) {
-  Out << " : ";
+  Out << ": ";
   for (CXXRecordDecl::base_class_iterator Base = D->bases_begin(),
  BaseEnd = D->bases_end(); Base != BaseEnd; ++Base) {
 if (Base != D->bases_begin())
@@ -1110,14 +1115,15 @@ void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) {
 if (Base->isPackExpansion())
   Out << "...";
   }
+  Out << ' ';
 }
 
 // Print the class definition
 // FIXME: Doesn't print access specifiers, e.g., "public:"
 if (Policy.TerseOutput) {
-  Out << " {}";
+  Out << "{}";
 } else {
-  Out << " {\n";
+  Out << "{\n";
   VisitDeclContext(D);
   Indent() << "}";
 }
diff --git a/clang/test/SemaCXX/cxx11-attr-print.cpp 
b/clang/test/SemaCXX/cxx11-attr-print.cpp
index a169d1b4409b4d..2b084018bc0662 100644
--- a/clang/test/SemaCXX/cxx11-attr-print.cpp
+++ b/clang/test/SemaCXX/cxx11-attr-print.cpp
@@ -87,3 +87,8 @@ template struct S;
 
 // CHECK: using Small2 {{\[}}[gnu::mode(byte)]] = int;
 using Small2 [[gnu::mode(byte)]] = int;
+
+class FinalNonTemplate final {};
+// CHECK: class FinalNonTemplate final {
+template  class FinalTemplate final {};
+// CHECK: template  class FinalTemplate final {
diff --git a/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl 
b/clang/tes

[clang] [clang-format] Annotate ampamp after new/delete as BinaryOperator (PR #89033)

2024-04-17 Thread Owen Pan via cfe-commits

https://github.com/owenca created 
https://github.com/llvm/llvm-project/pull/89033

Fixes #78789.

>From 0e2d91d20a1c318868f2e791d859a047b83f0277 Mon Sep 17 00:00:00 2001
From: Owen Pan 
Date: Wed, 17 Apr 2024 00:39:36 -0700
Subject: [PATCH] [clang-format] Annotate ampamp after new/delete as
 BinaryOperator

Fixes #78789.
---
 clang/lib/Format/TokenAnnotator.cpp   |  2 ++
 clang/unittests/Format/TokenAnnotatorTest.cpp | 10 ++
 2 files changed, 12 insertions(+)

diff --git a/clang/lib/Format/TokenAnnotator.cpp 
b/clang/lib/Format/TokenAnnotator.cpp
index 628f70417866c3..272d7bbb352daf 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -2912,6 +2912,8 @@ class AnnotatingParser {
   return TT_UnaryOperator;
 if (PrevToken->is(TT_TypeName))
   return TT_PointerOrReference;
+if (PrevToken->isOneOf(tok::kw_new, tok::kw_delete) && Tok.is(tok::ampamp))
+  return TT_BinaryOperator;
 
 const FormatToken *NextToken = Tok.getNextNonComment();
 
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp 
b/clang/unittests/Format/TokenAnnotatorTest.cpp
index da02ced8c7a949..10e0eca62510a7 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -309,6 +309,16 @@ TEST_F(TokenAnnotatorTest, UnderstandsUsesOfStarAndAmp) {
   EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_OverloadedOperatorLParen);
   EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_FunctionLBrace);
   EXPECT_TOKEN(Tokens[11], tok::amp, TT_PointerOrReference);
+
+  Tokens = annotate("if (new && num) {\n"
+"  new = 1;\n"
+"}\n"
+"if (!delete && num) {\n"
+"  delete = 1;\n"
+"}");
+  ASSERT_EQ(Tokens.size(), 26u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_BinaryOperator);
+  EXPECT_TOKEN(Tokens[16], tok::ampamp, TT_BinaryOperator);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandsUsesOfPlusAndMinus) {

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


[clang] [clang-format] Annotate ampamp after new/delete as BinaryOperator (PR #89033)

2024-04-17 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-format

Author: Owen Pan (owenca)


Changes

Fixes #78789.

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


2 Files Affected:

- (modified) clang/lib/Format/TokenAnnotator.cpp (+2) 
- (modified) clang/unittests/Format/TokenAnnotatorTest.cpp (+10) 


``diff
diff --git a/clang/lib/Format/TokenAnnotator.cpp 
b/clang/lib/Format/TokenAnnotator.cpp
index 628f70417866c3..272d7bbb352daf 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -2912,6 +2912,8 @@ class AnnotatingParser {
   return TT_UnaryOperator;
 if (PrevToken->is(TT_TypeName))
   return TT_PointerOrReference;
+if (PrevToken->isOneOf(tok::kw_new, tok::kw_delete) && Tok.is(tok::ampamp))
+  return TT_BinaryOperator;
 
 const FormatToken *NextToken = Tok.getNextNonComment();
 
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp 
b/clang/unittests/Format/TokenAnnotatorTest.cpp
index da02ced8c7a949..10e0eca62510a7 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -309,6 +309,16 @@ TEST_F(TokenAnnotatorTest, UnderstandsUsesOfStarAndAmp) {
   EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_OverloadedOperatorLParen);
   EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_FunctionLBrace);
   EXPECT_TOKEN(Tokens[11], tok::amp, TT_PointerOrReference);
+
+  Tokens = annotate("if (new && num) {\n"
+"  new = 1;\n"
+"}\n"
+"if (!delete && num) {\n"
+"  delete = 1;\n"
+"}");
+  ASSERT_EQ(Tokens.size(), 26u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_BinaryOperator);
+  EXPECT_TOKEN(Tokens[16], tok::ampamp, TT_BinaryOperator);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandsUsesOfPlusAndMinus) {

``




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


[clang] [flang] [flang][driver] Avoid mentions of Clang in Flang's command line reference. (PR #88932)

2024-04-17 Thread Michael Kruse via cfe-commits

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


[clang] [flang] [flang][driver] Avoid mentions of Clang in Flang's command line reference. (PR #88932)

2024-04-17 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Michael Kruse (Meinersbur)


Changes

The help text was not updated in #87360.

Clang is also mentioned for the diagnostic warnings reference, which mostly 
applies to C/C++/Obj-C, not Fortran. #81726 already tried to fix this, 
and I don't know a better solution.

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


3 Files Affected:

- (modified) clang/include/clang/Driver/Options.td (+6-2) 
- (modified) flang/test/Driver/driver-help-hidden.f90 (+1-1) 
- (modified) flang/test/Driver/driver-help.f90 (+1-1) 


``diff
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index e24626913add76..d89b53e4049cf6 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -807,8 +807,12 @@ def gcc_install_dir_EQ : Joined<["--"], 
"gcc-install-dir=">,
   "Note: executables (e.g. ld) used by the compiler are not overridden by the 
selected GCC installation">;
 def gcc_toolchain : Joined<["--"], "gcc-toolchain=">, Flags<[NoXarchOption]>,
   Visibility<[ClangOption, FlangOption]>,
-  HelpText<"Specify a directory where Clang can find 'include' and 
'lib{,32,64}/gcc{,-cross}/$triple/$version'. "
-  "Clang will use the GCC installation with the largest version">;
+  HelpText<
+"Specify a directory where Clang can find 'include' and 
'lib{,32,64}/gcc{,-cross}/$triple/$version'. "
+"Clang will use the GCC installation with the largest version">,
+  HelpTextForVariants<[FlangOption],
+"Specify a directory where Flang can find 
'lib{,32,64}/gcc{,-cross}/$triple/$version'. "
+"Flang will use the GCC installation with the largest version">;
 def gcc_triple_EQ : Joined<["--"], "gcc-triple=">,
   HelpText<"Search for the GCC installation with the specified triple.">;
 def CC : Flag<["-"], "CC">, Visibility<[ClangOption, CC1Option]>,
diff --git a/flang/test/Driver/driver-help-hidden.f90 
b/flang/test/Driver/driver-help-hidden.f90
index de2fe3048f993c..b5bb0f1c1b2560 100644
--- a/flang/test/Driver/driver-help-hidden.f90
+++ b/flang/test/Driver/driver-help-hidden.f90
@@ -109,7 +109,7 @@
 ! CHECK-NEXT: -fxor-operator  Enable .XOR. as a synonym of .NEQV.
 ! CHECK-NEXT: --gcc-install-dir=
 ! CHECK-NEXT: Use GCC installation in the specified 
directory. The directory ends with path components like 
'lib{,32,64}/gcc{,-cross}/$triple/$version'. Note: executables (e.g. ld) used 
by the compiler are not overridden by the selected GCC installation
-! CHECK-NEXT: --gcc-toolchain= Specify a directory where Clang can find 
'include' and 'lib{,32,64}/gcc{,-cross}/$triple/$version'. Clang will use the 
GCC installation with the largest version
+! CHECK-NEXT: --gcc-toolchain= Specify a directory where Flang can find 
'lib{,32,64}/gcc{,-cross}/$triple/$version'. Flang will use the GCC 
installation with the largest version
 ! CHECK-NEXT: -gline-directives-only  Emit debug line info directives only
 ! CHECK-NEXT: -gline-tables-only  Emit debug line number tables only
 ! CHECK-NEXT: -gpulibcLink the LLVM C Library for GPUs
diff --git a/flang/test/Driver/driver-help.f90 
b/flang/test/Driver/driver-help.f90
index b258eb59c18629..0b0a493baf07f7 100644
--- a/flang/test/Driver/driver-help.f90
+++ b/flang/test/Driver/driver-help.f90
@@ -97,7 +97,7 @@
 ! HELP-NEXT: -fxor-operator  Enable .XOR. as a synonym of .NEQV.
 ! HELP-NEXT: --gcc-install-dir=
 ! HELP-NEXT: Use GCC installation in the specified 
directory. The directory ends with path components like 
'lib{,32,64}/gcc{,-cross}/$triple/$version'. Note: executables (e.g. ld) used 
by the compiler are not overridden by the selected GCC installation
-! HELP-NEXT: --gcc-toolchain= Specify a directory where Clang can find 
'include' and 'lib{,32,64}/gcc{,-cross}/$triple/$version'. Clang will use the 
GCC installation with the largest version
+! HELP-NEXT: --gcc-toolchain= Specify a directory where Flang can find 
'lib{,32,64}/gcc{,-cross}/$triple/$version'. Flang will use the GCC 
installation with the largest version
 ! HELP-NEXT: -gline-directives-only  Emit debug line info directives only
 ! HELP-NEXT: -gline-tables-only  Emit debug line number tables only
 ! HELP-NEXT: -gpulibcLink the LLVM C Library for GPUs

``




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


[clang] [flang] [flang][driver] Avoid mentions of Clang in Flang's command line reference. (PR #88932)

2024-04-17 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-flang-driver

Author: Michael Kruse (Meinersbur)


Changes

The help text was not updated in #87360.

Clang is also mentioned for the diagnostic warnings reference, which mostly 
applies to C/C++/Obj-C, not Fortran. #81726 already tried to fix this, 
and I don't know a better solution.

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


3 Files Affected:

- (modified) clang/include/clang/Driver/Options.td (+6-2) 
- (modified) flang/test/Driver/driver-help-hidden.f90 (+1-1) 
- (modified) flang/test/Driver/driver-help.f90 (+1-1) 


``diff
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index e24626913add76..d89b53e4049cf6 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -807,8 +807,12 @@ def gcc_install_dir_EQ : Joined<["--"], 
"gcc-install-dir=">,
   "Note: executables (e.g. ld) used by the compiler are not overridden by the 
selected GCC installation">;
 def gcc_toolchain : Joined<["--"], "gcc-toolchain=">, Flags<[NoXarchOption]>,
   Visibility<[ClangOption, FlangOption]>,
-  HelpText<"Specify a directory where Clang can find 'include' and 
'lib{,32,64}/gcc{,-cross}/$triple/$version'. "
-  "Clang will use the GCC installation with the largest version">;
+  HelpText<
+"Specify a directory where Clang can find 'include' and 
'lib{,32,64}/gcc{,-cross}/$triple/$version'. "
+"Clang will use the GCC installation with the largest version">,
+  HelpTextForVariants<[FlangOption],
+"Specify a directory where Flang can find 
'lib{,32,64}/gcc{,-cross}/$triple/$version'. "
+"Flang will use the GCC installation with the largest version">;
 def gcc_triple_EQ : Joined<["--"], "gcc-triple=">,
   HelpText<"Search for the GCC installation with the specified triple.">;
 def CC : Flag<["-"], "CC">, Visibility<[ClangOption, CC1Option]>,
diff --git a/flang/test/Driver/driver-help-hidden.f90 
b/flang/test/Driver/driver-help-hidden.f90
index de2fe3048f993c..b5bb0f1c1b2560 100644
--- a/flang/test/Driver/driver-help-hidden.f90
+++ b/flang/test/Driver/driver-help-hidden.f90
@@ -109,7 +109,7 @@
 ! CHECK-NEXT: -fxor-operator  Enable .XOR. as a synonym of .NEQV.
 ! CHECK-NEXT: --gcc-install-dir=
 ! CHECK-NEXT: Use GCC installation in the specified 
directory. The directory ends with path components like 
'lib{,32,64}/gcc{,-cross}/$triple/$version'. Note: executables (e.g. ld) used 
by the compiler are not overridden by the selected GCC installation
-! CHECK-NEXT: --gcc-toolchain= Specify a directory where Clang can find 
'include' and 'lib{,32,64}/gcc{,-cross}/$triple/$version'. Clang will use the 
GCC installation with the largest version
+! CHECK-NEXT: --gcc-toolchain= Specify a directory where Flang can find 
'lib{,32,64}/gcc{,-cross}/$triple/$version'. Flang will use the GCC 
installation with the largest version
 ! CHECK-NEXT: -gline-directives-only  Emit debug line info directives only
 ! CHECK-NEXT: -gline-tables-only  Emit debug line number tables only
 ! CHECK-NEXT: -gpulibcLink the LLVM C Library for GPUs
diff --git a/flang/test/Driver/driver-help.f90 
b/flang/test/Driver/driver-help.f90
index b258eb59c18629..0b0a493baf07f7 100644
--- a/flang/test/Driver/driver-help.f90
+++ b/flang/test/Driver/driver-help.f90
@@ -97,7 +97,7 @@
 ! HELP-NEXT: -fxor-operator  Enable .XOR. as a synonym of .NEQV.
 ! HELP-NEXT: --gcc-install-dir=
 ! HELP-NEXT: Use GCC installation in the specified 
directory. The directory ends with path components like 
'lib{,32,64}/gcc{,-cross}/$triple/$version'. Note: executables (e.g. ld) used 
by the compiler are not overridden by the selected GCC installation
-! HELP-NEXT: --gcc-toolchain= Specify a directory where Clang can find 
'include' and 'lib{,32,64}/gcc{,-cross}/$triple/$version'. Clang will use the 
GCC installation with the largest version
+! HELP-NEXT: --gcc-toolchain= Specify a directory where Flang can find 
'lib{,32,64}/gcc{,-cross}/$triple/$version'. Flang will use the GCC 
installation with the largest version
 ! HELP-NEXT: -gline-directives-only  Emit debug line info directives only
 ! HELP-NEXT: -gline-tables-only  Emit debug line number tables only
 ! HELP-NEXT: -gpulibcLink the LLVM C Library for GPUs

``




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


[clang] [flang] [flang][driver] Avoid mentions of Clang in Flang's command line reference. (PR #88932)

2024-04-17 Thread Andrzej Warzyński via cfe-commits

https://github.com/banach-space approved this pull request.

Nice, thank you! LGTM

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


[clang] [clang][dataflow] Refactor `PropagateResultObject()` with a switch statement. (PR #88865)

2024-04-17 Thread via cfe-commits

https://github.com/martinboehme updated 
https://github.com/llvm/llvm-project/pull/88865

>From 69f444532a9dd1da4c8018684fbf24edacfc91fd Mon Sep 17 00:00:00 2001
From: Martin Braenne 
Date: Tue, 16 Apr 2024 09:52:35 +
Subject: [PATCH] [clang][dataflow] Refactor `PropagateResultObject()` with a
 switch statement.

See also discussion in #88726.
---
 .../FlowSensitive/DataflowEnvironment.cpp | 86 +++
 1 file changed, 50 insertions(+), 36 deletions(-)

diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index 3f1600d9ac5d87..e5aaa8fea4803f 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -414,25 +414,52 @@ class ResultObjectVisitor : public 
RecursiveASTVisitor {
 
 ResultObjectMap[E] = Loc;
 
+switch (E->getStmtClass()) {
 // The following AST node kinds are "original initializers": They are the
 // lowest-level AST node that initializes a given object, and nothing
 // below them can initialize the same object (or part of it).
-if (isa(E) || isa(E) || isa(E) ||
-isa(E) || isa(E) ||
-isa(E) ||
-// We treat `BuiltinBitCastExpr` as an "original initializer" too as
-// it may not even be casting from a record type -- and even if it is,
-// the two objects are in general of unrelated type.
-isa(E)) {
+case Stmt::CXXConstructExprClass:
+case Stmt::CallExprClass:
+case Stmt::LambdaExprClass:
+case Stmt::CXXDefaultArgExprClass:
+case Stmt::CXXDefaultInitExprClass:
+case Stmt::CXXStdInitializerListExprClass:
+// We treat `BuiltinBitCastExpr` as an "original initializer" too as it may
+// not even be casting from a record type -- and even if it is, the two
+// objects are in general of unrelated type.
+case Stmt::BuiltinBitCastExprClass:
+  return;
+case Stmt::BinaryOperatorClass: {
+  auto *Op = cast(E);
+  if (Op->getOpcode() == BO_Cmp) {
+// Builtin `<=>` returns a `std::strong_ordering` object. We
+// consider this to be an "original" initializer too (see above).
+return;
+  }
+  if (Op->isCommaOp()) {
+PropagateResultObject(Op->getRHS(), Loc);
+return;
+  }
+  // We don't expect any other binary operators to produce a record
+  // prvalue, so if we get here, we've hit some case we don't know
+  // about.
+  assert(false);
   return;
 }
-if (auto *Op = dyn_cast(E);
-Op && Op->getOpcode() == BO_Cmp) {
-  // Builtin `<=>` returns a `std::strong_ordering` object.
+case Stmt::BinaryConditionalOperatorClass:
+case Stmt::ConditionalOperatorClass: {
+  auto *Cond = cast(E);
+  PropagateResultObject(Cond->getTrueExpr(), Loc);
+  PropagateResultObject(Cond->getFalseExpr(), Loc);
   return;
 }
-
-if (auto *InitList = dyn_cast(E)) {
+case Stmt::StmtExprClass: {
+  auto *SE = cast(E);
+  PropagateResultObject(cast(SE->getSubStmt()->body_back()), Loc);
+  return;
+}
+case Stmt::InitListExprClass: {
+  auto *InitList = cast(E);
   if (!InitList->isSemanticForm())
 return;
   if (InitList->isTransparent()) {
@@ -462,33 +489,20 @@ class ResultObjectVisitor : public 
RecursiveASTVisitor {
   }
   return;
 }
-
-if (auto *Op = dyn_cast(E); Op && Op->isCommaOp()) {
-  PropagateResultObject(Op->getRHS(), Loc);
+default: {
+  // All other expression nodes that propagate a record prvalue should
+  // have exactly one child.
+  SmallVector Children(E->child_begin(), E->child_end());
+  LLVM_DEBUG({
+if (Children.size() != 1)
+  E->dump();
+  });
+  assert(Children.size() == 1);
+  for (Stmt *S : Children)
+PropagateResultObject(cast(S), Loc);
   return;
 }
-
-if (auto *Cond = dyn_cast(E)) {
-  PropagateResultObject(Cond->getTrueExpr(), Loc);
-  PropagateResultObject(Cond->getFalseExpr(), Loc);
-  return;
 }
-
-if (auto *SE = dyn_cast(E)) {
-  PropagateResultObject(cast(SE->getSubStmt()->body_back()), Loc);
-  return;
-}
-
-// All other expression nodes that propagate a record prvalue should have
-// exactly one child.
-SmallVector Children(E->child_begin(), E->child_end());
-LLVM_DEBUG({
-  if (Children.size() != 1)
-E->dump();
-});
-assert(Children.size() == 1);
-for (Stmt *S : Children)
-  PropagateResultObject(cast(S), Loc);
   }
 
 private:

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


[clang] [clang][dataflow] Refactor `PropagateResultObject()` with a switch statement. (PR #88865)

2024-04-17 Thread via cfe-commits

martinboehme wrote:

Ready for review.

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


[clang] [flang] [flang][driver] Avoid mentions of Clang in Flang's command line reference. (PR #88932)

2024-04-17 Thread David Spickett via cfe-commits


@@ -807,8 +807,12 @@ def gcc_install_dir_EQ : Joined<["--"], 
"gcc-install-dir=">,
   "Note: executables (e.g. ld) used by the compiler are not overridden by the 
selected GCC installation">;
 def gcc_toolchain : Joined<["--"], "gcc-toolchain=">, Flags<[NoXarchOption]>,
   Visibility<[ClangOption, FlangOption]>,
-  HelpText<"Specify a directory where Clang can find 'include' and 
'lib{,32,64}/gcc{,-cross}/$triple/$version'. "
-  "Clang will use the GCC installation with the largest version">;
+  HelpText<
+"Specify a directory where Clang can find 'include' and 
'lib{,32,64}/gcc{,-cross}/$triple/$version'. "
+"Clang will use the GCC installation with the largest version">,
+  HelpTextForVariants<[FlangOption],
+"Specify a directory where Flang can find 
'lib{,32,64}/gcc{,-cross}/$triple/$version'. "

DavidSpickett wrote:

So flang doesn't need 'include' ?

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


[clang] [flang] [flang][driver] Avoid mentions of Clang in Flang's command line reference. (PR #88932)

2024-04-17 Thread David Spickett via cfe-commits

DavidSpickett wrote:

> Clang is also mentioned for the diagnostic warnings reference, which mostly 
> applies to C/C++/Obj-C, not Fortran. 
> https://github.com/llvm/llvm-project/pull/81726 already tried to fix this, 
> and I don't know a better solution.

Do you mean that this PR fixes this, or that you noticed this problem while 
working on this?

If it's the latter it may be as @banach-space mentioned to me, that the 
`docbrief` is still shared between Flang and Clang. This could be solved in a 
similar, albeit tedious way to what I did for the help text.

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


[clang-tools-extra] [clang-tidy] Ignore deleted ctor in `bugprone-forwarding-reference-overload` (PR #88138)

2024-04-17 Thread Mike Weller via cfe-commits

MikeWeller wrote:

FYI I don't have merge privs, not sure if I need to ping anybody. Then again I 
still see "This workflow requires approval from a maintainer", possibly because 
this is my first contribution?

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


[clang-tools-extra] [clang-tidy] Ignore deleted ctor in `bugprone-forwarding-reference-overload` (PR #88138)

2024-04-17 Thread Mike Weller via cfe-commits


@@ -286,6 +286,10 @@ Changes in existing checks
   check by resolving fix-it overlaps in template code by disregarding implicit
   instances.
 
+- Improved :doc:`bugprone-forwarding-reference-overload
+  `
+  check to not flag deleted constructors which are unable to hide anything.

MikeWeller wrote:

Done in bab66e1, let me know if you have a better suggestion

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


[clang] [compiler-rt] [llvm] [FMV] Remove useless features according the latest ACLE spec. (PR #88965)

2024-04-17 Thread Alexandros Lamprineas via cfe-commits


@@ -67,57 +67,42 @@ enum CPUFeatures {
   FEAT_FP,
   FEAT_SIMD,
   FEAT_CRC,
-  FEAT_SHA1,
   FEAT_SHA2,
   FEAT_SHA3,
   FEAT_AES,
-  FEAT_PMULL,
   FEAT_FP16,
-  FEAT_DIT,
   FEAT_DPB,
   FEAT_DPB2,
   FEAT_JSCVT,
   FEAT_FCMA,
   FEAT_RCPC,
   FEAT_RCPC2,
   FEAT_FRINTTS,
-  FEAT_DGH,
   FEAT_I8MM,
   FEAT_BF16,
-  FEAT_EBF16,
   FEAT_RPRES,
   FEAT_SVE,
-  FEAT_SVE_BF16,
-  FEAT_SVE_EBF16,
-  FEAT_SVE_I8MM,
   FEAT_SVE_F32MM,
   FEAT_SVE_F64MM,
   FEAT_SVE2,
   FEAT_SVE_AES,
-  FEAT_SVE_PMULL128,
   FEAT_SVE_BITPERM,
   FEAT_SVE_SHA3,
   FEAT_SVE_SM4,
   FEAT_SME,
   FEAT_MEMTAG,
-  FEAT_MEMTAG2,
-  FEAT_MEMTAG3,
   FEAT_SB,
   FEAT_PREDRES,
   FEAT_SSBS,
-  FEAT_SSBS2,
-  FEAT_BTI,
   FEAT_LS64,
-  FEAT_LS64_V,
-  FEAT_LS64_ACCDATA,
   FEAT_WFXT,
   FEAT_SME_F64,
   FEAT_SME_I64,
   FEAT_SME2,
   FEAT_RCPC3,
   FEAT_MOPS,
   FEAT_MAX,
-  FEAT_EXT = 62, // Reserved to indicate presence of additional features field

labrinea wrote:

For the time being `__aarch64_cpu_features` is not part of the ABI, but that 
may change in the future.

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


[clang] [llvm] Move several vector intrinsics out of experimental namespace (PR #88748)

2024-04-17 Thread Maciej Gabka via cfe-commits


@@ -1099,6 +1099,25 @@ static bool upgradeIntrinsicFunction1(Function *F, 
Function *&NewFn,
 return true;
   }
 
+  ID = StringSwitch(Name)
+   .StartsWith("splice.", Intrinsic::vector_splice)
+   .StartsWith("reverse.", Intrinsic::vector_reverse)
+   .StartsWith("interleave2.", Intrinsic::vector_interleave2)
+   .StartsWith("deinterleave2.", Intrinsic::vector_deinterleave2)
+   .Default(Intrinsic::not_intrinsic);
+  if (ID != Intrinsic::not_intrinsic) {
+const auto *FT = F->getFunctionType();
+rename(F);
+if (ID == Intrinsic::vector_interleave2)
+  NewFn = Intrinsic::getDeclaration(F->getParent(), ID,
+FT->getReturnType());
+else {

mgabka wrote:

Thanks for pointing this out, decided to merge this with the similar section 
for insert/extract.

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


[clang] [llvm] Move several vector intrinsics out of experimental namespace (PR #88748)

2024-04-17 Thread Maciej Gabka via cfe-commits


@@ -18779,13 +18779,13 @@ This is an overloaded intrinsic.
 
 ::
 
-  declare <2 x i8> @llvm.experimental.vector.reverse.v2i8(<2 x i8> %a)
-  declare  
@llvm.experimental.vector.reverse.nxv4i32( %a)
+  declare <2 x i8> @llvm.vector.reverse.v2i8(<2 x i8> %a)
+  declare  @llvm.vector.reverse.nxv4i32( %a)
 
 Overview:
 "
 
-The '``llvm.experimental.vector.reverse.*``' intrinsics reverse a vector.
+The '``llvm.vector.reverse.*``' intrinsics reverse a vector.
 The intrinsic takes a single vector and returns a vector of matching type but
 with the original lane order reversed. These intrinsics work for both fixed
 and scalable vectors. While this intrinsic is marked as experimental the

mgabka wrote:

Sorry I missed it.

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


[clang] [llvm] Move several vector intrinsics out of experimental namespace (PR #88748)

2024-04-17 Thread Maciej Gabka via cfe-commits


@@ -18914,13 +18914,13 @@ This is an overloaded intrinsic.
 
 ::
 
-  declare <2 x double> @llvm.experimental.vector.splice.v2f64(<2 x double> 
%vec1, <2 x double> %vec2, i32 %imm)
-  declare  
@llvm.experimental.vector.splice.nxv4i32( %vec1,  %vec2, i32 %imm)
+  declare <2 x double> @llvm.vector.splice.v2f64(<2 x double> %vec1, <2 x 
double> %vec2, i32 %imm)
+  declare  @llvm.vector.splice.nxv4i32( %vec1,  %vec2, i32 %imm)
 
 Overview:
 "
 
-The '``llvm.experimental.vector.splice.*``' intrinsics construct a vector by
+The '``llvm.vector.splice.*``' intrinsics construct a vector by

mgabka wrote:

Sorry I missed it.

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


[clang] [llvm] Move several vector intrinsics out of experimental namespace (PR #88748)

2024-04-17 Thread Maciej Gabka via cfe-commits

mgabka wrote:

> > vector.revert
> 
> I think should be vector.reverse?

Will fix the commit message when merging the PR.

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


[clang] [X86][test] Added extra cet tests (PR #88736)

2024-04-17 Thread Phoebe Wang via cfe-commits


@@ -1,13 +1,22 @@
 // RUN: %clang_cc1 -E -triple i386 -dM -o - -fcf-protection=return %s | 
FileCheck %s --check-prefix=RETURN
 // RUN: %clang_cc1 -E -triple i386 -dM -o - -fcf-protection=branch %s | 
FileCheck %s --check-prefix=BRANCH
 // RUN: %clang_cc1 -E -triple i386 -dM -o - -fcf-protection=full %s   | 
FileCheck %s --check-prefix=FULL
+// RUN: %clang_cc1 -E -triple=x86_64 -dM -o - -fcf-protection=none %s | 
FileCheck %s --check-prefix=NOTCET
 // RUN: not %clang_cc1 -emit-llvm-only -triple i386 -target-cpu pentium-mmx 
-fcf-protection=branch %s 2>&1 | FileCheck %s --check-prefix=NOCFPROT
+// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=return %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROTR
+// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=branch %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROTB
+// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=full %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROTF
+// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=none %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROTNONE
 
 // RETURN: #define __CET__ 2
 // BRANCH: #define __CET__ 1
 // FULL: #define __CET__ 3
-// CFPROT: !{i32 8, !"cf-protection-branch", i32 1}
-
+// NOTCET-NOT: #define __CET__
 // NOCFPROT: error: option 'cf-protection=branch' cannot be specified on this 
target
+// CFPROTR: !{i32 8, !"cf-protection-return", i32 1}
+// CFPROTB: !{i32 8, !"cf-protection-branch", i32 1}
+// CFPROTF: !{i32 8, !"cf-protection-return", i32 1}
+// CFPROTF-NEXT: !{i32 8, !"cf-protection-branch", i32 1}

phoebewang wrote:

```suggestion
// CFPROTNONE-NOT: cf-protection-
// CFPROTR: !{i32 8, !"cf-protection-return", i32 1}
// CFPROTB: !{i32 8, !"cf-protection-branch", i32 1}
// CFPROTNONE-NOT: cf-protection-
```

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


[clang] [X86][test] Added extra cet tests (PR #88736)

2024-04-17 Thread Phoebe Wang via cfe-commits


@@ -1,13 +1,22 @@
 // RUN: %clang_cc1 -E -triple i386 -dM -o - -fcf-protection=return %s | 
FileCheck %s --check-prefix=RETURN
 // RUN: %clang_cc1 -E -triple i386 -dM -o - -fcf-protection=branch %s | 
FileCheck %s --check-prefix=BRANCH
 // RUN: %clang_cc1 -E -triple i386 -dM -o - -fcf-protection=full %s   | 
FileCheck %s --check-prefix=FULL
+// RUN: %clang_cc1 -E -triple=x86_64 -dM -o - -fcf-protection=none %s | 
FileCheck %s --check-prefix=NOTCET
 // RUN: not %clang_cc1 -emit-llvm-only -triple i386 -target-cpu pentium-mmx 
-fcf-protection=branch %s 2>&1 | FileCheck %s --check-prefix=NOCFPROT
+// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=return %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROTR
+// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=branch %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROTB
+// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=full %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROTF

phoebewang wrote:

```suggestion
// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=return %s -emit-llvm | 
FileCheck %s --check-prefixes=CFPROTR,CFPROTNONE
// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=branch %s -emit-llvm | 
FileCheck %s --check-prefixes=CFPROTB,CFPROTNONE
// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=full %s -emit-llvm | 
FileCheck %s --check-prefixes=CFPROTR,CFPROTB,CFPROTNONE
```

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


[clang] [Modules] Add -cc1 -flate-module-map-file to load module maps after PCMs (PR #88893)

2024-04-17 Thread Ilya Biryukov via cfe-commits

ilya-biryukov wrote:

> Have you tried changing the behavior of the existing `-fmodule-map-file=` to 
> load the file after we load module files? If so, what kinds of things do you 
> see breaking or changing? If we can avoid it, I think it would be better to 
> only have a single mode here, and loading the module files first seems to 
> make a lot of sense given that they can make it unnecessary to load the 
> module map files at all.

I did not do it because I was sure this will break the "module shadowing" rules 
after reading the code.
I'll try it now and get back with my findings.

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


[clang] [Clang][Sema] placement new initializes typedef array with correct size (PR #89036)

2024-04-17 Thread via cfe-commits

https://github.com/mahtohappy created 
https://github.com/llvm/llvm-project/pull/89036

When in-place new-ing a local variable of an array of trivial type, the 
generated code calls 'memset' with the correct size of the array, earlier it 
was generating size (squared of the typedef array + size).

The cause: typedef TYPE TArray[8]; TArray x; The type of declarator is 
Tarray[8] and in SemaExprCXX.cpp::BuildCXXNew we check if it's of typedef and 
of constant size then we get the original type and it works fine for 
non-dependent cases.
But in case of template we do TreeTransform.h:TransformCXXNEWExpr and there we 
again check the allocated type which is TArray[8] and it stays that way, so 
ArraySize=(Tarray[8] type, alloc Tarray[8*type]) so the squared size allocation.

ArraySize gets calculated earlier in TreeTransform.h so that if(!ArraySize) 
condition was failing.
fix: I changed that condition to if(ArraySize).
fixes https://github.com/llvm/llvm-project/issues/41441

>From 56c2b4f70735a6ef3b80cb8461a88ea51f2d02d7 Mon Sep 17 00:00:00 2001
From: mahtohappy 
Date: Tue, 16 Apr 2024 17:48:45 +0530
Subject: [PATCH 1/3] [Clang][Sema] placement new initializes typedef array
 with correct size (#83124)

When in-place new-ing a local variable of an array of trivial type, the
generated code calls 'memset' with the correct size of the array,
earlier it was generating size (squared of the typedef array + size).

The cause: `typedef TYPE TArray[8]; TArray x;` The type of declarator is
Tarray[8] and in `SemaExprCXX.cpp::BuildCXXNew` we check if it's of
typedef and of constant size then we get the original type and it works
fine for non-dependent cases.
But in case of template we do `TreeTransform.h:TransformCXXNEWExpr` and
there we again check the allocated type which is TArray[8] and it stays
that way, so ArraySize=(Tarray[8] type, alloc Tarray[8*type]) so the
squared size allocation.

ArraySize gets calculated earlier in `TreeTransform.h` so that
`if(!ArraySize)` condition was failing.
fix: I changed that condition to `if(ArraySize)`.


Fixes #41441
---
 clang/docs/ReleaseNotes.rst   |  2 ++
 clang/lib/Sema/TreeTransform.h| 14 -
 .../instantiate-new-placement-size.cpp| 20 +++
 3 files changed, 35 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/SemaCXX/instantiate-new-placement-size.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 96ad92b540b47f..636d76f1836759 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -534,6 +534,8 @@ Bug Fixes to C++ Support
   Fixes (#GH70604), (#GH79754), (#GH84163), (#GH84425), (#GH86054), 
(#GH86398), and (#GH86399).
 - Fix a crash when deducing ``auto`` from an invalid dereference (#GH88329).
 - Fix a crash in requires expression with templated base class member 
function. Fixes (#GH84020).
+- placement new initializes typedef array with correct size
+  (`#GH41441 `_)
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index eb05783a6219dc..0c7fdb357235e1 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -12864,6 +12864,19 @@ TreeTransform::TransformCXXNewExpr(CXXNewExpr 
*E) {
 ArraySize = NewArraySize.get();
   }
 
+  // Per C++0x [expr.new]p5, the type being constructed may be a
+  // typedef of an array type.
+  QualType AllocType = AllocTypeInfo->getType();
+  if (ArraySize) {
+if (const ConstantArrayType *Array =
+SemaRef.Context.getAsConstantArrayType(AllocType)) {
+  ArraySize = IntegerLiteral::Create(SemaRef.Context, Array->getSize(),
+ SemaRef.Context.getSizeType(),
+ E->getBeginLoc());
+  AllocType = Array->getElementType();
+}
+  }
+
   // Transform the placement arguments (if any).
   bool ArgumentChanged = false;
   SmallVector PlacementArgs;
@@ -12925,7 +12938,6 @@ TreeTransform::TransformCXXNewExpr(CXXNewExpr 
*E) {
 return E;
   }
 
-  QualType AllocType = AllocTypeInfo->getType();
   if (!ArraySize) {
 // If no array size was specified, but the new expression was
 // instantiated with an array type (e.g., "new T" where T is
diff --git a/clang/test/SemaCXX/instantiate-new-placement-size.cpp 
b/clang/test/SemaCXX/instantiate-new-placement-size.cpp
new file mode 100644
index 00..7a29d3dee8491e
--- /dev/null
+++ b/clang/test/SemaCXX/instantiate-new-placement-size.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang -S -fno-discard-value-names -emit-llvm -o - %s | FileCheck %s
+// Issue no: 41441
+#include 
+
+// CHECK: call void @llvm.memset.p0.i64(ptr align 1 %x, i8 0, i64 8, i1 false)
+// CHECK: call void @llvm.memset.p0.i64(ptr align 16 %x, i8 0, i64 32, i1 
false)
+template 
+void f()
+{
+typedef TYPE TArray[8];
+
+TArray x;
+new(&x) TA

[clang] [Clang][Sema] placement new initializes typedef array with correct size (PR #89036)

2024-04-17 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: None (mahtohappy)


Changes

When in-place new-ing a local variable of an array of trivial type, the 
generated code calls 'memset' with the correct size of the array, earlier it 
was generating size (squared of the typedef array + size).

The cause: typedef TYPE TArray[8]; TArray x; The type of declarator is 
Tarray[8] and in SemaExprCXX.cpp::BuildCXXNew we check if it's of typedef and 
of constant size then we get the original type and it works fine for 
non-dependent cases.
But in case of template we do TreeTransform.h:TransformCXXNEWExpr and there we 
again check the allocated type which is TArray[8] and it stays that way, so 
ArraySize=(Tarray[8] type, alloc Tarray[8*type]) so the squared size allocation.

ArraySize gets calculated earlier in TreeTransform.h so that if(!ArraySize) 
condition was failing.
fix: I changed that condition to if(ArraySize).
fixes https://github.com/llvm/llvm-project/issues/41441

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


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+2) 
- (modified) clang/lib/Sema/TreeTransform.h (+13-1) 
- (added) clang/test/SemaCXX/PR41441.cpp (+23) 


``diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 96ad92b540b47f..636d76f1836759 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -534,6 +534,8 @@ Bug Fixes to C++ Support
   Fixes (#GH70604), (#GH79754), (#GH84163), (#GH84425), (#GH86054), 
(#GH86398), and (#GH86399).
 - Fix a crash when deducing ``auto`` from an invalid dereference (#GH88329).
 - Fix a crash in requires expression with templated base class member 
function. Fixes (#GH84020).
+- placement new initializes typedef array with correct size
+  (`#GH41441 `_)
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index eb05783a6219dc..0c7fdb357235e1 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -12864,6 +12864,19 @@ TreeTransform::TransformCXXNewExpr(CXXNewExpr 
*E) {
 ArraySize = NewArraySize.get();
   }
 
+  // Per C++0x [expr.new]p5, the type being constructed may be a
+  // typedef of an array type.
+  QualType AllocType = AllocTypeInfo->getType();
+  if (ArraySize) {
+if (const ConstantArrayType *Array =
+SemaRef.Context.getAsConstantArrayType(AllocType)) {
+  ArraySize = IntegerLiteral::Create(SemaRef.Context, Array->getSize(),
+ SemaRef.Context.getSizeType(),
+ E->getBeginLoc());
+  AllocType = Array->getElementType();
+}
+  }
+
   // Transform the placement arguments (if any).
   bool ArgumentChanged = false;
   SmallVector PlacementArgs;
@@ -12925,7 +12938,6 @@ TreeTransform::TransformCXXNewExpr(CXXNewExpr 
*E) {
 return E;
   }
 
-  QualType AllocType = AllocTypeInfo->getType();
   if (!ArraySize) {
 // If no array size was specified, but the new expression was
 // instantiated with an array type (e.g., "new T" where T is
diff --git a/clang/test/SemaCXX/PR41441.cpp b/clang/test/SemaCXX/PR41441.cpp
new file mode 100644
index 00..d0f2917e52f211
--- /dev/null
+++ b/clang/test/SemaCXX/PR41441.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang --target=x86_64-pc-linux -S -fno-discard-value-names -emit-llvm 
-o - %s | FileCheck %s
+
+namespace std {
+  using size_t = decltype(sizeof(int));
+};
+void* operator new[](std::size_t, void*) noexcept;
+
+// CHECK: call void @llvm.memset.p0.i64(ptr align 1 %x, i8 0, i64 8, i1 false)
+// CHECK: call void @llvm.memset.p0.i64(ptr align 16 %x, i8 0, i64 32, i1 
false)
+template 
+void f()
+{
+typedef TYPE TArray[8];
+
+TArray x;
+new(&x) TArray();
+}
+
+int main()
+{
+f();
+f();
+}

``




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


[clang] [clang][SPIR-V] Set AS for the SPIR-V logical triple (PR #88939)

2024-04-17 Thread Nathan Gauër via cfe-commits

Keenuts wrote:

Thanks all!
Agree with Bogner, let's unblock the tests first.
As for the address space for globals, this isn't something we have looked into 
yet, so I'd be in favor of keeping the same behavior as the SPIRN flavor until 
we have a reason to diverge (as in "thought about this issue" 😊)



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


[clang] [flang] [flang][driver] Avoid mentions of Clang in Flang's command line reference. (PR #88932)

2024-04-17 Thread Andrzej Warzyński via cfe-commits

banach-space wrote:

> > Clang is also mentioned for the diagnostic warnings reference, which mostly 
> > applies to C/C++/Obj-C, not Fortran. #81726 already tried to fix this, and 
> > I don't know a better solution.
> 
> Do you mean that this PR fixes this, or that you noticed this problem while 
> working on this?
> 
> If it's the latter it may be as @banach-space mentioned to me, that the 
> `docbrief` is still shared between Flang and Clang. This could be solved in a 
> similar, albeit tedious way to what I did for the help text.

@Meinersbur Could you share an example? If it's a problem specific to 
diagnostics then we should possibly just start separating Clang and Flang 
diagnostics. That could mean a bit of duplication, but not too much, so I'm not 
worried.

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


[clang] [Modules] Add -cc1 -flate-module-map-file to load module maps after PCMs (PR #88893)

2024-04-17 Thread Ilya Biryukov via cfe-commits

ilya-biryukov wrote:

There's quite a few failures:
https://gist.github.com/ilya-biryukov/380d84dfe53f839f449231eb9a2dd46c

The logic that sets up module structure from module maps before starting to 
load PCMs definitely needs to be reworked (and I'm not sure if it can be in the 
first place). I believe we get away with it internally because we always pass 
either a top-level PCM or a top-level module map for every top-level dependency 
of our compilation. Therefore, our loading of PCMs ends up being 
self-contained, which is not always the case. This probably can't be fixed.

Btw, #89005 might make this change unnecessary for us as it should also unbreak 
our existing builds.

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


[clang] [llvm] Move several vector intrinsics out of experimental namespace (PR #88748)

2024-04-17 Thread Cullen Rhodes via cfe-commits

c-rhodes wrote:

Thanks for patch. We use `interleave2` in MLIR so it'll need updating there as 
well.

I don't know what the policy is for promoting intrinsics from experimental to 
first-class or if it's documented anywhere (?), but I would expect this to be 
accompanied with an RFC / announcement on Discourse.

Also, what about `stepvector`?

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


[clang] [flang] [flang][driver] Avoid mentions of Clang in Flang's command line reference. (PR #88932)

2024-04-17 Thread Michael Kruse via cfe-commits

Meinersbur wrote:

> Do you mean that this PR fixes this, or that you noticed this problem while 
> working on this?

I noticed this when working on the patch, .i.e that 
https://flang.llvm.org/docs/FlangCommandLineReference.html still mentioned 
Clang in several places and since it was common, I didn't want to fix it only 
for `--gcc-toolchain`. `HelpTextForVariants` was introduced later, reducing the 
number of "Clang" in FlangCommandLineReference already. This fixes 
`--gcc-toolchain`, but there is no list of warnings supported by Flang, so I 
don't have anything beyond what #81726  already did.

> If it's the latter it may be as @banach-space mentioned to me, that the 
> `docbrief` is still shared between Flang and Clang. This could be solved in a 
> similar, albeit tedious way to what I did for the help text.

The docbrief strings already use `%Program`/`GlobalDocumentation.Program` which 
seems to work and made me think that `HelpTextForVariants` was actually 
unnecessary. Would you like me to introduce `DocBriefForVariants`?


> @Meinersbur Could you share an example? If it's a problem specific to 
> diagnostics then we should possibly just start separating Clang and Flang 
> diagnostics. That could mean a bit of duplication, but not too much, so I'm 
> not worried.

```
def Diag_Group : OptionGroup<"">, Group,
 DocName<"Diagnostic options">,
 DocBrief.str,
   !cond(!eq(GlobalDocumentation.Program, "Clang"):
   "See the :doc:`full list of warning and remark flags 
`.",
 true:
   "See Clang's Diagnostic Reference for a full list of 
warning and remark flags."
   )
 )>;
```


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


[clang] [llvm] Move several vector intrinsics out of experimental namespace (PR #88748)

2024-04-17 Thread Matt Arsenault via cfe-commits

arsenm wrote:

> I don't know what the policy is for promoting intrinsics from experimental to 
> first-class or if it's documented anywhere (?), but I would expect this to be 
> accompanied with an RFC / announcement on Discourse.

I don't remember any intrinsic ever making the move out of experimental. It 
seems to be a permanent prefix 

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


[clang] [llvm] Move several vector intrinsics out of experimental namespace (PR #88748)

2024-04-17 Thread Nikita Popov via cfe-commits

nikic wrote:

> > I don't know what the policy is for promoting intrinsics from experimental 
> > to first-class or if it's documented anywhere (?), but I would expect this 
> > to be accompanied with an RFC / announcement on Discourse.
> 
> I don't remember any intrinsic ever making the move out of experimental. It 
> seems to be a permanent prefix

At least the vector.reduce intrinsics were moved out of the experimental 
namespace.

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


[clang] [flang] [flang][driver] Avoid mentions of Clang in Flang's command line reference. (PR #88932)

2024-04-17 Thread Michael Kruse via cfe-commits


@@ -807,8 +807,12 @@ def gcc_install_dir_EQ : Joined<["--"], 
"gcc-install-dir=">,
   "Note: executables (e.g. ld) used by the compiler are not overridden by the 
selected GCC installation">;
 def gcc_toolchain : Joined<["--"], "gcc-toolchain=">, Flags<[NoXarchOption]>,
   Visibility<[ClangOption, FlangOption]>,
-  HelpText<"Specify a directory where Clang can find 'include' and 
'lib{,32,64}/gcc{,-cross}/$triple/$version'. "
-  "Clang will use the GCC installation with the largest version">;
+  HelpText<
+"Specify a directory where Clang can find 'include' and 
'lib{,32,64}/gcc{,-cross}/$triple/$version'. "
+"Clang will use the GCC installation with the largest version">,
+  HelpTextForVariants<[FlangOption],
+"Specify a directory where Flang can find 
'lib{,32,64}/gcc{,-cross}/$triple/$version'. "

Meinersbur wrote:

Even though flang has a (non-standard) preprocessor, it doesn't add `-isystem` 
includes from gcc's dir. Hence referencing `include` could be confusing.

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


[clang] [llvm] Move several vector intrinsics out of experimental namespace (PR #88748)

2024-04-17 Thread Maciej Gabka via cfe-commits

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


[clang] [llvm] Move several vector intrinsics out of experimental namespace (PR #88748)

2024-04-17 Thread Maciej Gabka via cfe-commits

mgabka wrote:

I was actually following this patch https://reviews.llvm.org/D127976 which 
promoted vector.insert/extract and there was no RFC for it.
My understanding is that these intrinsics are so heavily used in LLVM now so 
there is no need to call them experimental, moreover the auto upgrade ensures 
that the "experimental" name is still honoured.

My plan was to promote stepvector as well in separate PR.

I am happy to raise an RFC if you feel that it is worth it.

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


[clang] [llvm] Move several vector intrinsics out of experimental namespace (PR #88748)

2024-04-17 Thread Cullen Rhodes via cfe-commits

c-rhodes wrote:

> I was actually following this patch https://reviews.llvm.org/D127976 which 
> promoted vector.insert/extract and there was no RFC for it. My understanding 
> is that these intrinsics are so heavily used in LLVM now so there is no need 
> to call them experimental, moreover the auto upgrade ensures that the 
> "experimental" name is still honoured.
> 
> My plan was to promote stepvector as well in separate PR.

👍

> I am happy to raise an RFC if you feel that it is worth it.

The reduction intrinsics were accompanied with an RFC:
https://lists.llvm.org/pipermail/llvm-dev/2020-April/140729.html

I think at least an announcement with a link to the patch for visibility would 
be worthwhile.



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


[clang] [Clang] Allow the value of unroll count to be zero in `#pragma GCC unroll` and `#pragma unroll` (PR #88666)

2024-04-17 Thread via cfe-commits

https://github.com/yronglin updated 
https://github.com/llvm/llvm-project/pull/88666

>From 8d48a0bd1cf15b9cf00bc294912b674b5f94a11c Mon Sep 17 00:00:00 2001
From: yronglin 
Date: Mon, 15 Apr 2024 00:36:06 +0800
Subject: [PATCH 1/4] [Clang] Allow the value of unroll count to be zero  in
 '#pragma GCC unroll' and '#pragma unroll'

Signed-off-by: yronglin 
---
 clang/docs/ReleaseNotes.rst |  4 
 clang/include/clang/Sema/Sema.h |  3 ++-
 clang/lib/CodeGen/CGLoopInfo.cpp|  2 ++
 clang/lib/Parse/ParsePragma.cpp |  7 ---
 clang/lib/Sema/SemaExpr.cpp | 12 +--
 clang/lib/Sema/SemaStmtAttr.cpp | 19 +-
 clang/lib/Sema/SemaTemplateInstantiate.cpp  |  3 ++-
 clang/test/CodeGenCXX/pragma-gcc-unroll.cpp | 22 +
 clang/test/Parser/pragma-unroll.cpp |  8 ++--
 9 files changed, 66 insertions(+), 14 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index ade8f4e93d5a0c..5183edcf01b1cc 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -423,6 +423,10 @@ Bug Fixes in This Version
 - Fixed a regression in CTAD that a friend declaration that befriends itself 
may cause
   incorrect constraint substitution. (#GH86769).
 
+- Clang now allowed the value of unroll count to be zero in ``#pragma GCC 
unroll`` and ``#pragma unroll``. 
+  The values of 0 and 1 block any unrolling of the loop. This keeps the same 
behavior with GCC.
+  Fixes (`#88624 `_).
+
 Bug Fixes to Compiler Builtins
 ^^
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index c6e0332c3176b3..3b2f3a6d82675c 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5469,7 +5469,8 @@ class Sema final : public SemaBase {
   ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind);
   ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val);
 
-  bool CheckLoopHintExpr(Expr *E, SourceLocation Loc);
+  bool CheckLoopHintExpr(Expr *E, SourceLocation Loc,
+ const IdentifierInfo *PragmaNameInfo);
 
   ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope = nullptr);
   ExprResult ActOnCharacterConstant(const Token &Tok,
diff --git a/clang/lib/CodeGen/CGLoopInfo.cpp b/clang/lib/CodeGen/CGLoopInfo.cpp
index 0d4800b90a2f26..72d1471021ac02 100644
--- a/clang/lib/CodeGen/CGLoopInfo.cpp
+++ b/clang/lib/CodeGen/CGLoopInfo.cpp
@@ -673,6 +673,8 @@ void LoopInfoStack::push(BasicBlock *Header, 
clang::ASTContext &Ctx,
 setPipelineDisabled(true);
 break;
   case LoopHintAttr::UnrollCount:
+setUnrollState(LoopAttributes::Disable);
+break;
   case LoopHintAttr::UnrollAndJamCount:
   case LoopHintAttr::VectorizeWidth:
   case LoopHintAttr::InterleaveCount:
diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp
index 3979f75b6020db..8fed9e70f7a56e 100644
--- a/clang/lib/Parse/ParsePragma.cpp
+++ b/clang/lib/Parse/ParsePragma.cpp
@@ -1569,7 +1569,8 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
   ConsumeToken(); // Consume the constant expression eof terminator.
 
   if (Arg2Error || R.isInvalid() ||
-  Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation()))
+  Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation(),
+PragmaNameInfo))
 return false;
 
   // Argument is a constant expression with an integer type.
@@ -1593,8 +1594,8 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
 
 ConsumeToken(); // Consume the constant expression eof terminator.
 
-if (R.isInvalid() ||
-Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation()))
+if (R.isInvalid() || Actions.CheckLoopHintExpr(
+ R.get(), Toks[0].getLocation(), PragmaNameInfo))
   return false;
 
 // Argument is a constant expression with an integer type.
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 505d068ac42ebe..437b31716ed30c 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -3885,7 +3885,8 @@ static Expr *BuildFloatingLiteral(Sema &S, 
NumericLiteralParser &Literal,
   return FloatingLiteral::Create(S.Context, Val, isExact, Ty, Loc);
 }
 
-bool Sema::CheckLoopHintExpr(Expr *E, SourceLocation Loc) {
+bool Sema::CheckLoopHintExpr(Expr *E, SourceLocation Loc,
+ const IdentifierInfo *PragmaNameInfo) {
   assert(E && "Invalid expression");
 
   if (E->isValueDependent())
@@ -3903,7 +3904,14 @@ bool Sema::CheckLoopHintExpr(Expr *E, SourceLocation 
Loc) {
   if (R.isInvalid())
 return true;
 
-  bool ValueIsPositive = ValueAPS.isStrictlyPositive();
+  // GCC allows the value of unroll count to be 0.
+  // https://gcc.gnu.org/onlinedocs/gcc/

[clang] [clang][CodeGen][NFC] Make ConstExprEmitter a ConstStmtVisitor (PR #89041)

2024-04-17 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/89041

No reason for this to not be one. This gets rid of a few const_casts.

>From 2edf794268aa825391a37053bb5908e362ad62a6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Wed, 17 Apr 2024 11:02:20 +0200
Subject: [PATCH] [clang][CodeGen][NFC] Make ConstExprEmitter a
 ConstStmtVisitor

No reason for this to not be one. This gets rid of a few
const_casts.
---
 clang/lib/CodeGen/CGExprConstant.cpp | 108 ++-
 1 file changed, 56 insertions(+), 52 deletions(-)

diff --git a/clang/lib/CodeGen/CGExprConstant.cpp 
b/clang/lib/CodeGen/CGExprConstant.cpp
index 9f1b06eebf9ed0..c7557469954e67 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -564,12 +564,13 @@ class ConstStructBuilder {
 
 public:
   static llvm::Constant *BuildStruct(ConstantEmitter &Emitter,
- InitListExpr *ILE, QualType StructTy);
+ const InitListExpr *ILE,
+ QualType StructTy);
   static llvm::Constant *BuildStruct(ConstantEmitter &Emitter,
  const APValue &Value, QualType ValTy);
   static bool UpdateStruct(ConstantEmitter &Emitter,
ConstantAggregateBuilder &Const, CharUnits Offset,
-   InitListExpr *Updater);
+   const InitListExpr *Updater);
 
 private:
   ConstStructBuilder(ConstantEmitter &Emitter,
@@ -586,7 +587,7 @@ class ConstStructBuilder {
   bool AppendBitField(const FieldDecl *Field, uint64_t FieldOffset,
   llvm::ConstantInt *InitExpr, bool AllowOverwrite = 
false);
 
-  bool Build(InitListExpr *ILE, bool AllowOverwrite);
+  bool Build(const InitListExpr *ILE, bool AllowOverwrite);
   bool Build(const APValue &Val, const RecordDecl *RD, bool IsPrimaryBase,
  const CXXRecordDecl *VTableClass, CharUnits BaseOffset);
   llvm::Constant *Finalize(QualType Ty);
@@ -635,7 +636,7 @@ bool ConstStructBuilder::AppendBitField(
 static bool EmitDesignatedInitUpdater(ConstantEmitter &Emitter,
   ConstantAggregateBuilder &Const,
   CharUnits Offset, QualType Type,
-  InitListExpr *Updater) {
+  const InitListExpr *Updater) {
   if (Type->isRecordType())
 return ConstStructBuilder::UpdateStruct(Emitter, Const, Offset, Updater);
 
@@ -647,7 +648,7 @@ static bool EmitDesignatedInitUpdater(ConstantEmitter 
&Emitter,
   llvm::Type *ElemTy = Emitter.CGM.getTypes().ConvertTypeForMem(ElemType);
 
   llvm::Constant *FillC = nullptr;
-  if (Expr *Filler = Updater->getArrayFiller()) {
+  if (const Expr *Filler = Updater->getArrayFiller()) {
 if (!isa(Filler)) {
   FillC = Emitter.tryEmitAbstractForMemory(Filler, ElemType);
   if (!FillC)
@@ -658,7 +659,7 @@ static bool EmitDesignatedInitUpdater(ConstantEmitter 
&Emitter,
   unsigned NumElementsToUpdate =
   FillC ? CAT->getZExtSize() : Updater->getNumInits();
   for (unsigned I = 0; I != NumElementsToUpdate; ++I, Offset += ElemSize) {
-Expr *Init = nullptr;
+const Expr *Init = nullptr;
 if (I < Updater->getNumInits())
   Init = Updater->getInit(I);
 
@@ -667,7 +668,7 @@ static bool EmitDesignatedInitUpdater(ConstantEmitter 
&Emitter,
 return false;
 } else if (!Init || isa(Init)) {
   continue;
-} else if (InitListExpr *ChildILE = dyn_cast(Init)) {
+} else if (const auto *ChildILE = dyn_cast(Init)) {
   if (!EmitDesignatedInitUpdater(Emitter, Const, Offset, ElemType,
  ChildILE))
 return false;
@@ -683,7 +684,7 @@ static bool EmitDesignatedInitUpdater(ConstantEmitter 
&Emitter,
   return true;
 }
 
-bool ConstStructBuilder::Build(InitListExpr *ILE, bool AllowOverwrite) {
+bool ConstStructBuilder::Build(const InitListExpr *ILE, bool AllowOverwrite) {
   RecordDecl *RD = ILE->getType()->castAs()->getDecl();
   const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
 
@@ -711,7 +712,7 @@ bool ConstStructBuilder::Build(InitListExpr *ILE, bool 
AllowOverwrite) {
 
 // Get the initializer.  A struct can include fields without initializers,
 // we just use explicit null values for them.
-Expr *Init = nullptr;
+const Expr *Init = nullptr;
 if (ElementNo < ILE->getNumInits())
   Init = ILE->getInit(ElementNo++);
 if (Init && isa(Init))
@@ -879,7 +880,7 @@ llvm::Constant *ConstStructBuilder::Finalize(QualType Type) 
{
 }
 
 llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
-InitListExpr *ILE,
+const InitListExpr *ILE,
 QualType ValTy) {
   ConstantAg

[clang] [Clang] Allow the value of unroll count to be zero in `#pragma GCC unroll` and `#pragma unroll` (PR #88666)

2024-04-17 Thread via cfe-commits

https://github.com/yronglin updated 
https://github.com/llvm/llvm-project/pull/88666

>From 8d48a0bd1cf15b9cf00bc294912b674b5f94a11c Mon Sep 17 00:00:00 2001
From: yronglin 
Date: Mon, 15 Apr 2024 00:36:06 +0800
Subject: [PATCH 1/4] [Clang] Allow the value of unroll count to be zero  in
 '#pragma GCC unroll' and '#pragma unroll'

Signed-off-by: yronglin 
---
 clang/docs/ReleaseNotes.rst |  4 
 clang/include/clang/Sema/Sema.h |  3 ++-
 clang/lib/CodeGen/CGLoopInfo.cpp|  2 ++
 clang/lib/Parse/ParsePragma.cpp |  7 ---
 clang/lib/Sema/SemaExpr.cpp | 12 +--
 clang/lib/Sema/SemaStmtAttr.cpp | 19 +-
 clang/lib/Sema/SemaTemplateInstantiate.cpp  |  3 ++-
 clang/test/CodeGenCXX/pragma-gcc-unroll.cpp | 22 +
 clang/test/Parser/pragma-unroll.cpp |  8 ++--
 9 files changed, 66 insertions(+), 14 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index ade8f4e93d5a0c..5183edcf01b1cc 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -423,6 +423,10 @@ Bug Fixes in This Version
 - Fixed a regression in CTAD that a friend declaration that befriends itself 
may cause
   incorrect constraint substitution. (#GH86769).
 
+- Clang now allowed the value of unroll count to be zero in ``#pragma GCC 
unroll`` and ``#pragma unroll``. 
+  The values of 0 and 1 block any unrolling of the loop. This keeps the same 
behavior with GCC.
+  Fixes (`#88624 `_).
+
 Bug Fixes to Compiler Builtins
 ^^
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index c6e0332c3176b3..3b2f3a6d82675c 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5469,7 +5469,8 @@ class Sema final : public SemaBase {
   ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind);
   ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val);
 
-  bool CheckLoopHintExpr(Expr *E, SourceLocation Loc);
+  bool CheckLoopHintExpr(Expr *E, SourceLocation Loc,
+ const IdentifierInfo *PragmaNameInfo);
 
   ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope = nullptr);
   ExprResult ActOnCharacterConstant(const Token &Tok,
diff --git a/clang/lib/CodeGen/CGLoopInfo.cpp b/clang/lib/CodeGen/CGLoopInfo.cpp
index 0d4800b90a2f26..72d1471021ac02 100644
--- a/clang/lib/CodeGen/CGLoopInfo.cpp
+++ b/clang/lib/CodeGen/CGLoopInfo.cpp
@@ -673,6 +673,8 @@ void LoopInfoStack::push(BasicBlock *Header, 
clang::ASTContext &Ctx,
 setPipelineDisabled(true);
 break;
   case LoopHintAttr::UnrollCount:
+setUnrollState(LoopAttributes::Disable);
+break;
   case LoopHintAttr::UnrollAndJamCount:
   case LoopHintAttr::VectorizeWidth:
   case LoopHintAttr::InterleaveCount:
diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp
index 3979f75b6020db..8fed9e70f7a56e 100644
--- a/clang/lib/Parse/ParsePragma.cpp
+++ b/clang/lib/Parse/ParsePragma.cpp
@@ -1569,7 +1569,8 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
   ConsumeToken(); // Consume the constant expression eof terminator.
 
   if (Arg2Error || R.isInvalid() ||
-  Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation()))
+  Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation(),
+PragmaNameInfo))
 return false;
 
   // Argument is a constant expression with an integer type.
@@ -1593,8 +1594,8 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
 
 ConsumeToken(); // Consume the constant expression eof terminator.
 
-if (R.isInvalid() ||
-Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation()))
+if (R.isInvalid() || Actions.CheckLoopHintExpr(
+ R.get(), Toks[0].getLocation(), PragmaNameInfo))
   return false;
 
 // Argument is a constant expression with an integer type.
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 505d068ac42ebe..437b31716ed30c 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -3885,7 +3885,8 @@ static Expr *BuildFloatingLiteral(Sema &S, 
NumericLiteralParser &Literal,
   return FloatingLiteral::Create(S.Context, Val, isExact, Ty, Loc);
 }
 
-bool Sema::CheckLoopHintExpr(Expr *E, SourceLocation Loc) {
+bool Sema::CheckLoopHintExpr(Expr *E, SourceLocation Loc,
+ const IdentifierInfo *PragmaNameInfo) {
   assert(E && "Invalid expression");
 
   if (E->isValueDependent())
@@ -3903,7 +3904,14 @@ bool Sema::CheckLoopHintExpr(Expr *E, SourceLocation 
Loc) {
   if (R.isInvalid())
 return true;
 
-  bool ValueIsPositive = ValueAPS.isStrictlyPositive();
+  // GCC allows the value of unroll count to be 0.
+  // https://gcc.gnu.org/onlinedocs/gcc/

[clang] [clang][CodeGen][NFC] Make ConstExprEmitter a ConstStmtVisitor (PR #89041)

2024-04-17 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-codegen

Author: Timm Baeder (tbaederr)


Changes

No reason for this to not be one. This gets rid of a few const_casts.

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


1 Files Affected:

- (modified) clang/lib/CodeGen/CGExprConstant.cpp (+56-52) 


``diff
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp 
b/clang/lib/CodeGen/CGExprConstant.cpp
index 9f1b06eebf9ed0..c7557469954e67 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -564,12 +564,13 @@ class ConstStructBuilder {
 
 public:
   static llvm::Constant *BuildStruct(ConstantEmitter &Emitter,
- InitListExpr *ILE, QualType StructTy);
+ const InitListExpr *ILE,
+ QualType StructTy);
   static llvm::Constant *BuildStruct(ConstantEmitter &Emitter,
  const APValue &Value, QualType ValTy);
   static bool UpdateStruct(ConstantEmitter &Emitter,
ConstantAggregateBuilder &Const, CharUnits Offset,
-   InitListExpr *Updater);
+   const InitListExpr *Updater);
 
 private:
   ConstStructBuilder(ConstantEmitter &Emitter,
@@ -586,7 +587,7 @@ class ConstStructBuilder {
   bool AppendBitField(const FieldDecl *Field, uint64_t FieldOffset,
   llvm::ConstantInt *InitExpr, bool AllowOverwrite = 
false);
 
-  bool Build(InitListExpr *ILE, bool AllowOverwrite);
+  bool Build(const InitListExpr *ILE, bool AllowOverwrite);
   bool Build(const APValue &Val, const RecordDecl *RD, bool IsPrimaryBase,
  const CXXRecordDecl *VTableClass, CharUnits BaseOffset);
   llvm::Constant *Finalize(QualType Ty);
@@ -635,7 +636,7 @@ bool ConstStructBuilder::AppendBitField(
 static bool EmitDesignatedInitUpdater(ConstantEmitter &Emitter,
   ConstantAggregateBuilder &Const,
   CharUnits Offset, QualType Type,
-  InitListExpr *Updater) {
+  const InitListExpr *Updater) {
   if (Type->isRecordType())
 return ConstStructBuilder::UpdateStruct(Emitter, Const, Offset, Updater);
 
@@ -647,7 +648,7 @@ static bool EmitDesignatedInitUpdater(ConstantEmitter 
&Emitter,
   llvm::Type *ElemTy = Emitter.CGM.getTypes().ConvertTypeForMem(ElemType);
 
   llvm::Constant *FillC = nullptr;
-  if (Expr *Filler = Updater->getArrayFiller()) {
+  if (const Expr *Filler = Updater->getArrayFiller()) {
 if (!isa(Filler)) {
   FillC = Emitter.tryEmitAbstractForMemory(Filler, ElemType);
   if (!FillC)
@@ -658,7 +659,7 @@ static bool EmitDesignatedInitUpdater(ConstantEmitter 
&Emitter,
   unsigned NumElementsToUpdate =
   FillC ? CAT->getZExtSize() : Updater->getNumInits();
   for (unsigned I = 0; I != NumElementsToUpdate; ++I, Offset += ElemSize) {
-Expr *Init = nullptr;
+const Expr *Init = nullptr;
 if (I < Updater->getNumInits())
   Init = Updater->getInit(I);
 
@@ -667,7 +668,7 @@ static bool EmitDesignatedInitUpdater(ConstantEmitter 
&Emitter,
 return false;
 } else if (!Init || isa(Init)) {
   continue;
-} else if (InitListExpr *ChildILE = dyn_cast(Init)) {
+} else if (const auto *ChildILE = dyn_cast(Init)) {
   if (!EmitDesignatedInitUpdater(Emitter, Const, Offset, ElemType,
  ChildILE))
 return false;
@@ -683,7 +684,7 @@ static bool EmitDesignatedInitUpdater(ConstantEmitter 
&Emitter,
   return true;
 }
 
-bool ConstStructBuilder::Build(InitListExpr *ILE, bool AllowOverwrite) {
+bool ConstStructBuilder::Build(const InitListExpr *ILE, bool AllowOverwrite) {
   RecordDecl *RD = ILE->getType()->castAs()->getDecl();
   const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
 
@@ -711,7 +712,7 @@ bool ConstStructBuilder::Build(InitListExpr *ILE, bool 
AllowOverwrite) {
 
 // Get the initializer.  A struct can include fields without initializers,
 // we just use explicit null values for them.
-Expr *Init = nullptr;
+const Expr *Init = nullptr;
 if (ElementNo < ILE->getNumInits())
   Init = ILE->getInit(ElementNo++);
 if (Init && isa(Init))
@@ -879,7 +880,7 @@ llvm::Constant *ConstStructBuilder::Finalize(QualType Type) 
{
 }
 
 llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
-InitListExpr *ILE,
+const InitListExpr *ILE,
 QualType ValTy) {
   ConstantAggregateBuilder Const(Emitter.CGM);
   ConstStructBuilder Builder(Emitter, Const, CharUnits::Zero());
@@ -906,7 +907,8 @@ llvm::Constant 
*ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
 
 bool ConstStructBuilder:

[clang] [flang] [flang][driver] Avoid mentions of Clang in Flang's command line reference. (PR #88932)

2024-04-17 Thread David Spickett via cfe-commits

DavidSpickett wrote:

> The docbrief strings already use %Program/GlobalDocumentation.Program which 
> seems to work and made me think that HelpTextForVariants was actually 
> unnecessary. Would you like me to introduce DocBriefForVariants?

IIRC it was unnessecary for the documentation because it gets built multiple 
times, for the driver it's built once so it has to include all possible 
variants the first time.

I have no preference for how it's done, if the `%Program` thing works then 
fine. We only need a `ForVariants` if it's something people see when 
interacting with Flang itself I think.

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


[clang] [flang] [flang][driver] Avoid mentions of Clang in Flang's command line reference. (PR #88932)

2024-04-17 Thread David Spickett via cfe-commits

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

The changes themselves LGTM, thanks for fixing this.

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


[clang] [Clang] Allow the value of unroll count to be zero in `#pragma GCC unroll` and `#pragma unroll` (PR #88666)

2024-04-17 Thread via cfe-commits


@@ -3903,7 +3904,14 @@ bool Sema::CheckLoopHintExpr(Expr *E, SourceLocation 
Loc) {
   if (R.isInvalid())
 return true;
 
-  bool ValueIsPositive = ValueAPS.isStrictlyPositive();
+  // GCC allows the value of unroll count to be 0.
+  // https://gcc.gnu.org/onlinedocs/gcc/Loop-Specific-Pragmas.html says
+  // "The values of 0 and 1 block any unrolling of the loop."
+  // The values doesn't have to be strictly positive in '#pragma GCC unroll' 
and
+  // '#pragma unroll' cases.
+  bool ValueIsPositive = PragmaNameInfo->isStr("unroll")

yronglin wrote:

Thanks for your review! I've add a bool parameter `AllowZero` here. I want to 
go further, should we move all the string checks in `Sema::handleLoopHintAttr` 
to `Parser::HandlePragmaLoopHint`? 
(https://github.com/llvm/llvm-project/blob/ac791888bbbe58651e597cf7a4b2276424b77a92/clang/lib/Sema/SemaStmtAttr.cpp#L108)
 , these checks used to classify `LoopHintAttr::OptionType` and 
`LoopHintAttr::LoopHintState`, I'd like to classification in 
`Parser::HandlePragmaLoopHint` and pass the result into 
`Sema::handleLoopHintAttr` through `ParsedAttr`.

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


[clang] [clang][SPIR-V] Always add convervence intrinsics (PR #88918)

2024-04-17 Thread Matt Arsenault via cfe-commits
Nathan =?utf-8?q?Gauër?= 
Message-ID:
In-Reply-To: 



@@ -1109,6 +1124,10 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
   llvm::BasicBlock *CondBlock = CondDest.getBlock();
   EmitBlock(CondBlock);
 
+  if (getTarget().getTriple().isSPIRVLogical())

arsenm wrote:

None of these target checks have anything to do with the target. If you want to 
conditionally enable these for bringup, these should be hidden in an 
enableConvergenceTokenEmission or something predicate 

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


[clang] [clang][SPIR-V] Always add convervence intrinsics (PR #88918)

2024-04-17 Thread Matt Arsenault via cfe-commits
Nathan =?utf-8?q?Gauër?= 
Message-ID:
In-Reply-To: 



@@ -4824,6 +4824,9 @@ llvm::CallInst 
*CodeGenFunction::EmitRuntimeCall(llvm::FunctionCallee callee,
   llvm::CallInst *call = Builder.CreateCall(
   callee, args, getBundlesForFunclet(callee.getCallee()), name);
   call->setCallingConv(getRuntimeCC());
+
+  if (getTarget().getTriple().isSPIRVLogical() && call->isConvergent())

arsenm wrote:

Shouldn't have this target check 

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


[clang] [llvm] [WIP] Expand variadic functions in IR (PR #89007)

2024-04-17 Thread Matt Arsenault via cfe-commits


@@ -154,11 +154,20 @@ llvm::Value 
*CodeGen::emitRoundPointerUpToAlignment(CodeGenFunction &CGF,
 llvm::Value *Ptr,
 CharUnits Align) {
   // OverflowArgArea = (OverflowArgArea + Align - 1) & -Align;
+  Ptr = CGF.Builder.CreateAddrSpaceCast(Ptr, CGF.AllocaInt8PtrTy,
+Ptr->getName() + ".addrcast");

arsenm wrote:

This isn't the right place for it, I would expect this function to preserve 
whatever address space was passed in 

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


[clang] [llvm] [WIP] Expand variadic functions in IR (PR #89007)

2024-04-17 Thread Matt Arsenault via cfe-commits


@@ -154,11 +154,20 @@ llvm::Value 
*CodeGen::emitRoundPointerUpToAlignment(CodeGenFunction &CGF,
 llvm::Value *Ptr,
 CharUnits Align) {
   // OverflowArgArea = (OverflowArgArea + Align - 1) & -Align;
+  Ptr = CGF.Builder.CreateAddrSpaceCast(Ptr, CGF.AllocaInt8PtrTy,
+Ptr->getName() + ".addrcast");
   llvm::Value *RoundUp = CGF.Builder.CreateConstInBoundsGEP1_32(
   CGF.Builder.getInt8Ty(), Ptr, Align.getQuantity() - 1);
+
+  // ptrmask is sensitive to the bitwidth of the mask
+  unsigned IndexTypeSize =
+  CGF.CGM.getDataLayout().getIndexTypeSizeInBits(RoundUp->getType());
+  llvm::IntegerType *MaskType =
+  llvm::IntegerType::get(CGF.getLLVMContext(), IndexTypeSize);
+
   return CGF.Builder.CreateIntrinsic(
-  llvm::Intrinsic::ptrmask, {CGF.AllocaInt8PtrTy, CGF.IntPtrTy},
-  {RoundUp, llvm::ConstantInt::get(CGF.IntPtrTy, -Align.getQuantity())},
+  llvm::Intrinsic::ptrmask, {CGF.AllocaInt8PtrTy, MaskType},

arsenm wrote:

This seems like it was bad to begin with, I think this should have just been 
using Ptr->getType() instead of the CFG types 

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


[libclc] [llvm] [libclc] Allow building with pre-built tools (PR #88922)

2024-04-17 Thread Fraser Cormack via cfe-commits

https://github.com/frasercrmck updated 
https://github.com/llvm/llvm-project/pull/88922

>From bff3b97b599e1c9529a95ead9d61f9ecc9cad129 Mon Sep 17 00:00:00 2001
From: Fraser Cormack 
Date: Tue, 16 Apr 2024 15:30:20 +0100
Subject: [PATCH 1/5] [libclc] Convert llvm-spirv to imported executable

This tool now behaves like the others, for consistency.
---
 libclc/CMakeLists.txt | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/libclc/CMakeLists.txt b/libclc/CMakeLists.txt
index f605c3bbbe9dce..c77da2d4f18e74 100644
--- a/libclc/CMakeLists.txt
+++ b/libclc/CMakeLists.txt
@@ -81,6 +81,11 @@ endif()
 # llvm-spirv is an optional dependency, used to build spirv-* targets.
 find_program( LLVM_SPIRV llvm-spirv PATHS ${LLVM_TOOLS_BINARY_DIR} 
NO_DEFAULT_PATH )
 
+if( LLVM_SPIRV )
+  add_executable( libclc::llvm-spirv IMPORTED GLOBAL )
+  set_target_properties( libclc::llvm-spirv PROPERTIES IMPORTED_LOCATION 
${LLVM_SPIRV} )
+endif()
+
 # List of all targets. Note that some are added dynamically below.
 set( LIBCLC_TARGETS_ALL
   amdgcn--
@@ -101,7 +106,7 @@ endif()
 
 # spirv-mesa3d and spirv64-mesa3d targets can only be built with the (optional)
 # llvm-spirv external tool.
-if( LLVM_SPIRV )
+if( TARGET libclc::llvm-spirv )
   list( APPEND LIBCLC_TARGETS_ALL  spirv-mesa3d- spirv64-mesa3d- )
 endif()
 
@@ -114,7 +119,7 @@ list( SORT LIBCLC_TARGETS_TO_BUILD )
 # Verify that the user hasn't requested mesa3d targets without an available
 # llvm-spirv tool.
 if( "spirv-mesa3d-" IN_LIST LIBCLC_TARGETS_TO_BUILD OR "spirv64-mesa3d-" 
IN_LIST LIBCLC_TARGETS_TO_BUILD )
-  if( NOT LLVM_SPIRV )
+  if( NOT TARGET libclc::llvm-spirv )
 message( FATAL_ERROR "SPIR-V targets requested, but spirv-tools is not 
installed" )
   endif()
 endif()
@@ -363,7 +368,7 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} )
 if( ARCH STREQUAL spirv OR ARCH STREQUAL spirv64 )
   set( spv_suffix ${arch_suffix}.spv )
   add_custom_command( OUTPUT ${spv_suffix}
-COMMAND ${LLVM_SPIRV} ${spvflags} -o ${spv_suffix} ${builtins_link_lib}
+COMMAND libclc::llvm-spirv ${spvflags} -o ${spv_suffix} 
${builtins_link_lib}
 DEPENDS ${builtins_link_lib}
   )
   add_custom_target( "prepare-${spv_suffix}" ALL DEPENDS "${spv_suffix}" )

>From 98a9c4621c7814848c5b4fe18e41bd7c671b84ee Mon Sep 17 00:00:00 2001
From: Fraser Cormack 
Date: Tue, 16 Apr 2024 16:55:53 +0100
Subject: [PATCH 2/5] [libclc] Clarify option help message

This should make it more obvious it applies only to libclc.
---
 libclc/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libclc/CMakeLists.txt b/libclc/CMakeLists.txt
index c77da2d4f18e74..4442ff6daa61b8 100644
--- a/libclc/CMakeLists.txt
+++ b/libclc/CMakeLists.txt
@@ -32,7 +32,7 @@ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
 set( LIBCLC_MIN_LLVM 3.9.0 )
 
 set( LIBCLC_TARGETS_TO_BUILD "all"
-CACHE STRING "Semicolon-separated list of targets to build, or 'all'." )
+CACHE STRING "Semicolon-separated list of libclc targets to build, or 
'all'." )
 
 option( ENABLE_RUNTIME_SUBNORMAL "Enable runtime linking of subnormal 
support." OFF )
 

>From 4257979d8ee548672b8507bd00486fae98481e3b Mon Sep 17 00:00:00 2001
From: Fraser Cormack 
Date: Tue, 16 Apr 2024 16:46:37 +0100
Subject: [PATCH 3/5] [libclc] Allow building with pre-built tools

Building the libclc project in-tree with debug tools can be very slow.
This commit adds an option for a user to specify a dierctory from which
to import (e.g., release-built) tools. All tools required by the project
must be imported from the same location, for simplicity.

Original patch downstream authored by @jchlanda.
---
 libclc/CMakeLists.txt | 33 +++--
 1 file changed, 27 insertions(+), 6 deletions(-)

diff --git a/libclc/CMakeLists.txt b/libclc/CMakeLists.txt
index 4442ff6daa61b8..b0c29ed77270cf 100644
--- a/libclc/CMakeLists.txt
+++ b/libclc/CMakeLists.txt
@@ -50,11 +50,13 @@ if( LIBCLC_STANDALONE_BUILD OR CMAKE_SOURCE_DIR STREQUAL 
CMAKE_CURRENT_SOURCE_DI
   endif()
 
   # Import required tools as targets
-  foreach( tool IN ITEMS clang llvm-as llvm-link opt )
-find_program( LLVM_TOOL_${tool} ${tool} PATHS ${LLVM_TOOLS_BINARY_DIR} 
NO_DEFAULT_PATH )
-add_executable( libclc::${tool} IMPORTED GLOBAL )
-set_target_properties( libclc::${tool} PROPERTIES IMPORTED_LOCATION 
${LLVM_TOOL_${tool}} )
-  endforeach()
+  if( NOT EXISTS ${LIBCLC_CUSTOM_LLVM_TOOLS_BINARY_DIR} )
+foreach( tool IN ITEMS clang llvm-as llvm-link opt )
+  find_program( LLVM_TOOL_${tool} ${tool} PATHS ${LLVM_TOOLS_BINARY_DIR} 
NO_DEFAULT_PATH )
+  add_executable( libclc::${tool} IMPORTED GLOBAL )
+  set_target_properties( libclc::${tool} PROPERTIES IMPORTED_LOCATION 
${LLVM_TOOL_${tool}} )
+endforeach()
+  endif()
 else()
   # In-tree configuration
   set( LIBCLC_STANDALONE_BUILD FALSE )
@@ -68,8 +70,27 @@ else()
 message(FATAL_ERROR "Clang is not enabled, 

[clang] [Clang][Sema] placement new initializes typedef array with correct size (PR #89036)

2024-04-17 Thread via cfe-commits

https://github.com/mahtohappy updated 
https://github.com/llvm/llvm-project/pull/89036

>From 56c2b4f70735a6ef3b80cb8461a88ea51f2d02d7 Mon Sep 17 00:00:00 2001
From: mahtohappy 
Date: Tue, 16 Apr 2024 17:48:45 +0530
Subject: [PATCH 1/4] [Clang][Sema] placement new initializes typedef array
 with correct size (#83124)

When in-place new-ing a local variable of an array of trivial type, the
generated code calls 'memset' with the correct size of the array,
earlier it was generating size (squared of the typedef array + size).

The cause: `typedef TYPE TArray[8]; TArray x;` The type of declarator is
Tarray[8] and in `SemaExprCXX.cpp::BuildCXXNew` we check if it's of
typedef and of constant size then we get the original type and it works
fine for non-dependent cases.
But in case of template we do `TreeTransform.h:TransformCXXNEWExpr` and
there we again check the allocated type which is TArray[8] and it stays
that way, so ArraySize=(Tarray[8] type, alloc Tarray[8*type]) so the
squared size allocation.

ArraySize gets calculated earlier in `TreeTransform.h` so that
`if(!ArraySize)` condition was failing.
fix: I changed that condition to `if(ArraySize)`.


Fixes #41441
---
 clang/docs/ReleaseNotes.rst   |  2 ++
 clang/lib/Sema/TreeTransform.h| 14 -
 .../instantiate-new-placement-size.cpp| 20 +++
 3 files changed, 35 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/SemaCXX/instantiate-new-placement-size.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 96ad92b540b47f..636d76f1836759 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -534,6 +534,8 @@ Bug Fixes to C++ Support
   Fixes (#GH70604), (#GH79754), (#GH84163), (#GH84425), (#GH86054), 
(#GH86398), and (#GH86399).
 - Fix a crash when deducing ``auto`` from an invalid dereference (#GH88329).
 - Fix a crash in requires expression with templated base class member 
function. Fixes (#GH84020).
+- placement new initializes typedef array with correct size
+  (`#GH41441 `_)
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index eb05783a6219dc..0c7fdb357235e1 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -12864,6 +12864,19 @@ TreeTransform::TransformCXXNewExpr(CXXNewExpr 
*E) {
 ArraySize = NewArraySize.get();
   }
 
+  // Per C++0x [expr.new]p5, the type being constructed may be a
+  // typedef of an array type.
+  QualType AllocType = AllocTypeInfo->getType();
+  if (ArraySize) {
+if (const ConstantArrayType *Array =
+SemaRef.Context.getAsConstantArrayType(AllocType)) {
+  ArraySize = IntegerLiteral::Create(SemaRef.Context, Array->getSize(),
+ SemaRef.Context.getSizeType(),
+ E->getBeginLoc());
+  AllocType = Array->getElementType();
+}
+  }
+
   // Transform the placement arguments (if any).
   bool ArgumentChanged = false;
   SmallVector PlacementArgs;
@@ -12925,7 +12938,6 @@ TreeTransform::TransformCXXNewExpr(CXXNewExpr 
*E) {
 return E;
   }
 
-  QualType AllocType = AllocTypeInfo->getType();
   if (!ArraySize) {
 // If no array size was specified, but the new expression was
 // instantiated with an array type (e.g., "new T" where T is
diff --git a/clang/test/SemaCXX/instantiate-new-placement-size.cpp 
b/clang/test/SemaCXX/instantiate-new-placement-size.cpp
new file mode 100644
index 00..7a29d3dee8491e
--- /dev/null
+++ b/clang/test/SemaCXX/instantiate-new-placement-size.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang -S -fno-discard-value-names -emit-llvm -o - %s | FileCheck %s
+// Issue no: 41441
+#include 
+
+// CHECK: call void @llvm.memset.p0.i64(ptr align 1 %x, i8 0, i64 8, i1 false)
+// CHECK: call void @llvm.memset.p0.i64(ptr align 16 %x, i8 0, i64 32, i1 
false)
+template 
+void f()
+{
+typedef TYPE TArray[8];
+
+TArray x;
+new(&x) TArray();
+}
+
+int main()
+{
+f();
+f();
+}

>From bdd7f66e560f60d1f0027b04ad12989b2f786df3 Mon Sep 17 00:00:00 2001
From: mahtohappy 
Date: Wed, 17 Apr 2024 00:12:14 +0530
Subject: [PATCH 2/4] [Clang][Sema] placement new initializes typedef array
 with correct size (#88902)

Build Failure Fix
Fixes build failures due to #83124
---
 .../{instantiate-new-placement-size.cpp => PR41441.cpp}   | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
 rename clang/test/SemaCXX/{instantiate-new-placement-size.cpp => PR41441.cpp} 
(75%)

diff --git a/clang/test/SemaCXX/instantiate-new-placement-size.cpp 
b/clang/test/SemaCXX/PR41441.cpp
similarity index 75%
rename from clang/test/SemaCXX/instantiate-new-placement-size.cpp
rename to clang/test/SemaCXX/PR41441.cpp
index 7a29d3dee8491e..0b012b33fce343 100644
--- a/clang/test/SemaCXX/instantiate-new-placement-size.cpp
+++ b/clang/tes

[clang-tools-extra] [clang-tidy] Ignore deleted ctor in `bugprone-forwarding-reference-overload` (PR #88138)

2024-04-17 Thread Congcong Cai via cfe-commits

HerrCai0907 wrote:

I can help you to merge it. 😄 

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


[clang] [Clang][Sema] placement new initializes typedef array with correct size (PR #89036)

2024-04-17 Thread via cfe-commits

https://github.com/mahtohappy updated 
https://github.com/llvm/llvm-project/pull/89036

>From 56c2b4f70735a6ef3b80cb8461a88ea51f2d02d7 Mon Sep 17 00:00:00 2001
From: mahtohappy 
Date: Tue, 16 Apr 2024 17:48:45 +0530
Subject: [PATCH 1/4] [Clang][Sema] placement new initializes typedef array
 with correct size (#83124)

When in-place new-ing a local variable of an array of trivial type, the
generated code calls 'memset' with the correct size of the array,
earlier it was generating size (squared of the typedef array + size).

The cause: `typedef TYPE TArray[8]; TArray x;` The type of declarator is
Tarray[8] and in `SemaExprCXX.cpp::BuildCXXNew` we check if it's of
typedef and of constant size then we get the original type and it works
fine for non-dependent cases.
But in case of template we do `TreeTransform.h:TransformCXXNEWExpr` and
there we again check the allocated type which is TArray[8] and it stays
that way, so ArraySize=(Tarray[8] type, alloc Tarray[8*type]) so the
squared size allocation.

ArraySize gets calculated earlier in `TreeTransform.h` so that
`if(!ArraySize)` condition was failing.
fix: I changed that condition to `if(ArraySize)`.


Fixes #41441
---
 clang/docs/ReleaseNotes.rst   |  2 ++
 clang/lib/Sema/TreeTransform.h| 14 -
 .../instantiate-new-placement-size.cpp| 20 +++
 3 files changed, 35 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/SemaCXX/instantiate-new-placement-size.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 96ad92b540b47f..636d76f1836759 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -534,6 +534,8 @@ Bug Fixes to C++ Support
   Fixes (#GH70604), (#GH79754), (#GH84163), (#GH84425), (#GH86054), 
(#GH86398), and (#GH86399).
 - Fix a crash when deducing ``auto`` from an invalid dereference (#GH88329).
 - Fix a crash in requires expression with templated base class member 
function. Fixes (#GH84020).
+- placement new initializes typedef array with correct size
+  (`#GH41441 `_)
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index eb05783a6219dc..0c7fdb357235e1 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -12864,6 +12864,19 @@ TreeTransform::TransformCXXNewExpr(CXXNewExpr 
*E) {
 ArraySize = NewArraySize.get();
   }
 
+  // Per C++0x [expr.new]p5, the type being constructed may be a
+  // typedef of an array type.
+  QualType AllocType = AllocTypeInfo->getType();
+  if (ArraySize) {
+if (const ConstantArrayType *Array =
+SemaRef.Context.getAsConstantArrayType(AllocType)) {
+  ArraySize = IntegerLiteral::Create(SemaRef.Context, Array->getSize(),
+ SemaRef.Context.getSizeType(),
+ E->getBeginLoc());
+  AllocType = Array->getElementType();
+}
+  }
+
   // Transform the placement arguments (if any).
   bool ArgumentChanged = false;
   SmallVector PlacementArgs;
@@ -12925,7 +12938,6 @@ TreeTransform::TransformCXXNewExpr(CXXNewExpr 
*E) {
 return E;
   }
 
-  QualType AllocType = AllocTypeInfo->getType();
   if (!ArraySize) {
 // If no array size was specified, but the new expression was
 // instantiated with an array type (e.g., "new T" where T is
diff --git a/clang/test/SemaCXX/instantiate-new-placement-size.cpp 
b/clang/test/SemaCXX/instantiate-new-placement-size.cpp
new file mode 100644
index 00..7a29d3dee8491e
--- /dev/null
+++ b/clang/test/SemaCXX/instantiate-new-placement-size.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang -S -fno-discard-value-names -emit-llvm -o - %s | FileCheck %s
+// Issue no: 41441
+#include 
+
+// CHECK: call void @llvm.memset.p0.i64(ptr align 1 %x, i8 0, i64 8, i1 false)
+// CHECK: call void @llvm.memset.p0.i64(ptr align 16 %x, i8 0, i64 32, i1 
false)
+template 
+void f()
+{
+typedef TYPE TArray[8];
+
+TArray x;
+new(&x) TArray();
+}
+
+int main()
+{
+f();
+f();
+}

>From bdd7f66e560f60d1f0027b04ad12989b2f786df3 Mon Sep 17 00:00:00 2001
From: mahtohappy 
Date: Wed, 17 Apr 2024 00:12:14 +0530
Subject: [PATCH 2/4] [Clang][Sema] placement new initializes typedef array
 with correct size (#88902)

Build Failure Fix
Fixes build failures due to #83124
---
 .../{instantiate-new-placement-size.cpp => PR41441.cpp}   | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
 rename clang/test/SemaCXX/{instantiate-new-placement-size.cpp => PR41441.cpp} 
(75%)

diff --git a/clang/test/SemaCXX/instantiate-new-placement-size.cpp 
b/clang/test/SemaCXX/PR41441.cpp
similarity index 75%
rename from clang/test/SemaCXX/instantiate-new-placement-size.cpp
rename to clang/test/SemaCXX/PR41441.cpp
index 7a29d3dee8491e..0b012b33fce343 100644
--- a/clang/test/SemaCXX/instantiate-new-placement-size.cpp
+++ b/clang/tes

[clang-tools-extra] [clang-tidy] Ignore deleted ctor in `bugprone-forwarding-reference-overload` (PR #88138)

2024-04-17 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff a71565d75e23fc28076aa5bf1c5cf4432623afc5 
bab66e16f29367fa44002d9d31c328607c734354 -- 
clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp 
clang-tools-extra/test/clang-tidy/checkers/bugprone/forwarding-reference-overload.cpp
``





View the diff from clang-format here.


``diff
diff --git 
a/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp
index e42b40d7b6..e7be813478 100644
--- a/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp
@@ -72,8 +72,7 @@ void 
ForwardingReferenceOverloadCheck::registerMatchers(MatchFinder *Finder) {
 
   DeclarationMatcher FindOverload =
   cxxConstructorDecl(
-  hasParameter(0, ForwardingRefParm),
-  unless(isDeleted()),
+  hasParameter(0, ForwardingRefParm), unless(isDeleted()),
   unless(hasAnyParameter(
   // No warning: enable_if as constructor parameter.
   parmVarDecl(hasType(isEnableIf(),

``




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


[clang] [llvm] [WIP] Expand variadic functions in IR (PR #89007)

2024-04-17 Thread Matt Arsenault via cfe-commits


@@ -115,7 +115,13 @@ void AMDGPUABIInfo::computeInfo(CGFunctionInfo &FI) const {
 
 Address AMDGPUABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
  QualType Ty) const {
-  llvm_unreachable("AMDGPU does not support varargs");
+  const bool IsIndirect = false;
+  const bool AllowHigherAlign = true;
+  // Would rather not naturally align values
+  // Splitting {char, short} into two separate arguments makes that difficult.

arsenm wrote:

Not sure what this comment is saying. 4 is the only correct alignment for 
anything stack related 

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


[clang] [llvm] [WIP] Expand variadic functions in IR (PR #89007)

2024-04-17 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,43 @@
+//===- ExpandVariadics.h - expand variadic functions *- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+#ifndef LLVM_TRANSFORMS_IPO_EXPANDVARIADICS_H
+#define LLVM_TRANSFORMS_IPO_EXPANDVARIADICS_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class Module;
+class ModulePass;
+class OptimizationLevel;
+
+enum class ExpandVariadicsMode {
+  unspecified,

arsenm wrote:

Capitalize and document the fields 

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


[clang] [llvm] [WIP] Expand variadic functions in IR (PR #89007)

2024-04-17 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,1056 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a varidic function into a va_list
+// and fix up the call sites. This is completely effective if the calling
+// convention can declare that to be the right thing, e.g. on GPUs or where
+// the application is wholly statically linked. In the usual case, it will
+// replace known calls to known variadic functions with calls that are amenable
+// to inlining and other optimisations.
+//
+// The target-dependent parts are in class VariadicABIInfo. Enabling a new
+// target means adding a case to VariadicABIInfo::create() along with tests.
+// This will be especially simple if the va_list representation is a char*.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. The target specific
+// part is packing arguments into a contiguous buffer that the clang expansion
+// of va_arg will do the right thing with.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+
+#include 
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::lowering, "lowering",
+  "Change variadic calling convention")));
+
+namespace {
+
+// Module implements getFunction() which returns nullptr on missing declaration
+// and getOrInsertFunction which creates one when absent. Intrinsics.h
+// implements getDeclaration which creates one when missing. This should be
+// changed to be consistent with Module()'s naming. Implementing as a local
+// function here in the meantime to decouple from that process.
+Function *getPreexistingDeclaration(Module *M, Intrinsic::ID id,
+ArrayRef Tys = std::nullopt) {
+  auto *FT = Intrinsic::getType(M->getContext(), id, Tys);
+  return M->getFunction(Tys.empty() ? Intrinsic::getName(id)
+: Intrinsic::getName(id, Tys, M, FT));
+}
+
+// Lots of targets use a void* pointed at a buffer for va_list.
+// Some use more complicated iterator constructs. Type erase that
+// so the rest of the pass can operation on either.
+// Virtual functions where different targets want different behaviour,
+// normal where all implemented targets presently have the same.
+struct VAListInterface {
+  virtual ~VAListInterface() {}
+
+  // Whether a valist instance is passed by value or by address
+  // I.e. does it need to be alloca'ed and stored into, or can
+  // it be passed directly in a SSA register
+  virtual bool passedInSSARegister() = 0;
+
+  // The type of a va_list iterator object
+  virtual Type *vaListType(LLVMContext &Ctx) = 0;
+
+  // The type of a va_list as a function argument as lowered by C
+  vir

[clang] [llvm] [WIP] Expand variadic functions in IR (PR #89007)

2024-04-17 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,1056 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a varidic function into a va_list
+// and fix up the call sites. This is completely effective if the calling
+// convention can declare that to be the right thing, e.g. on GPUs or where
+// the application is wholly statically linked. In the usual case, it will
+// replace known calls to known variadic functions with calls that are amenable
+// to inlining and other optimisations.
+//
+// The target-dependent parts are in class VariadicABIInfo. Enabling a new
+// target means adding a case to VariadicABIInfo::create() along with tests.
+// This will be especially simple if the va_list representation is a char*.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. The target specific
+// part is packing arguments into a contiguous buffer that the clang expansion
+// of va_arg will do the right thing with.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+
+#include 
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::lowering, "lowering",
+  "Change variadic calling convention")));
+
+namespace {
+
+// Module implements getFunction() which returns nullptr on missing declaration
+// and getOrInsertFunction which creates one when absent. Intrinsics.h
+// implements getDeclaration which creates one when missing. This should be
+// changed to be consistent with Module()'s naming. Implementing as a local
+// function here in the meantime to decouple from that process.
+Function *getPreexistingDeclaration(Module *M, Intrinsic::ID id,
+ArrayRef Tys = std::nullopt) {
+  auto *FT = Intrinsic::getType(M->getContext(), id, Tys);
+  return M->getFunction(Tys.empty() ? Intrinsic::getName(id)
+: Intrinsic::getName(id, Tys, M, FT));
+}
+
+// Lots of targets use a void* pointed at a buffer for va_list.
+// Some use more complicated iterator constructs. Type erase that
+// so the rest of the pass can operation on either.
+// Virtual functions where different targets want different behaviour,
+// normal where all implemented targets presently have the same.
+struct VAListInterface {
+  virtual ~VAListInterface() {}
+
+  // Whether a valist instance is passed by value or by address
+  // I.e. does it need to be alloca'ed and stored into, or can
+  // it be passed directly in a SSA register
+  virtual bool passedInSSARegister() = 0;
+
+  // The type of a va_list iterator object
+  virtual Type *vaListType(LLVMContext &Ctx) = 0;
+
+  // The type of a va_list as a function argument as lowered by C
+  vir

[clang] [llvm] [WIP] Expand variadic functions in IR (PR #89007)

2024-04-17 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,1056 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a varidic function into a va_list
+// and fix up the call sites. This is completely effective if the calling
+// convention can declare that to be the right thing, e.g. on GPUs or where
+// the application is wholly statically linked. In the usual case, it will
+// replace known calls to known variadic functions with calls that are amenable
+// to inlining and other optimisations.
+//
+// The target-dependent parts are in class VariadicABIInfo. Enabling a new
+// target means adding a case to VariadicABIInfo::create() along with tests.
+// This will be especially simple if the va_list representation is a char*.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. The target specific
+// part is packing arguments into a contiguous buffer that the clang expansion
+// of va_arg will do the right thing with.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+
+#include 
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::lowering, "lowering",
+  "Change variadic calling convention")));
+
+namespace {
+
+// Module implements getFunction() which returns nullptr on missing declaration
+// and getOrInsertFunction which creates one when absent. Intrinsics.h
+// implements getDeclaration which creates one when missing. This should be
+// changed to be consistent with Module()'s naming. Implementing as a local
+// function here in the meantime to decouple from that process.
+Function *getPreexistingDeclaration(Module *M, Intrinsic::ID id,
+ArrayRef Tys = std::nullopt) {
+  auto *FT = Intrinsic::getType(M->getContext(), id, Tys);
+  return M->getFunction(Tys.empty() ? Intrinsic::getName(id)
+: Intrinsic::getName(id, Tys, M, FT));
+}
+
+// Lots of targets use a void* pointed at a buffer for va_list.
+// Some use more complicated iterator constructs. Type erase that
+// so the rest of the pass can operation on either.
+// Virtual functions where different targets want different behaviour,
+// normal where all implemented targets presently have the same.
+struct VAListInterface {
+  virtual ~VAListInterface() {}
+
+  // Whether a valist instance is passed by value or by address
+  // I.e. does it need to be alloca'ed and stored into, or can
+  // it be passed directly in a SSA register
+  virtual bool passedInSSARegister() = 0;
+
+  // The type of a va_list iterator object
+  virtual Type *vaListType(LLVMContext &Ctx) = 0;
+
+  // The type of a va_list as a function argument as lowered by C
+  vir

[clang] [llvm] [WIP] Expand variadic functions in IR (PR #89007)

2024-04-17 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,1056 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a varidic function into a va_list
+// and fix up the call sites. This is completely effective if the calling
+// convention can declare that to be the right thing, e.g. on GPUs or where
+// the application is wholly statically linked. In the usual case, it will
+// replace known calls to known variadic functions with calls that are amenable
+// to inlining and other optimisations.
+//
+// The target-dependent parts are in class VariadicABIInfo. Enabling a new
+// target means adding a case to VariadicABIInfo::create() along with tests.
+// This will be especially simple if the va_list representation is a char*.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. The target specific
+// part is packing arguments into a contiguous buffer that the clang expansion
+// of va_arg will do the right thing with.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+
+#include 
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::lowering, "lowering",
+  "Change variadic calling convention")));
+
+namespace {
+
+// Module implements getFunction() which returns nullptr on missing declaration
+// and getOrInsertFunction which creates one when absent. Intrinsics.h
+// implements getDeclaration which creates one when missing. This should be
+// changed to be consistent with Module()'s naming. Implementing as a local
+// function here in the meantime to decouple from that process.
+Function *getPreexistingDeclaration(Module *M, Intrinsic::ID id,
+ArrayRef Tys = std::nullopt) {
+  auto *FT = Intrinsic::getType(M->getContext(), id, Tys);
+  return M->getFunction(Tys.empty() ? Intrinsic::getName(id)
+: Intrinsic::getName(id, Tys, M, FT));
+}
+
+// Lots of targets use a void* pointed at a buffer for va_list.
+// Some use more complicated iterator constructs. Type erase that
+// so the rest of the pass can operation on either.
+// Virtual functions where different targets want different behaviour,
+// normal where all implemented targets presently have the same.
+struct VAListInterface {
+  virtual ~VAListInterface() {}
+
+  // Whether a valist instance is passed by value or by address
+  // I.e. does it need to be alloca'ed and stored into, or can
+  // it be passed directly in a SSA register
+  virtual bool passedInSSARegister() = 0;
+
+  // The type of a va_list iterator object
+  virtual Type *vaListType(LLVMContext &Ctx) = 0;
+
+  // The type of a va_list as a function argument as lowered by C
+  vir

[clang] [llvm] [WIP] Expand variadic functions in IR (PR #89007)

2024-04-17 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,1056 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a varidic function into a va_list
+// and fix up the call sites. This is completely effective if the calling
+// convention can declare that to be the right thing, e.g. on GPUs or where
+// the application is wholly statically linked. In the usual case, it will
+// replace known calls to known variadic functions with calls that are amenable
+// to inlining and other optimisations.
+//
+// The target-dependent parts are in class VariadicABIInfo. Enabling a new
+// target means adding a case to VariadicABIInfo::create() along with tests.
+// This will be especially simple if the va_list representation is a char*.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. The target specific
+// part is packing arguments into a contiguous buffer that the clang expansion
+// of va_arg will do the right thing with.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+
+#include 
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::lowering, "lowering",
+  "Change variadic calling convention")));
+
+namespace {
+
+// Module implements getFunction() which returns nullptr on missing declaration
+// and getOrInsertFunction which creates one when absent. Intrinsics.h
+// implements getDeclaration which creates one when missing. This should be
+// changed to be consistent with Module()'s naming. Implementing as a local
+// function here in the meantime to decouple from that process.
+Function *getPreexistingDeclaration(Module *M, Intrinsic::ID id,
+ArrayRef Tys = std::nullopt) {
+  auto *FT = Intrinsic::getType(M->getContext(), id, Tys);
+  return M->getFunction(Tys.empty() ? Intrinsic::getName(id)
+: Intrinsic::getName(id, Tys, M, FT));
+}
+
+// Lots of targets use a void* pointed at a buffer for va_list.
+// Some use more complicated iterator constructs. Type erase that
+// so the rest of the pass can operation on either.
+// Virtual functions where different targets want different behaviour,
+// normal where all implemented targets presently have the same.
+struct VAListInterface {
+  virtual ~VAListInterface() {}
+
+  // Whether a valist instance is passed by value or by address
+  // I.e. does it need to be alloca'ed and stored into, or can
+  // it be passed directly in a SSA register
+  virtual bool passedInSSARegister() = 0;
+
+  // The type of a va_list iterator object
+  virtual Type *vaListType(LLVMContext &Ctx) = 0;
+
+  // The type of a va_list as a function argument as lowered by C
+  vir

[clang] [llvm] [WIP] Expand variadic functions in IR (PR #89007)

2024-04-17 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,1056 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a varidic function into a va_list
+// and fix up the call sites. This is completely effective if the calling
+// convention can declare that to be the right thing, e.g. on GPUs or where
+// the application is wholly statically linked. In the usual case, it will
+// replace known calls to known variadic functions with calls that are amenable
+// to inlining and other optimisations.
+//
+// The target-dependent parts are in class VariadicABIInfo. Enabling a new
+// target means adding a case to VariadicABIInfo::create() along with tests.
+// This will be especially simple if the va_list representation is a char*.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. The target specific
+// part is packing arguments into a contiguous buffer that the clang expansion
+// of va_arg will do the right thing with.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+
+#include 
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::lowering, "lowering",
+  "Change variadic calling convention")));
+
+namespace {
+
+// Module implements getFunction() which returns nullptr on missing declaration
+// and getOrInsertFunction which creates one when absent. Intrinsics.h
+// implements getDeclaration which creates one when missing. This should be
+// changed to be consistent with Module()'s naming. Implementing as a local
+// function here in the meantime to decouple from that process.
+Function *getPreexistingDeclaration(Module *M, Intrinsic::ID id,
+ArrayRef Tys = std::nullopt) {

arsenm wrote:

```suggestion
ArrayRef Tys = {}) {
```

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


[clang] [llvm] [WIP] Expand variadic functions in IR (PR #89007)

2024-04-17 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,1056 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a varidic function into a va_list
+// and fix up the call sites. This is completely effective if the calling
+// convention can declare that to be the right thing, e.g. on GPUs or where
+// the application is wholly statically linked. In the usual case, it will
+// replace known calls to known variadic functions with calls that are amenable
+// to inlining and other optimisations.
+//
+// The target-dependent parts are in class VariadicABIInfo. Enabling a new
+// target means adding a case to VariadicABIInfo::create() along with tests.
+// This will be especially simple if the va_list representation is a char*.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. The target specific
+// part is packing arguments into a contiguous buffer that the clang expansion
+// of va_arg will do the right thing with.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+
+#include 
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::lowering, "lowering",
+  "Change variadic calling convention")));
+
+namespace {
+
+// Module implements getFunction() which returns nullptr on missing declaration
+// and getOrInsertFunction which creates one when absent. Intrinsics.h
+// implements getDeclaration which creates one when missing. This should be
+// changed to be consistent with Module()'s naming. Implementing as a local
+// function here in the meantime to decouple from that process.
+Function *getPreexistingDeclaration(Module *M, Intrinsic::ID id,
+ArrayRef Tys = std::nullopt) {
+  auto *FT = Intrinsic::getType(M->getContext(), id, Tys);
+  return M->getFunction(Tys.empty() ? Intrinsic::getName(id)
+: Intrinsic::getName(id, Tys, M, FT));
+}
+
+// Lots of targets use a void* pointed at a buffer for va_list.
+// Some use more complicated iterator constructs. Type erase that
+// so the rest of the pass can operation on either.
+// Virtual functions where different targets want different behaviour,
+// normal where all implemented targets presently have the same.
+struct VAListInterface {
+  virtual ~VAListInterface() {}
+
+  // Whether a valist instance is passed by value or by address
+  // I.e. does it need to be alloca'ed and stored into, or can
+  // it be passed directly in a SSA register
+  virtual bool passedInSSARegister() = 0;
+
+  // The type of a va_list iterator object
+  virtual Type *vaListType(LLVMContext &Ctx) = 0;
+
+  // The type of a va_list as a function argument as lowered by C
+  vir

[clang] [llvm] [WIP] Expand variadic functions in IR (PR #89007)

2024-04-17 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,1056 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a varidic function into a va_list
+// and fix up the call sites. This is completely effective if the calling
+// convention can declare that to be the right thing, e.g. on GPUs or where
+// the application is wholly statically linked. In the usual case, it will
+// replace known calls to known variadic functions with calls that are amenable
+// to inlining and other optimisations.
+//
+// The target-dependent parts are in class VariadicABIInfo. Enabling a new
+// target means adding a case to VariadicABIInfo::create() along with tests.
+// This will be especially simple if the va_list representation is a char*.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. The target specific
+// part is packing arguments into a contiguous buffer that the clang expansion
+// of va_arg will do the right thing with.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+
+#include 
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::lowering, "lowering",
+  "Change variadic calling convention")));
+
+namespace {
+
+// Module implements getFunction() which returns nullptr on missing declaration
+// and getOrInsertFunction which creates one when absent. Intrinsics.h
+// implements getDeclaration which creates one when missing. This should be
+// changed to be consistent with Module()'s naming. Implementing as a local
+// function here in the meantime to decouple from that process.
+Function *getPreexistingDeclaration(Module *M, Intrinsic::ID id,
+ArrayRef Tys = std::nullopt) {
+  auto *FT = Intrinsic::getType(M->getContext(), id, Tys);
+  return M->getFunction(Tys.empty() ? Intrinsic::getName(id)
+: Intrinsic::getName(id, Tys, M, FT));
+}
+
+// Lots of targets use a void* pointed at a buffer for va_list.
+// Some use more complicated iterator constructs. Type erase that
+// so the rest of the pass can operation on either.
+// Virtual functions where different targets want different behaviour,
+// normal where all implemented targets presently have the same.
+struct VAListInterface {
+  virtual ~VAListInterface() {}
+
+  // Whether a valist instance is passed by value or by address
+  // I.e. does it need to be alloca'ed and stored into, or can
+  // it be passed directly in a SSA register
+  virtual bool passedInSSARegister() = 0;
+
+  // The type of a va_list iterator object
+  virtual Type *vaListType(LLVMContext &Ctx) = 0;
+
+  // The type of a va_list as a function argument as lowered by C
+  vir

[clang] [llvm] [WIP] Expand variadic functions in IR (PR #89007)

2024-04-17 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,1056 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a varidic function into a va_list
+// and fix up the call sites. This is completely effective if the calling
+// convention can declare that to be the right thing, e.g. on GPUs or where
+// the application is wholly statically linked. In the usual case, it will
+// replace known calls to known variadic functions with calls that are amenable
+// to inlining and other optimisations.
+//
+// The target-dependent parts are in class VariadicABIInfo. Enabling a new
+// target means adding a case to VariadicABIInfo::create() along with tests.
+// This will be especially simple if the va_list representation is a char*.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. The target specific
+// part is packing arguments into a contiguous buffer that the clang expansion
+// of va_arg will do the right thing with.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+
+#include 
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::lowering, "lowering",
+  "Change variadic calling convention")));
+
+namespace {
+
+// Module implements getFunction() which returns nullptr on missing declaration
+// and getOrInsertFunction which creates one when absent. Intrinsics.h
+// implements getDeclaration which creates one when missing. This should be
+// changed to be consistent with Module()'s naming. Implementing as a local
+// function here in the meantime to decouple from that process.
+Function *getPreexistingDeclaration(Module *M, Intrinsic::ID id,
+ArrayRef Tys = std::nullopt) {
+  auto *FT = Intrinsic::getType(M->getContext(), id, Tys);
+  return M->getFunction(Tys.empty() ? Intrinsic::getName(id)
+: Intrinsic::getName(id, Tys, M, FT));
+}
+
+// Lots of targets use a void* pointed at a buffer for va_list.
+// Some use more complicated iterator constructs. Type erase that
+// so the rest of the pass can operation on either.
+// Virtual functions where different targets want different behaviour,
+// normal where all implemented targets presently have the same.
+struct VAListInterface {
+  virtual ~VAListInterface() {}
+
+  // Whether a valist instance is passed by value or by address
+  // I.e. does it need to be alloca'ed and stored into, or can
+  // it be passed directly in a SSA register
+  virtual bool passedInSSARegister() = 0;
+
+  // The type of a va_list iterator object
+  virtual Type *vaListType(LLVMContext &Ctx) = 0;
+
+  // The type of a va_list as a function argument as lowered by C
+  vir

[clang] [llvm] [WIP] Expand variadic functions in IR (PR #89007)

2024-04-17 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,1056 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a varidic function into a va_list
+// and fix up the call sites. This is completely effective if the calling
+// convention can declare that to be the right thing, e.g. on GPUs or where
+// the application is wholly statically linked. In the usual case, it will
+// replace known calls to known variadic functions with calls that are amenable
+// to inlining and other optimisations.
+//
+// The target-dependent parts are in class VariadicABIInfo. Enabling a new
+// target means adding a case to VariadicABIInfo::create() along with tests.
+// This will be especially simple if the va_list representation is a char*.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. The target specific
+// part is packing arguments into a contiguous buffer that the clang expansion
+// of va_arg will do the right thing with.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+
+#include 
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::lowering, "lowering",
+  "Change variadic calling convention")));
+
+namespace {
+
+// Module implements getFunction() which returns nullptr on missing declaration
+// and getOrInsertFunction which creates one when absent. Intrinsics.h
+// implements getDeclaration which creates one when missing. This should be
+// changed to be consistent with Module()'s naming. Implementing as a local
+// function here in the meantime to decouple from that process.
+Function *getPreexistingDeclaration(Module *M, Intrinsic::ID id,
+ArrayRef Tys = std::nullopt) {
+  auto *FT = Intrinsic::getType(M->getContext(), id, Tys);
+  return M->getFunction(Tys.empty() ? Intrinsic::getName(id)
+: Intrinsic::getName(id, Tys, M, FT));
+}
+
+// Lots of targets use a void* pointed at a buffer for va_list.
+// Some use more complicated iterator constructs. Type erase that
+// so the rest of the pass can operation on either.
+// Virtual functions where different targets want different behaviour,
+// normal where all implemented targets presently have the same.
+struct VAListInterface {
+  virtual ~VAListInterface() {}
+
+  // Whether a valist instance is passed by value or by address
+  // I.e. does it need to be alloca'ed and stored into, or can
+  // it be passed directly in a SSA register
+  virtual bool passedInSSARegister() = 0;
+
+  // The type of a va_list iterator object
+  virtual Type *vaListType(LLVMContext &Ctx) = 0;
+
+  // The type of a va_list as a function argument as lowered by C
+  vir

[clang] [llvm] [WIP] Expand variadic functions in IR (PR #89007)

2024-04-17 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,1056 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a varidic function into a va_list
+// and fix up the call sites. This is completely effective if the calling
+// convention can declare that to be the right thing, e.g. on GPUs or where
+// the application is wholly statically linked. In the usual case, it will
+// replace known calls to known variadic functions with calls that are amenable
+// to inlining and other optimisations.
+//
+// The target-dependent parts are in class VariadicABIInfo. Enabling a new
+// target means adding a case to VariadicABIInfo::create() along with tests.
+// This will be especially simple if the va_list representation is a char*.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. The target specific
+// part is packing arguments into a contiguous buffer that the clang expansion
+// of va_arg will do the right thing with.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+
+#include 
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::lowering, "lowering",
+  "Change variadic calling convention")));
+
+namespace {
+
+// Module implements getFunction() which returns nullptr on missing declaration
+// and getOrInsertFunction which creates one when absent. Intrinsics.h
+// implements getDeclaration which creates one when missing. This should be
+// changed to be consistent with Module()'s naming. Implementing as a local
+// function here in the meantime to decouple from that process.
+Function *getPreexistingDeclaration(Module *M, Intrinsic::ID id,
+ArrayRef Tys = std::nullopt) {
+  auto *FT = Intrinsic::getType(M->getContext(), id, Tys);
+  return M->getFunction(Tys.empty() ? Intrinsic::getName(id)
+: Intrinsic::getName(id, Tys, M, FT));
+}
+
+// Lots of targets use a void* pointed at a buffer for va_list.
+// Some use more complicated iterator constructs. Type erase that
+// so the rest of the pass can operation on either.
+// Virtual functions where different targets want different behaviour,
+// normal where all implemented targets presently have the same.
+struct VAListInterface {
+  virtual ~VAListInterface() {}
+
+  // Whether a valist instance is passed by value or by address
+  // I.e. does it need to be alloca'ed and stored into, or can
+  // it be passed directly in a SSA register
+  virtual bool passedInSSARegister() = 0;
+
+  // The type of a va_list iterator object
+  virtual Type *vaListType(LLVMContext &Ctx) = 0;
+
+  // The type of a va_list as a function argument as lowered by C
+  vir

[clang] [llvm] [WIP] Expand variadic functions in IR (PR #89007)

2024-04-17 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,1056 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a varidic function into a va_list
+// and fix up the call sites. This is completely effective if the calling
+// convention can declare that to be the right thing, e.g. on GPUs or where
+// the application is wholly statically linked. In the usual case, it will
+// replace known calls to known variadic functions with calls that are amenable
+// to inlining and other optimisations.
+//
+// The target-dependent parts are in class VariadicABIInfo. Enabling a new
+// target means adding a case to VariadicABIInfo::create() along with tests.
+// This will be especially simple if the va_list representation is a char*.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. The target specific
+// part is packing arguments into a contiguous buffer that the clang expansion
+// of va_arg will do the right thing with.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+
+#include 
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::lowering, "lowering",
+  "Change variadic calling convention")));
+
+namespace {
+
+// Module implements getFunction() which returns nullptr on missing declaration
+// and getOrInsertFunction which creates one when absent. Intrinsics.h
+// implements getDeclaration which creates one when missing. This should be
+// changed to be consistent with Module()'s naming. Implementing as a local
+// function here in the meantime to decouple from that process.
+Function *getPreexistingDeclaration(Module *M, Intrinsic::ID id,
+ArrayRef Tys = std::nullopt) {
+  auto *FT = Intrinsic::getType(M->getContext(), id, Tys);
+  return M->getFunction(Tys.empty() ? Intrinsic::getName(id)
+: Intrinsic::getName(id, Tys, M, FT));
+}
+
+// Lots of targets use a void* pointed at a buffer for va_list.
+// Some use more complicated iterator constructs. Type erase that
+// so the rest of the pass can operation on either.
+// Virtual functions where different targets want different behaviour,
+// normal where all implemented targets presently have the same.
+struct VAListInterface {
+  virtual ~VAListInterface() {}
+
+  // Whether a valist instance is passed by value or by address
+  // I.e. does it need to be alloca'ed and stored into, or can
+  // it be passed directly in a SSA register
+  virtual bool passedInSSARegister() = 0;
+
+  // The type of a va_list iterator object
+  virtual Type *vaListType(LLVMContext &Ctx) = 0;
+
+  // The type of a va_list as a function argument as lowered by C
+  vir

[clang-tools-extra] [clang-tidy] Ignore deleted ctor in `bugprone-forwarding-reference-overload` (PR #88138)

2024-04-17 Thread Congcong Cai via cfe-commits

HerrCai0907 wrote:

please fix format issue.`git-clang-format` is helpful.

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


[clang-tools-extra] 792d437 - [clang-tidy NFC] Fix a typo in docs for sizeof-expression (#88912)

2024-04-17 Thread via cfe-commits

Author: NagyDonat
Date: 2024-04-17T12:52:23+02:00
New Revision: 792d437b56adfb3416daf8105942d4899fb82763

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

LOG: [clang-tidy NFC] Fix a typo in docs for sizeof-expression (#88912)

"Till heaven and earth pass, one jot, or one tittle shall not pass of
the law"

Added: 


Modified: 
clang-tools-extra/docs/clang-tidy/checks/bugprone/sizeof-expression.rst

Removed: 




diff  --git 
a/clang-tools-extra/docs/clang-tidy/checks/bugprone/sizeof-expression.rst 
b/clang-tools-extra/docs/clang-tidy/checks/bugprone/sizeof-expression.rst
index a3e88b837d3758..c37df1706eb4e1 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/sizeof-expression.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/sizeof-expression.rst
@@ -190,6 +190,6 @@ Options
 
 .. option:: WarnOnSizeOfPointerToAggregate
 
-   When `true, the check will warn on an expression like
+   When `true`, the check will warn on an expression like
``sizeof(expr)`` where the expression is a pointer
to aggregate. Default is `true`.



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


[clang-tools-extra] [clang-tidy NFC] Fix a typo in docs for sizeof-expression (PR #88912)

2024-04-17 Thread via cfe-commits

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


[clang] [llvm] [WIP] Expand variadic functions in IR (PR #89007)

2024-04-17 Thread Jon Chesterfield via cfe-commits


@@ -115,7 +115,13 @@ void AMDGPUABIInfo::computeInfo(CGFunctionInfo &FI) const {
 
 Address AMDGPUABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
  QualType Ty) const {
-  llvm_unreachable("AMDGPU does not support varargs");
+  const bool IsIndirect = false;
+  const bool AllowHigherAlign = true;
+  // Would rather not naturally align values
+  // Splitting {char, short} into two separate arguments makes that difficult.

JonChesterfield wrote:

Currently amdgpu takes a `struct {char x; short y;} example;` and splats it 
across two registers. Doesn't seem totally good to me but I'm trying to avoid 
changing the non-variadic calling convention at the same time.

This means foo(example) and bar (char, short) look the same in IR, thus they 
need to have consistent representations as far as va_arg is concerned. The 
specific case that caused me trouble here was trying to pass a double with four 
byte alignment as opposed to eight (that's what the the naturally align values 
comment relates to).

I'll see if I can capture this in an amdgpu specific test case and fix up the 
comment



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


[clang] [clang][NFC] Fix FieldDecl::isUnnamedBitfield() capitalization (PR #89048)

2024-04-17 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/89048

We always capitalize bitfield as "BitField".

>From 071305b588337841fbd2dbb929487c105a289d4b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Wed, 17 Apr 2024 12:53:49 +0200
Subject: [PATCH] [clang][NFC] Fix FieldDecl::isUnnamedBitfield()
 capitalization

We always capitalize bitfield as "BitField".
---
 clang/include/clang/AST/Decl.h|  2 +-
 clang/lib/AST/APValue.cpp |  3 ++-
 clang/lib/AST/ASTContext.cpp  |  2 +-
 clang/lib/AST/Decl.cpp|  2 +-
 clang/lib/AST/DeclCXX.cpp |  7 +++---
 clang/lib/AST/Expr.cpp|  4 ++--
 clang/lib/AST/ExprConstant.cpp| 18 +++---
 clang/lib/AST/Interp/EvaluationResult.cpp |  2 +-
 clang/lib/AST/ItaniumMangle.cpp   |  8 +++
 clang/lib/AST/MicrosoftMangle.cpp |  2 +-
 .../FlowSensitive/DataflowEnvironment.cpp |  2 +-
 clang/lib/Analysis/UninitializedValues.cpp|  2 +-
 clang/lib/CodeGen/ABIInfoImpl.cpp |  2 +-
 clang/lib/CodeGen/CGCall.cpp  |  2 +-
 clang/lib/CodeGen/CGExprAgg.cpp   |  8 ---
 clang/lib/CodeGen/CGExprCXX.cpp   |  2 +-
 clang/lib/CodeGen/CGExprConstant.cpp  |  4 ++--
 clang/lib/CodeGen/CodeGenTBAA.cpp |  2 +-
 clang/lib/CodeGen/Targets/X86.cpp |  4 ++--
 clang/lib/Sema/SemaChecking.cpp   |  2 +-
 clang/lib/Sema/SemaDecl.cpp   |  2 +-
 clang/lib/Sema/SemaDeclCXX.cpp| 24 +--
 clang/lib/Sema/SemaInit.cpp   | 24 +--
 .../Checkers/ObjCUnusedIVarsChecker.cpp   |  3 +--
 clang/lib/StaticAnalyzer/Core/RegionStore.cpp |  4 ++--
 25 files changed, 70 insertions(+), 67 deletions(-)

diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 01af50ca694fdd..fe8fe5574a5ea0 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -3149,7 +3149,7 @@ class FieldDecl : public DeclaratorDecl, public 
Mergeable {
   bool isBitField() const { return BitField; }
 
   /// Determines whether this is an unnamed bitfield.
-  bool isUnnamedBitfield() const { return isBitField() && !getDeclName(); }
+  bool isUnnamedBitField() const { return isBitField() && !getDeclName(); }
 
   /// Determines whether this field is a
   /// representative for an anonymous struct or union. Such fields are
diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp
index d8042321319a67..8c77b563657d90 100644
--- a/clang/lib/AST/APValue.cpp
+++ b/clang/lib/AST/APValue.cpp
@@ -908,7 +908,8 @@ void APValue::printPretty(raw_ostream &Out, const 
PrintingPolicy &Policy,
 for (const auto *FI : RD->fields()) {
   if (!First)
 Out << ", ";
-  if (FI->isUnnamedBitfield()) continue;
+  if (FI->isUnnamedBitField())
+continue;
   getStructField(FI->getFieldIndex()).
 printPretty(Out, Policy, FI->getType(), Ctx);
   First = false;
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 6ce233704a5885..68a86de2f46466 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -2684,7 +2684,7 @@ getSubobjectSizeInBits(const FieldDecl *Field, const 
ASTContext &Context,
   if (Field->isBitField()) {
 // If we have explicit padding bits, they don't contribute bits
 // to the actual object representation, so return 0.
-if (Field->isUnnamedBitfield())
+if (Field->isUnnamedBitField())
   return 0;
 
 int64_t BitfieldSize = Field->getBitWidthValue(Context);
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 33b6f8611f2162..169a6333c14f6e 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -4597,7 +4597,7 @@ unsigned FieldDecl::getBitWidthValue(const ASTContext 
&Ctx) const {
 }
 
 bool FieldDecl::isZeroLengthBitField(const ASTContext &Ctx) const {
-  return isUnnamedBitfield() && !getBitWidth()->isValueDependent() &&
+  return isUnnamedBitField() && !getBitWidth()->isValueDependent() &&
  getBitWidthValue(Ctx) == 0;
 }
 
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 645ec2f7563bca..00cc857f5e7379 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -668,7 +668,7 @@ bool CXXRecordDecl::hasSubobjectAtOffsetZeroOfEmptyBaseType(
 for (auto *FD : X->fields()) {
   // FIXME: Should we really care about the type of the first non-static
   // data member of a non-union if there are preceding unnamed bit-fields?
-  if (FD->isUnnamedBitfield())
+  if (FD->isUnnamedBitField())
 continue;
 
   if (!IsFirstField && !FD->isZeroSize(Ctx))
@@ -947,7 +947,7 @@ void CXXRecordDecl::addedMember(Decl *D) {
 //   A declaration for a bit-field that omits the identifier declares an
 //   unnamed

[clang] [clang][NFC] Fix FieldDecl::isUnnamedBitfield() capitalization (PR #89048)

2024-04-17 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)


Changes

We always capitalize bitfield as "BitField".

---

Patch is 31.15 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/89048.diff


25 Files Affected:

- (modified) clang/include/clang/AST/Decl.h (+1-1) 
- (modified) clang/lib/AST/APValue.cpp (+2-1) 
- (modified) clang/lib/AST/ASTContext.cpp (+1-1) 
- (modified) clang/lib/AST/Decl.cpp (+1-1) 
- (modified) clang/lib/AST/DeclCXX.cpp (+4-3) 
- (modified) clang/lib/AST/Expr.cpp (+2-2) 
- (modified) clang/lib/AST/ExprConstant.cpp (+9-9) 
- (modified) clang/lib/AST/Interp/EvaluationResult.cpp (+1-1) 
- (modified) clang/lib/AST/ItaniumMangle.cpp (+4-4) 
- (modified) clang/lib/AST/MicrosoftMangle.cpp (+1-1) 
- (modified) clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp (+1-1) 
- (modified) clang/lib/Analysis/UninitializedValues.cpp (+1-1) 
- (modified) clang/lib/CodeGen/ABIInfoImpl.cpp (+1-1) 
- (modified) clang/lib/CodeGen/CGCall.cpp (+1-1) 
- (modified) clang/lib/CodeGen/CGExprAgg.cpp (+5-3) 
- (modified) clang/lib/CodeGen/CGExprCXX.cpp (+1-1) 
- (modified) clang/lib/CodeGen/CGExprConstant.cpp (+2-2) 
- (modified) clang/lib/CodeGen/CodeGenTBAA.cpp (+1-1) 
- (modified) clang/lib/CodeGen/Targets/X86.cpp (+2-2) 
- (modified) clang/lib/Sema/SemaChecking.cpp (+1-1) 
- (modified) clang/lib/Sema/SemaDecl.cpp (+1-1) 
- (modified) clang/lib/Sema/SemaDeclCXX.cpp (+12-12) 
- (modified) clang/lib/Sema/SemaInit.cpp (+12-12) 
- (modified) clang/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp 
(+1-2) 
- (modified) clang/lib/StaticAnalyzer/Core/RegionStore.cpp (+2-2) 


``diff
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 01af50ca694fdd..fe8fe5574a5ea0 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -3149,7 +3149,7 @@ class FieldDecl : public DeclaratorDecl, public 
Mergeable {
   bool isBitField() const { return BitField; }
 
   /// Determines whether this is an unnamed bitfield.
-  bool isUnnamedBitfield() const { return isBitField() && !getDeclName(); }
+  bool isUnnamedBitField() const { return isBitField() && !getDeclName(); }
 
   /// Determines whether this field is a
   /// representative for an anonymous struct or union. Such fields are
diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp
index d8042321319a67..8c77b563657d90 100644
--- a/clang/lib/AST/APValue.cpp
+++ b/clang/lib/AST/APValue.cpp
@@ -908,7 +908,8 @@ void APValue::printPretty(raw_ostream &Out, const 
PrintingPolicy &Policy,
 for (const auto *FI : RD->fields()) {
   if (!First)
 Out << ", ";
-  if (FI->isUnnamedBitfield()) continue;
+  if (FI->isUnnamedBitField())
+continue;
   getStructField(FI->getFieldIndex()).
 printPretty(Out, Policy, FI->getType(), Ctx);
   First = false;
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 6ce233704a5885..68a86de2f46466 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -2684,7 +2684,7 @@ getSubobjectSizeInBits(const FieldDecl *Field, const 
ASTContext &Context,
   if (Field->isBitField()) {
 // If we have explicit padding bits, they don't contribute bits
 // to the actual object representation, so return 0.
-if (Field->isUnnamedBitfield())
+if (Field->isUnnamedBitField())
   return 0;
 
 int64_t BitfieldSize = Field->getBitWidthValue(Context);
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 33b6f8611f2162..169a6333c14f6e 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -4597,7 +4597,7 @@ unsigned FieldDecl::getBitWidthValue(const ASTContext 
&Ctx) const {
 }
 
 bool FieldDecl::isZeroLengthBitField(const ASTContext &Ctx) const {
-  return isUnnamedBitfield() && !getBitWidth()->isValueDependent() &&
+  return isUnnamedBitField() && !getBitWidth()->isValueDependent() &&
  getBitWidthValue(Ctx) == 0;
 }
 
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 645ec2f7563bca..00cc857f5e7379 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -668,7 +668,7 @@ bool CXXRecordDecl::hasSubobjectAtOffsetZeroOfEmptyBaseType(
 for (auto *FD : X->fields()) {
   // FIXME: Should we really care about the type of the first non-static
   // data member of a non-union if there are preceding unnamed bit-fields?
-  if (FD->isUnnamedBitfield())
+  if (FD->isUnnamedBitField())
 continue;
 
   if (!IsFirstField && !FD->isZeroSize(Ctx))
@@ -947,7 +947,7 @@ void CXXRecordDecl::addedMember(Decl *D) {
 //   A declaration for a bit-field that omits the identifier declares an
 //   unnamed bit-field. Unnamed bit-fields are not members and cannot be
 //   initialized.
-if (Field->isUnnamedBitfield()) {
+if (Field->isUnnamedBitField()) {
   // C++ [meta.unary.prop]p4: [LWG2358]
   //   T is a c

[clang] [llvm] [WIP] Expand variadic functions in IR (PR #89007)

2024-04-17 Thread Matt Arsenault via cfe-commits


@@ -115,7 +115,13 @@ void AMDGPUABIInfo::computeInfo(CGFunctionInfo &FI) const {
 
 Address AMDGPUABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
  QualType Ty) const {
-  llvm_unreachable("AMDGPU does not support varargs");
+  const bool IsIndirect = false;
+  const bool AllowHigherAlign = true;
+  // Would rather not naturally align values
+  // Splitting {char, short} into two separate arguments makes that difficult.

arsenm wrote:

I thought all structs under 8 bytes were packed into i32/i64

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


[clang] [llvm] [WIP] Expand variadic functions in IR (PR #89007)

2024-04-17 Thread Jon Chesterfield via cfe-commits


@@ -0,0 +1,1056 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a varidic function into a va_list
+// and fix up the call sites. This is completely effective if the calling
+// convention can declare that to be the right thing, e.g. on GPUs or where
+// the application is wholly statically linked. In the usual case, it will
+// replace known calls to known variadic functions with calls that are amenable
+// to inlining and other optimisations.
+//
+// The target-dependent parts are in class VariadicABIInfo. Enabling a new
+// target means adding a case to VariadicABIInfo::create() along with tests.
+// This will be especially simple if the va_list representation is a char*.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. The target specific
+// part is packing arguments into a contiguous buffer that the clang expansion
+// of va_arg will do the right thing with.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+
+#include 
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::lowering, "lowering",
+  "Change variadic calling convention")));
+
+namespace {
+
+// Module implements getFunction() which returns nullptr on missing declaration
+// and getOrInsertFunction which creates one when absent. Intrinsics.h
+// implements getDeclaration which creates one when missing. This should be
+// changed to be consistent with Module()'s naming. Implementing as a local
+// function here in the meantime to decouple from that process.
+Function *getPreexistingDeclaration(Module *M, Intrinsic::ID id,
+ArrayRef Tys = std::nullopt) {
+  auto *FT = Intrinsic::getType(M->getContext(), id, Tys);
+  return M->getFunction(Tys.empty() ? Intrinsic::getName(id)
+: Intrinsic::getName(id, Tys, M, FT));
+}
+
+// Lots of targets use a void* pointed at a buffer for va_list.
+// Some use more complicated iterator constructs. Type erase that
+// so the rest of the pass can operation on either.
+// Virtual functions where different targets want different behaviour,
+// normal where all implemented targets presently have the same.
+struct VAListInterface {
+  virtual ~VAListInterface() {}
+
+  // Whether a valist instance is passed by value or by address
+  // I.e. does it need to be alloca'ed and stored into, or can
+  // it be passed directly in a SSA register
+  virtual bool passedInSSARegister() = 0;
+
+  // The type of a va_list iterator object
+  virtual Type *vaListType(LLVMContext &Ctx) = 0;
+
+  // The type of a va_list as a function argument as lowered by C
+  vir

[clang] [llvm] [WIP] Expand variadic functions in IR (PR #89007)

2024-04-17 Thread Jon Chesterfield via cfe-commits


@@ -115,7 +115,13 @@ void AMDGPUABIInfo::computeInfo(CGFunctionInfo &FI) const {
 
 Address AMDGPUABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
  QualType Ty) const {
-  llvm_unreachable("AMDGPU does not support varargs");
+  const bool IsIndirect = false;
+  const bool AllowHigherAlign = true;
+  // Would rather not naturally align values
+  // Splitting {char, short} into two separate arguments makes that difficult.

JonChesterfield wrote:

Nope. At least, not what I got under testing. That sounds like a good idea 
though.

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


[clang] [llvm] [WIP] Expand variadic functions in IR (PR #89007)

2024-04-17 Thread Jon Chesterfield via cfe-commits


@@ -0,0 +1,1056 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a varidic function into a va_list
+// and fix up the call sites. This is completely effective if the calling
+// convention can declare that to be the right thing, e.g. on GPUs or where
+// the application is wholly statically linked. In the usual case, it will
+// replace known calls to known variadic functions with calls that are amenable
+// to inlining and other optimisations.
+//
+// The target-dependent parts are in class VariadicABIInfo. Enabling a new
+// target means adding a case to VariadicABIInfo::create() along with tests.
+// This will be especially simple if the va_list representation is a char*.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. The target specific
+// part is packing arguments into a contiguous buffer that the clang expansion
+// of va_arg will do the right thing with.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+
+#include 
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::lowering, "lowering",
+  "Change variadic calling convention")));
+
+namespace {
+
+// Module implements getFunction() which returns nullptr on missing declaration
+// and getOrInsertFunction which creates one when absent. Intrinsics.h
+// implements getDeclaration which creates one when missing. This should be
+// changed to be consistent with Module()'s naming. Implementing as a local
+// function here in the meantime to decouple from that process.
+Function *getPreexistingDeclaration(Module *M, Intrinsic::ID id,
+ArrayRef Tys = std::nullopt) {
+  auto *FT = Intrinsic::getType(M->getContext(), id, Tys);
+  return M->getFunction(Tys.empty() ? Intrinsic::getName(id)
+: Intrinsic::getName(id, Tys, M, FT));
+}
+
+// Lots of targets use a void* pointed at a buffer for va_list.
+// Some use more complicated iterator constructs. Type erase that
+// so the rest of the pass can operation on either.
+// Virtual functions where different targets want different behaviour,
+// normal where all implemented targets presently have the same.
+struct VAListInterface {
+  virtual ~VAListInterface() {}
+
+  // Whether a valist instance is passed by value or by address
+  // I.e. does it need to be alloca'ed and stored into, or can
+  // it be passed directly in a SSA register
+  virtual bool passedInSSARegister() = 0;
+
+  // The type of a va_list iterator object
+  virtual Type *vaListType(LLVMContext &Ctx) = 0;
+
+  // The type of a va_list as a function argument as lowered by C
+  vir

[clang] [llvm] [WIP] Expand variadic functions in IR (PR #89007)

2024-04-17 Thread Jon Chesterfield via cfe-commits


@@ -0,0 +1,1056 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a varidic function into a va_list
+// and fix up the call sites. This is completely effective if the calling
+// convention can declare that to be the right thing, e.g. on GPUs or where
+// the application is wholly statically linked. In the usual case, it will
+// replace known calls to known variadic functions with calls that are amenable
+// to inlining and other optimisations.
+//
+// The target-dependent parts are in class VariadicABIInfo. Enabling a new
+// target means adding a case to VariadicABIInfo::create() along with tests.
+// This will be especially simple if the va_list representation is a char*.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. The target specific
+// part is packing arguments into a contiguous buffer that the clang expansion
+// of va_arg will do the right thing with.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+
+#include 
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::lowering, "lowering",
+  "Change variadic calling convention")));
+
+namespace {
+
+// Module implements getFunction() which returns nullptr on missing declaration
+// and getOrInsertFunction which creates one when absent. Intrinsics.h
+// implements getDeclaration which creates one when missing. This should be
+// changed to be consistent with Module()'s naming. Implementing as a local
+// function here in the meantime to decouple from that process.
+Function *getPreexistingDeclaration(Module *M, Intrinsic::ID id,
+ArrayRef Tys = std::nullopt) {

JonChesterfield wrote:

Written to be consistent with Module::getFunction which uses nullopt. Need to 
open an issue about this, can't change getDeclaration to return null on missing 
without causing a lot of breakage. I think the right thing is to rename 
getDeclaration to getOrCreateDeclaration, introduce another function called 
getPreexistingDeclaration, wait for at least some of the downstream projects to 
do the rename, then rename getPreexistingDeclaration into getDeclaration and 
thus be consistent with Module...

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


[clang] [llvm] [WIP] Expand variadic functions in IR (PR #89007)

2024-04-17 Thread Jon Chesterfield via cfe-commits

JonChesterfield wrote:

Drive by fixes to some of Matt's comments. Caught a missing line in a .def file 
for NVPTX through luck due to the enum rename which means the 
Other/new-pm-thinlto-postlink-samplepgo-defaults.ll style tests need to be 
patched again - leaving that for now as I want to check whether the passes run 
in the order of the PassRegistry.def (in which case expand-variadics should 
probably happen before always-inline) and the failing test is a reminder to 
myself of that

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


[clang] [llvm] [WIP] Expand variadic functions in IR (PR #89007)

2024-04-17 Thread Jon Chesterfield via cfe-commits


@@ -0,0 +1,1056 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a varidic function into a va_list
+// and fix up the call sites. This is completely effective if the calling
+// convention can declare that to be the right thing, e.g. on GPUs or where
+// the application is wholly statically linked. In the usual case, it will
+// replace known calls to known variadic functions with calls that are amenable
+// to inlining and other optimisations.
+//
+// The target-dependent parts are in class VariadicABIInfo. Enabling a new
+// target means adding a case to VariadicABIInfo::create() along with tests.
+// This will be especially simple if the va_list representation is a char*.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. The target specific
+// part is packing arguments into a contiguous buffer that the clang expansion
+// of va_arg will do the right thing with.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+
+#include 
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::lowering, "lowering",
+  "Change variadic calling convention")));
+
+namespace {
+
+// Module implements getFunction() which returns nullptr on missing declaration
+// and getOrInsertFunction which creates one when absent. Intrinsics.h
+// implements getDeclaration which creates one when missing. This should be
+// changed to be consistent with Module()'s naming. Implementing as a local
+// function here in the meantime to decouple from that process.
+Function *getPreexistingDeclaration(Module *M, Intrinsic::ID id,
+ArrayRef Tys = std::nullopt) {
+  auto *FT = Intrinsic::getType(M->getContext(), id, Tys);
+  return M->getFunction(Tys.empty() ? Intrinsic::getName(id)
+: Intrinsic::getName(id, Tys, M, FT));
+}
+
+// Lots of targets use a void* pointed at a buffer for va_list.
+// Some use more complicated iterator constructs. Type erase that
+// so the rest of the pass can operation on either.
+// Virtual functions where different targets want different behaviour,
+// normal where all implemented targets presently have the same.
+struct VAListInterface {
+  virtual ~VAListInterface() {}
+
+  // Whether a valist instance is passed by value or by address
+  // I.e. does it need to be alloca'ed and stored into, or can
+  // it be passed directly in a SSA register
+  virtual bool passedInSSARegister() = 0;
+
+  // The type of a va_list iterator object
+  virtual Type *vaListType(LLVMContext &Ctx) = 0;
+
+  // The type of a va_list as a function argument as lowered by C
+  vir

[clang] [clang][NFC] Fix FieldDecl::isUnnamedBitfield() capitalization (PR #89048)

2024-04-17 Thread via cfe-commits

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

LGTM

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


[libclc] [libclc] Add initial LIT tests (PR #87989)

2024-04-17 Thread Fraser Cormack via cfe-commits


@@ -1,3 +1,6 @@
-__kernel void foo(int *i) {
+// RUN: %clang -emit-llvm -S -o - %s | FileCheck %s

frasercrmck wrote:

Yes, I was hoping to explore in that direction. I've kind of just copied the 
skeleton of the LIT tests we have downstream, but as you say, this isn't really 
workable as it assumes all tests will be able to use the same CHECK.

I think, for this to work, we'd have to configure LIT with all of the `libclc` 
targets (or, a subset we're interested in), then `RUN` each test multiple times 
with a unique `FileCheck` check prefix for each target. Then when running 
`update_cc_test_checks` it'd run the test on all targets.

I think we'd need a macro or substitution to expand a single `RUN` line to 
multiple architectures, to keep things maintainable.

We could also allow running the tests on just the one or a subset of 
architectures locally, using a `--param` to control the architectures to test.

Does that sound like a good direction? to take this in?

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


[clang] Reapply "[Clang][Sema] placement new initializes typedef array with correct size (#83124)" (PR #89036)

2024-04-17 Thread via cfe-commits

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


[clang] [analyzer] Use explicit call description mode in iterator checkers (PR #88913)

2024-04-17 Thread via cfe-commits

NagyDonat wrote:

Uh oh, those niebloids are really deep black magic :skull_and_crossbones: I 
didn't know about them previously, so thanks for mentioning them.

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


[clang] [clang-tools-extra] [clang][NFC] Fix FieldDecl::isUnnamedBitfield() capitalization (PR #89048)

2024-04-17 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/89048

>From 5e4b24933180f012573785fa5747bf37efd26fad Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Wed, 17 Apr 2024 12:53:49 +0200
Subject: [PATCH] [clang][NFC] Fix FieldDecl::isUnnamedBitfield()
 capitalization

We always capitalize bitfield as "BitField".
---
 .../ProTypeMemberInitCheck.cpp|  2 +-
 .../modernize/UseEqualsDefaultCheck.cpp   |  2 +-
 .../utils/ExceptionSpecAnalyzer.cpp   |  2 +-
 clang/include/clang/AST/Decl.h|  2 +-
 clang/lib/AST/APValue.cpp |  3 ++-
 clang/lib/AST/ASTContext.cpp  |  2 +-
 clang/lib/AST/Decl.cpp|  2 +-
 clang/lib/AST/DeclCXX.cpp |  7 +++---
 clang/lib/AST/Expr.cpp|  4 ++--
 clang/lib/AST/ExprConstant.cpp| 18 +++---
 clang/lib/AST/Interp/EvaluationResult.cpp |  2 +-
 clang/lib/AST/ItaniumMangle.cpp   |  8 +++
 clang/lib/AST/MicrosoftMangle.cpp |  2 +-
 clang/lib/Analysis/FlowSensitive/ASTOps.cpp   |  2 +-
 clang/lib/Analysis/UninitializedValues.cpp|  2 +-
 clang/lib/CodeGen/ABIInfoImpl.cpp |  2 +-
 clang/lib/CodeGen/CGCall.cpp  |  2 +-
 clang/lib/CodeGen/CGExpr.cpp  |  2 +-
 clang/lib/CodeGen/CGExprAgg.cpp   |  8 ---
 clang/lib/CodeGen/CGExprCXX.cpp   |  2 +-
 clang/lib/CodeGen/CGExprConstant.cpp  |  4 ++--
 clang/lib/CodeGen/CodeGenTBAA.cpp |  2 +-
 clang/lib/CodeGen/Targets/X86.cpp |  4 ++--
 clang/lib/Sema/SemaChecking.cpp   |  2 +-
 clang/lib/Sema/SemaDecl.cpp   |  2 +-
 clang/lib/Sema/SemaDeclCXX.cpp| 24 +--
 clang/lib/Sema/SemaInit.cpp   | 24 +--
 .../Checkers/ObjCUnusedIVarsChecker.cpp   |  3 +--
 clang/lib/StaticAnalyzer/Core/RegionStore.cpp |  4 ++--
 29 files changed, 74 insertions(+), 71 deletions(-)

diff --git 
a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp 
b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp
index 855c4a2efc373e..9c3c7cc70c187b 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp
@@ -444,7 +444,7 @@ void ProTypeMemberInitCheck::checkMissingMemberInitializer(
 if (!F->hasInClassInitializer() &&
 utils::type_traits::isTriviallyDefaultConstructible(F->getType(),
 Context) &&
-!isEmpty(Context, F->getType()) && !F->isUnnamedBitfield() &&
+!isEmpty(Context, F->getType()) && !F->isUnnamedBitField() &&
 !AnyMemberHasInitPerUnion)
   FieldsToInit.insert(F);
   });
diff --git a/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
index 5134eb51a03226..93151024064b42 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
@@ -26,7 +26,7 @@ getAllNamedFields(const CXXRecordDecl *Record) {
   std::set Result;
   for (const auto *Field : Record->fields()) {
 // Static data members are not in this range.
-if (Field->isUnnamedBitfield())
+if (Field->isUnnamedBitField())
   continue;
 Result.insert(Field);
   }
diff --git a/clang-tools-extra/clang-tidy/utils/ExceptionSpecAnalyzer.cpp 
b/clang-tools-extra/clang-tidy/utils/ExceptionSpecAnalyzer.cpp
index 1dde0490517852..4a9426ee7e8bbb 100644
--- a/clang-tools-extra/clang-tidy/utils/ExceptionSpecAnalyzer.cpp
+++ b/clang-tools-extra/clang-tidy/utils/ExceptionSpecAnalyzer.cpp
@@ -99,7 +99,7 @@ ExceptionSpecAnalyzer::analyzeRecord(const CXXRecordDecl 
*RecordDecl,
   }
 
   for (const auto *FDecl : RecordDecl->fields())
-if (!FDecl->isInvalidDecl() && !FDecl->isUnnamedBitfield()) {
+if (!FDecl->isInvalidDecl() && !FDecl->isUnnamedBitField()) {
   State Result = analyzeFieldDecl(FDecl, Kind);
   if (Result == State::Throwing || Result == State::Unknown)
 return Result;
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 01af50ca694fdd..fe8fe5574a5ea0 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -3149,7 +3149,7 @@ class FieldDecl : public DeclaratorDecl, public 
Mergeable {
   bool isBitField() const { return BitField; }
 
   /// Determines whether this is an unnamed bitfield.
-  bool isUnnamedBitfield() const { return isBitField() && !getDeclName(); }
+  bool isUnnamedBitField() const { return isBitField() && !getDeclName(); }
 
   /// Determines whether this field is a
   /// representative for an anonymous struct or union. Such fields are
diff --git a/clang/lib/AST/AP

[clang] 06eedff - [analyzer] Use explicit call description mode in iterator checkers (#88913)

2024-04-17 Thread via cfe-commits

Author: NagyDonat
Date: 2024-04-17T13:26:51+02:00
New Revision: 06eedffe0d2782922e63cc25cb927f4acdaf7b30

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

LOG: [analyzer] Use explicit call description mode in iterator checkers (#88913)

This commit explicitly specifies the matching mode (C library function,
any non-method function, or C++ method) for the `CallDescription`s
constructed in the iterator/container checkers.

This change won't cause major functional changes, but isn't NFC because
it ensures that e.g. call descriptions for a non-method function won't
accidentally match a method that has the same name.

Separate commits will perform (or have already performed) this change in
other checkers. My goal is to ensure that the call description mode is
always explicitly specified and eliminate (or strongly restrict) the
vague "may be either a method or a simple function" mode that's the
current default.

I'm handling the iterator checkers in this separate commit because
they're infamously complex; but I don't expect any trouble because this
transition doesn't interact with the "central" logic of iterator
handling.

Added: 


Modified: 
clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp
clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp
clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp
clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
clang/lib/StaticAnalyzer/Checkers/IteratorRangeChecker.cpp
clang/lib/StaticAnalyzer/Checkers/STLAlgorithmModeling.cpp

Removed: 




diff  --git a/clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp 
b/clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp
index 009c0d3fb93686..55ed809bfed6ce 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp
@@ -72,26 +72,31 @@ class ContainerModeling
SVal) const;
 
   CallDescriptionMap NoIterParamFunctions = {
-  {{{"clear"}, 0}, &ContainerModeling::handleClear},
-  {{{"assign"}, 2}, &ContainerModeling::handleAssign},
-  {{{"push_back"}, 1}, &ContainerModeling::handlePushBack},
-  {{{"emplace_back"}, 1}, &ContainerModeling::handlePushBack},
-  {{{"pop_back"}, 0}, &ContainerModeling::handlePopBack},
-  {{{"push_front"}, 1}, &ContainerModeling::handlePushFront},
-  {{{"emplace_front"}, 1}, &ContainerModeling::handlePushFront},
-  {{{"pop_front"}, 0}, &ContainerModeling::handlePopFront},
+  {{CDM::CXXMethod, {"clear"}, 0}, &ContainerModeling::handleClear},
+  {{CDM::CXXMethod, {"assign"}, 2}, &ContainerModeling::handleAssign},
+  {{CDM::CXXMethod, {"push_back"}, 1}, &ContainerModeling::handlePushBack},
+  {{CDM::CXXMethod, {"emplace_back"}, 1},
+   &ContainerModeling::handlePushBack},
+  {{CDM::CXXMethod, {"pop_back"}, 0}, &ContainerModeling::handlePopBack},
+  {{CDM::CXXMethod, {"push_front"}, 1},
+   &ContainerModeling::handlePushFront},
+  {{CDM::CXXMethod, {"emplace_front"}, 1},
+   &ContainerModeling::handlePushFront},
+  {{CDM::CXXMethod, {"pop_front"}, 0}, &ContainerModeling::handlePopFront},
   };
 
   CallDescriptionMap OneIterParamFunctions = {
-  {{{"insert"}, 2}, &ContainerModeling::handleInsert},
-  {{{"emplace"}, 2}, &ContainerModeling::handleInsert},
-  {{{"erase"}, 1}, &ContainerModeling::handleErase},
-  {{{"erase_after"}, 1}, &ContainerModeling::handleEraseAfter},
+  {{CDM::CXXMethod, {"insert"}, 2}, &ContainerModeling::handleInsert},
+  {{CDM::CXXMethod, {"emplace"}, 2}, &ContainerModeling::handleInsert},
+  {{CDM::CXXMethod, {"erase"}, 1}, &ContainerModeling::handleErase},
+  {{CDM::CXXMethod, {"erase_after"}, 1},
+   &ContainerModeling::handleEraseAfter},
   };
 
   CallDescriptionMap TwoIterParamFunctions = {
-  {{{"erase"}, 2}, &ContainerModeling::handleErase},
-  {{{"erase_after"}, 2}, &ContainerModeling::handleEraseAfter},
+  {{CDM::CXXMethod, {"erase"}, 2}, &ContainerModeling::handleErase},
+  {{CDM::CXXMethod, {"erase_after"}, 2},
+   &ContainerModeling::handleEraseAfter},
   };
 };
 

diff  --git a/clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp 
b/clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp
index 72186a99d94358..d3830a01dd0cbd 100644
--- a/clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp
@@ -42,9 +42,9 @@ class DebugContainerModeling
  CheckerContext &) const;
 
   CallDescriptionMap Callbacks = {
-  {{{"clang_analyzer_container_begin"}, 1},
+  {{CDM::SimpleFunc, {"clang_analyzer_container_begin"}, 1},
   

[clang] [analyzer] Use explicit call description mode in iterator checkers (PR #88913)

2024-04-17 Thread via cfe-commits

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


[clang] [clang] fix half && bfloat16 convert node expr codegen (PR #89051)

2024-04-17 Thread via cfe-commits

https://github.com/JinjinLi868 created 
https://github.com/llvm/llvm-project/pull/89051

Data type conversion between fp16 and bf16 will generate fptrunc and fpextend 
nodes, but they are actually bitcast nodes.


>From 02c11a9db49dd34839feb8329cfb8dbe4bc45763 Mon Sep 17 00:00:00 2001
From: Jinjin Li 
Date: Wed, 17 Apr 2024 16:44:50 +0800
Subject: [PATCH] [clang] fix half && bfloat16 convert node expr codegen

Data type conversion between fp16 and bf16 will generate fptrunc and fpextend 
nodes, but they are actually bitcast nodes.
---
 clang/lib/CodeGen/CGExprScalar.cpp | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/clang/lib/CodeGen/CGExprScalar.cpp 
b/clang/lib/CodeGen/CGExprScalar.cpp
index 1f18e0d5ba409a..da5a410f040d1b 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -1431,9 +1431,12 @@ Value *ScalarExprEmitter::EmitScalarCast(Value *Src, 
QualType SrcType,
 return Builder.CreateFPToUI(Src, DstTy, "conv");
   }
 
-  if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
+  if ((DstElementTy->is16bitFPTy() && SrcElementTy->is16bitFPTy()))
+return Builder.CreateBitCast(Src, DstTy, "conv");
+  else if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
 return Builder.CreateFPTrunc(Src, DstTy, "conv");
-  return Builder.CreateFPExt(Src, DstTy, "conv");
+  else
+return Builder.CreateFPExt(Src, DstTy, "conv");
 }
 
 /// Emit a conversion from the specified type to the specified destination 
type,
@@ -1906,7 +1909,9 @@ Value 
*ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
   } else {
 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
"Unknown real conversion");
-if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
+if ((DstEltTy->is16bitFPTy() && SrcEltTy->is16bitFPTy()))
+  Res = Builder.CreateBitCast(Src, DstTy, "conv");
+else if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
   Res = Builder.CreateFPTrunc(Src, DstTy, "conv");
 else
   Res = Builder.CreateFPExt(Src, DstTy, "conv");

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


[clang] [clang][nullability] Remove `RecordValue`. (PR #89052)

2024-04-17 Thread via cfe-commits

https://github.com/martinboehme created 
https://github.com/llvm/llvm-project/pull/89052

This class no longer serves any purpose; see also the discussion here:
https://reviews.llvm.org/D155204#inline-1503204

A lot of existing tests in TransferTest.cpp check for the existence of
`RecordValue`s. Some of these checks are now simply redundant and have been
removed. In other cases, tests were checking for the existence of a
`RecordValue` as a way of testing whether a record has been initialized. I have
typically changed these test to instead check whether a field of the record has
a value.


>From f5df084fa15869cdea9a7134d5e2a43bcb64b1fb Mon Sep 17 00:00:00 2001
From: Martin Braenne 
Date: Wed, 17 Apr 2024 11:31:12 +
Subject: [PATCH] [clang][nullability] Remove `RecordValue`.

This class no longer serves any purpose; see also the discussion here:
https://reviews.llvm.org/D155204#inline-1503204

A lot of existing tests in TransferTest.cpp check for the existence of
`RecordValue`s. Some of these checks are now simply redundant and have been
removed. In other cases, tests were checking for the existence of a
`RecordValue` as a way of testing whether a record has been initialized. I have
typically changed these test to instead check whether a field of the record has
a value.
---
 .../FlowSensitive/DataflowEnvironment.h   |  38 +++---
 .../clang/Analysis/FlowSensitive/Value.h  |  41 --
 .../FlowSensitive/DataflowEnvironment.cpp |  98 --
 .../Analysis/FlowSensitive/DebugSupport.cpp   |   2 -
 .../lib/Analysis/FlowSensitive/HTMLLogger.cpp |  13 +-
 .../Models/UncheckedOptionalAccessModel.cpp   |  46 +++
 .../lib/Analysis/FlowSensitive/RecordOps.cpp  |   3 -
 clang/lib/Analysis/FlowSensitive/Transfer.cpp |  62 +++--
 .../TypeErasedDataflowAnalysis.cpp|   6 +-
 clang/lib/Analysis/FlowSensitive/Value.cpp|   2 -
 .../FlowSensitive/DataflowEnvironmentTest.cpp |  81 ---
 .../Analysis/FlowSensitive/RecordOpsTest.cpp  |   8 --
 .../Analysis/FlowSensitive/TransferTest.cpp   | 126 ++
 13 files changed, 130 insertions(+), 396 deletions(-)

diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index 706664d7db1c25..c20e8f34d48d08 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -84,7 +84,7 @@ class Environment {
 virtual ComparisonResult compare(QualType Type, const Value &Val1,
  const Environment &Env1, const Value 
&Val2,
  const Environment &Env2) {
-  // FIXME: Consider adding QualType to RecordValue and removing the Type
+  // FIXME: Consider adding `QualType` to `Value` and removing the `Type`
   // argument here.
   return ComparisonResult::Unknown;
 }
@@ -407,20 +407,15 @@ class Environment {
   /// storage locations and values for indirections until it finds a
   /// non-pointer/non-reference type.
   ///
-  /// If `Type` is a class, struct, or union type, creates values for all
-  /// modeled fields (including synthetic fields) and calls `setValue()` to
-  /// associate the `RecordValue` with its storage location
-  /// (`RecordValue::getLoc()`).
-  ///
   /// If `Type` is one of the following types, this function will always return
   /// a non-null pointer:
   /// - `bool`
   /// - Any integer type
-  /// - Any class, struct, or union type
   ///
   /// Requirements:
   ///
-  ///  `Type` must not be null.
+  ///  - `Type` must not be null.
+  ///  - `Type` must not be a reference type or record type.
   Value *createValue(QualType Type);
 
   /// Creates an object (i.e. a storage location with an associated value) of
@@ -452,6 +447,7 @@ class Environment {
   /// Initializes the fields (including synthetic fields) of `Loc` with values,
   /// unless values of the field type are not supported or we hit one of the
   /// limits at which we stop producing values.
+  /// If a field already has a value, that value is preserved.
   /// If `Type` is provided, initializes only those fields that are modeled for
   /// `Type`; this is intended for use in cases where `Loc` is a derived type
   /// and we only want to initialize the fields of a base type.
@@ -461,6 +457,10 @@ class Environment {
   }
 
   /// Assigns `Val` as the value of `Loc` in the environment.
+  ///
+  /// Requirements:
+  ///
+  ///  `Loc` must not be a `RecordStorageLocation`.
   void setValue(const StorageLocation &Loc, Value &Val);
 
   /// Clears any association between `Loc` and a value in the environment.
@@ -470,20 +470,24 @@ class Environment {
   ///
   /// Requirements:
   ///
-  ///  - `E` must be a prvalue
-  ///  - If `Val` is a `RecordValue`, its `RecordStorageLocation` must be
-  ///`getResultObjectLocation(E)`. An exception to this is if `E` is an
-  ///expression 

[clang] [clang] fix half && bfloat16 convert node expr codegen (PR #89051)

2024-04-17 Thread via cfe-commits

github-actions[bot] wrote:



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

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

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

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

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

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

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

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


  1   2   3   4   5   >