[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-04-14 Thread Utkarsh Saxena via cfe-commits

usx95 wrote:

[ayermolo](https://github.com/ayermolo) Thanks for the reproducer. I was able 
to reproduce it. Sent out fix https://github.com/llvm/llvm-project/pull/88670


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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-04-14 Thread Alexander Yermolovich via cfe-commits

ayermolo wrote:

@usx95 can you repro?
Also is there ETA on a fix, and if not can you revert this?

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-04-12 Thread Alexander Yermolovich via cfe-commits

ayermolo wrote:

I think this commit is causing build failure when building clangd in debug mode 
with clang built in release mode.

```
Instruction does not dominate all uses!
  %K1104 = getelementptr inbounds %"struct.llvm::json::Object::KV", ptr 
%arrayinit.begin1100, i32 0, i32 0, !dbg !93928
  call void @_ZN4llvm4json9ObjectKeyD2Ev(ptr noundef nonnull align 8 
dereferenceable(24) %K1104) #21, !dbg !93937
fatal error: error in backend: Broken module found, compilation aborted!
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and 
include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.  Program arguments: 
/home/ayermolo/local/llvm-build-upstream-release/bin/clang++ -D_DEBUG 
-D_GLIBCXX_ASSERTIONS -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS 
-D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Itools/clang/tools/extra/clangd 
-I/home/ayermolo/local/upstream-llvm/llvm-project/clang-tools-extra/clangd 
-I/home/ayermolo/local/upstream-llvm/llvm-project/clang-tools-extra/clangd/../include-cleaner/include
 -Itools/clang/tools/extra/clangd/../clang-tidy 
-I/home/ayermolo/local/upstream-llvm/llvm-project/clang/include 
-Itools/clang/include -Iinclude 
-I/home/ayermolo/local/upstream-llvm/llvm-project/llvm/include 
-I/home/ayermolo/local/upstream-llvm/llvm-project/clang-tools-extra/pseudo/lib/../include
 
-isystem/home/ayermolo/local/llvm-build-upstream-llvm/build/lib/clang/19/include
 -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden 
-Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra 
-Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers 
-pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough 
-Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor 
-Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion 
-Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color 
-fno-common -Woverloaded-virtual -Wno-nested-anon-types -g -std=c++17 -MD -MT 
/home/ayermolo/local/llvm-build-upstream-debug/tools/clang/tools/extra/clangd/CMakeFiles/obj.clangDaemon.dir/ClangdLSPServer.cpp.o
 -MF 
/home/ayermolo/local/llvm-build-upstream-debug/tools/clang/tools/extra/clangd/CMakeFiles/obj.clangDaemon.dir/ClangdLSPServer.cpp.o.d
 -o 
/home/ayermolo/local/llvm-build-upstream-debug/tools/clang/tools/extra/clangd/CMakeFiles/obj.clangDaemon.dir/ClangdLSPServer.cpp.o
 -c 
/home/ayermolo/local/upstream-llvm/llvm-project/clang-tools-extra/clangd/ClangdLSPServer.cpp
```

Dropping this commit and running above clang build command makes it pass.
build command for easier reading:
```
COMP=/home/ayermolo/local/llvm-build-upstream-release/bin
$COMP/clang++ -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GNU_SOURCE 
-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS \
  -Itools/clang/tools/extra/clangd \
  -I/home/ayermolo/local/upstream-llvm/llvm-project/clang-tools-extra/clangd \
  
-I/home/ayermolo/local/upstream-llvm/llvm-project/clang-tools-extra/clangd/../include-cleaner/include
 \
  -Itools/clang/tools/extra/clangd/../clang-tidy \
  -I/home/ayermolo/local/upstream-llvm/llvm-project/clang/include \
  -Itools/clang/include \
  -Iinclude \
  -I/home/ayermolo/local/upstream-llvm/llvm-project/llvm/include \
  
-I/home/ayermolo/local/upstream-llvm/llvm-project/clang-tools-extra/pseudo/lib/../include
 \
  
-isystem/home/ayermolo/local/llvm-build-upstream-llvm/build/lib/clang/19/include
 \
  -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden 
-Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra \
  -Wno-unused-parameter -Wwrite-strings -Wcast-qual 
-Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi 
\
  -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type 
-Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override \
  -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported 
-fdiagnostics-color -fno-common -Woverloaded-virtual \
  -Wno-nested-anon-types -g -std=c++17 -MD \
  -MT 
/home/ayermolo/local/llvm-build-upstream-debug/tools/clang/tools/extra/clangd/CMakeFiles/obj.clangDaemon.dir/ClangdLSPServer.cpp.o
 \
  -MF 
/home/ayermolo/local/llvm-build-upstream-debug/tools/clang/tools/extra/clangd/CMakeFiles/obj.clangDaemon.dir/ClangdLSPServer.cpp.o.d
 \
  -o  
/home/ayermolo/local/llvm-build-upstream-debug/tools/clang/tools/extra/clangd/CMakeFiles/obj.clangDaemon.dir/ClangdLSPServer.cpp.o
 \
  -c  
/home/ayermolo/local/upstream-llvm/llvm-project/clang-tools-extra/clangd/ClangdLSPServer.cpp
```

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-04-10 Thread Utkarsh Saxena via cfe-commits

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-04-09 Thread Eli Friedman via cfe-commits

https://github.com/efriedma-quic approved this pull request.

LGTM

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-04-01 Thread Utkarsh Saxena via cfe-commits

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-04-01 Thread Utkarsh Saxena via cfe-commits


@@ -1105,19 +1105,24 @@ void CodeGenFunction::EmitNewArrayInitializer(
 }
 
 // Enter a partial-destruction Cleanup if necessary.
-if (needsEHCleanup(DtorKind)) {
+if (DtorKind) {
+  AllocaTrackerRAII AllocaTracker(*this);

usx95 wrote:

Unfortunately, that is not the case. We do create more allocas in conditional 
branches in `pushFullExprCleanup`, for eg: create `cond-cleanup.save` allocas 
in `DominatingLLVMValue::save` 
([src](https://github.com/llvm/llvm-project/blob/e93b5f5a4776ffea12d03652559dfdf8d421184c/clang/lib/CodeGen/CodeGenFunction.h#L5184)).


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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-04-01 Thread Utkarsh Saxena via cfe-commits


@@ -266,6 +269,54 @@ class alignas(8) EHCleanupScope : public EHScope {
   };
   mutable struct ExtInfo *ExtInfo;
 
+  /// Erases auxillary allocas and their usages for an unused cleanup.
+  /// Cleanups should mark these allocas as 'used' if the cleanup is
+  /// emitted, otherwise these instructions would be erased.
+  struct AuxillaryAllocas {
+SmallVector AuxAllocas;
+bool used = false;
+
+// Records a potentially unused instruction to be erased later.
+void Add(llvm::AllocaInst *Alloca) { AuxAllocas.push_back(Alloca); }
+
+// Mark all recorded instructions as used. These will not be erased later.
+void MarkUsed() {
+  used = true;
+  AuxAllocas.clear();
+}
+
+~AuxillaryAllocas() {
+  if (used)
+return;
+  llvm::SetVector Uses;
+  for (auto *Inst : llvm::reverse(AuxAllocas))
+CollectUses(Inst, Uses);
+  // Delete uses in the reverse order of insertion.
+  for (auto *I : llvm::reverse(Uses))
+I->eraseFromParent();
+}
+
+  private:
+void CollectUses(llvm::Instruction *I,
+ llvm::SetVector ) {
+  if (!I || !Uses.insert(I))
+return;
+  for (auto *User : I->materialized_users()) {

usx95 wrote:

Done.

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-04-01 Thread Eli Friedman via cfe-commits


@@ -266,6 +269,54 @@ class alignas(8) EHCleanupScope : public EHScope {
   };
   mutable struct ExtInfo *ExtInfo;
 
+  /// Erases auxillary allocas and their usages for an unused cleanup.
+  /// Cleanups should mark these allocas as 'used' if the cleanup is
+  /// emitted, otherwise these instructions would be erased.
+  struct AuxillaryAllocas {
+SmallVector AuxAllocas;
+bool used = false;
+
+// Records a potentially unused instruction to be erased later.
+void Add(llvm::AllocaInst *Alloca) { AuxAllocas.push_back(Alloca); }
+
+// Mark all recorded instructions as used. These will not be erased later.
+void MarkUsed() {
+  used = true;
+  AuxAllocas.clear();
+}
+
+~AuxillaryAllocas() {
+  if (used)
+return;
+  llvm::SetVector Uses;
+  for (auto *Inst : llvm::reverse(AuxAllocas))
+CollectUses(Inst, Uses);
+  // Delete uses in the reverse order of insertion.
+  for (auto *I : llvm::reverse(Uses))
+I->eraseFromParent();
+}
+
+  private:
+void CollectUses(llvm::Instruction *I,
+ llvm::SetVector ) {
+  if (!I || !Uses.insert(I))
+return;
+  for (auto *User : I->materialized_users()) {

efriedma-quic wrote:

Just "users()" (materialization isn't relevant here), and you can just `cast<>` 
to Instruction (all users of an Instruction are Instructions).

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-04-01 Thread Eli Friedman via cfe-commits


@@ -1105,19 +1105,24 @@ void CodeGenFunction::EmitNewArrayInitializer(
 }
 
 // Enter a partial-destruction Cleanup if necessary.
-if (needsEHCleanup(DtorKind)) {
+if (DtorKind) {
+  AllocaTrackerRAII AllocaTracker(*this);

efriedma-quic wrote:

"AllocaTracker" seems like overkill; CreateTempAlloca has an out parameter to 
access the created alloca, and I don't think you're creating any other allocas.

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-31 Thread Utkarsh Saxena via cfe-commits

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-31 Thread Utkarsh Saxena via cfe-commits

usx95 wrote:

Thanks @efriedma-quic . I was not aware that we have such edges in Codegen 
which could help in deleting these instructions transitively. Switched to 
capturing only auxillary `allocas` and deleting all transitive uses. PTAL.

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-31 Thread Utkarsh Saxena via cfe-commits


@@ -2503,6 +2506,29 @@ Stmt *BlockExpr::getBody() {
 // Generic Expression Routines
 
//===--===//
 
+bool Expr::mayBranchOut() const {

usx95 wrote:

This is now no more needed. We switched to deleting instructions related to 
unemitted cleanups.

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-31 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/85398

>From 0654f624b3b60026398e8b0168623a85e3129630 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 15 Mar 2024 13:19:36 +
Subject: [PATCH 1/8] [codegen] Emit cleanups for branch in stmt-expr and coro
 suspensions

---
 clang/lib/CodeGen/CGCleanup.cpp |  7 +--
 clang/lib/CodeGen/CGExprAgg.cpp | 13 +++--
 2 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp
index f87caf050eeaa7..c22d4da0fefc3c 100644
--- a/clang/lib/CodeGen/CGCleanup.cpp
+++ b/clang/lib/CodeGen/CGCleanup.cpp
@@ -694,7 +694,8 @@ void CodeGenFunction::PopCleanupBlock(bool 
FallthroughIsBranchThrough) {
 
   // - whether there's a fallthrough
   llvm::BasicBlock *FallthroughSource = Builder.GetInsertBlock();
-  bool HasFallthrough = (FallthroughSource != nullptr && IsActive);
+  bool HasFallthrough =
+  FallthroughSource != nullptr && (IsActive || HasExistingBranches);
 
   // Branch-through fall-throughs leave the insertion point set to the
   // end of the last cleanup, which points to the current scope.  The
@@ -719,7 +720,9 @@ void CodeGenFunction::PopCleanupBlock(bool 
FallthroughIsBranchThrough) {
 
   // If we have a prebranched fallthrough into an inactive normal
   // cleanup, rewrite it so that it leads to the appropriate place.
-  if (Scope.isNormalCleanup() && HasPrebranchedFallthrough && !IsActive) {
+  if (Scope.isNormalCleanup() && HasPrebranchedFallthrough &&
+  !RequiresNormalCleanup) {
+assert(!IsActive);
 llvm::BasicBlock *prebranchDest;
 
 // If the prebranch is semantically branching through the next
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index 5190b22bcc1622..7e62599089b8df 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -15,6 +15,7 @@
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
 #include "ConstantEmitter.h"
+#include "EHScopeStack.h"
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Attr.h"
@@ -1389,15 +1390,15 @@ AggExprEmitter::VisitLambdaExpr(LambdaExpr *E) {
 if (QualType::DestructionKind DtorKind =
 CurField->getType().isDestructedType()) {
   assert(LV.isSimple());
-  if (CGF.needsEHCleanup(DtorKind)) {
+  if (DtorKind) {
 if (!CleanupDominator)
   CleanupDominator = CGF.Builder.CreateAlignedLoad(
   CGF.Int8Ty,
   llvm::Constant::getNullValue(CGF.Int8PtrTy),
   CharUnits::One()); // placeholder
 
-CGF.pushDestroy(EHCleanup, LV.getAddress(CGF), CurField->getType(),
-CGF.getDestroyer(DtorKind), false);
+CGF.pushDestroy(NormalAndEHCleanup, LV.getAddress(CGF),
+CurField->getType(), CGF.getDestroyer(DtorKind), 
false);
 Cleanups.push_back(CGF.EHStack.stable_begin());
   }
 }
@@ -1806,9 +1807,9 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr(
 if (QualType::DestructionKind dtorKind
   = field->getType().isDestructedType()) {
   assert(LV.isSimple());
-  if (CGF.needsEHCleanup(dtorKind)) {
-CGF.pushDestroy(EHCleanup, LV.getAddress(CGF), field->getType(),
-CGF.getDestroyer(dtorKind), false);
+  if (dtorKind) {
+CGF.pushDestroy(NormalAndEHCleanup, LV.getAddress(CGF),
+field->getType(), CGF.getDestroyer(dtorKind), false);
 addCleanup(CGF.EHStack.stable_begin());
 pushedCleanup = true;
   }

>From 1b7c160b030f3a765d40723bbbf9a7daa4a1e090 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 15 Mar 2024 15:22:07 +
Subject: [PATCH 2/8] add tests

---
 .../control-flow-in-expr-cleanup.cpp  | 172 ++
 1 file changed, 172 insertions(+)
 create mode 100644 
clang/test/CodeGenCoroutines/control-flow-in-expr-cleanup.cpp

diff --git a/clang/test/CodeGenCoroutines/control-flow-in-expr-cleanup.cpp 
b/clang/test/CodeGenCoroutines/control-flow-in-expr-cleanup.cpp
new file mode 100644
index 00..d703532b5a10b9
--- /dev/null
+++ b/clang/test/CodeGenCoroutines/control-flow-in-expr-cleanup.cpp
@@ -0,0 +1,172 @@
+// RUN: %clang_cc1 --std=c++20 -triple x86_64-linux-gnu -emit-llvm %s -o - | 
FileCheck %s
+
+#include "Inputs/coroutine.h"
+
+struct Printy {
+  Printy(const char *name) : name(name) {}
+  ~Printy() {}
+  const char *name;
+};
+
+struct coroutine {
+  struct promise_type;
+  std::coroutine_handle handle;
+  ~coroutine() {
+if (handle) handle.destroy();
+  }
+};
+
+struct coroutine::promise_type {
+  coroutine get_return_object() {
+return {std::coroutine_handle::from_promise(*this)};
+  }
+  std::suspend_never initial_suspend() noexcept { return {}; }
+  std::suspend_always final_suspend() noexcept { return {}; }
+  void return_void() {}
+  void unhandled_exception() {}
+};
+
+struct Awaiter : 

[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-27 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

> > Instead of Expr::mayBranchOut, I'd prefer to just unconditionally create 
> > the alloca, then delete it later if it turns out we didn't actually need to 
> > emit the branch.
> 
> I had earlier tried tracking instructions auxiliary to a particular cleanup 
> in #83224 
> ([src](https://github.com/llvm/llvm-project/pull/83224/files#diff-9cdaea6a793ed2892bfcd6b431e933a49ebb25caa2bd1d630cd1ca823281092aR263-R286)).
>  This gets ugly very quickly and adds quite some complexity to the cleanup 
> addition and emission code. For example, more instructions could be added if 
> the cleanup is conditional.

You could simplify that code significantly, I think: instead of adding every 
instruction to the list, just add the alloca, then recursively delete all 
instructions that use the alloca.

> As far as compile-time is concerned, this involves revisiting the complete 
> expression exactly one more time.

You can end up visiting more than once if an array init contains another array 
init.

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-27 Thread Utkarsh Saxena via cfe-commits

usx95 wrote:

> Instead of Expr::mayBranchOut, I'd prefer to just unconditionally create the 
> alloca, then delete it later if it turns out we didn't actually need to emit 
> the branch. 

I had earlier tried tracking instructions auxiliary to a particular cleanup in 
#83224 
([src](https://github.com/llvm/llvm-project/pull/83224/files#diff-9cdaea6a793ed2892bfcd6b431e933a49ebb25caa2bd1d630cd1ca823281092aR263-R286)).
 This gets ugly very quickly and adds quite some complexity to the cleanup 
addition and emission code. For example, more instructions could be added if 
the cleanup is conditional.

> Trying to explicitly compute whether there's a branch out seems both 
> difficult, and potentially costly for compile-time.

Computing this 100% accurately is indeed difficult. But if we allow 
false-positives, as in the current approach, it gets clearer and simpler. As 
far as compile-time is concerned, this involves revisiting the complete 
expression exactly one more time. We could, in principle, cache this per 
expression to keep this linear. 


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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-27 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/85398

>From 0654f624b3b60026398e8b0168623a85e3129630 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 15 Mar 2024 13:19:36 +
Subject: [PATCH 1/7] [codegen] Emit cleanups for branch in stmt-expr and coro
 suspensions

---
 clang/lib/CodeGen/CGCleanup.cpp |  7 +--
 clang/lib/CodeGen/CGExprAgg.cpp | 13 +++--
 2 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp
index f87caf050eeaa7..c22d4da0fefc3c 100644
--- a/clang/lib/CodeGen/CGCleanup.cpp
+++ b/clang/lib/CodeGen/CGCleanup.cpp
@@ -694,7 +694,8 @@ void CodeGenFunction::PopCleanupBlock(bool 
FallthroughIsBranchThrough) {
 
   // - whether there's a fallthrough
   llvm::BasicBlock *FallthroughSource = Builder.GetInsertBlock();
-  bool HasFallthrough = (FallthroughSource != nullptr && IsActive);
+  bool HasFallthrough =
+  FallthroughSource != nullptr && (IsActive || HasExistingBranches);
 
   // Branch-through fall-throughs leave the insertion point set to the
   // end of the last cleanup, which points to the current scope.  The
@@ -719,7 +720,9 @@ void CodeGenFunction::PopCleanupBlock(bool 
FallthroughIsBranchThrough) {
 
   // If we have a prebranched fallthrough into an inactive normal
   // cleanup, rewrite it so that it leads to the appropriate place.
-  if (Scope.isNormalCleanup() && HasPrebranchedFallthrough && !IsActive) {
+  if (Scope.isNormalCleanup() && HasPrebranchedFallthrough &&
+  !RequiresNormalCleanup) {
+assert(!IsActive);
 llvm::BasicBlock *prebranchDest;
 
 // If the prebranch is semantically branching through the next
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index 5190b22bcc1622..7e62599089b8df 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -15,6 +15,7 @@
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
 #include "ConstantEmitter.h"
+#include "EHScopeStack.h"
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Attr.h"
@@ -1389,15 +1390,15 @@ AggExprEmitter::VisitLambdaExpr(LambdaExpr *E) {
 if (QualType::DestructionKind DtorKind =
 CurField->getType().isDestructedType()) {
   assert(LV.isSimple());
-  if (CGF.needsEHCleanup(DtorKind)) {
+  if (DtorKind) {
 if (!CleanupDominator)
   CleanupDominator = CGF.Builder.CreateAlignedLoad(
   CGF.Int8Ty,
   llvm::Constant::getNullValue(CGF.Int8PtrTy),
   CharUnits::One()); // placeholder
 
-CGF.pushDestroy(EHCleanup, LV.getAddress(CGF), CurField->getType(),
-CGF.getDestroyer(DtorKind), false);
+CGF.pushDestroy(NormalAndEHCleanup, LV.getAddress(CGF),
+CurField->getType(), CGF.getDestroyer(DtorKind), 
false);
 Cleanups.push_back(CGF.EHStack.stable_begin());
   }
 }
@@ -1806,9 +1807,9 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr(
 if (QualType::DestructionKind dtorKind
   = field->getType().isDestructedType()) {
   assert(LV.isSimple());
-  if (CGF.needsEHCleanup(dtorKind)) {
-CGF.pushDestroy(EHCleanup, LV.getAddress(CGF), field->getType(),
-CGF.getDestroyer(dtorKind), false);
+  if (dtorKind) {
+CGF.pushDestroy(NormalAndEHCleanup, LV.getAddress(CGF),
+field->getType(), CGF.getDestroyer(dtorKind), false);
 addCleanup(CGF.EHStack.stable_begin());
 pushedCleanup = true;
   }

>From 1b7c160b030f3a765d40723bbbf9a7daa4a1e090 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 15 Mar 2024 15:22:07 +
Subject: [PATCH 2/7] add tests

---
 .../control-flow-in-expr-cleanup.cpp  | 172 ++
 1 file changed, 172 insertions(+)
 create mode 100644 
clang/test/CodeGenCoroutines/control-flow-in-expr-cleanup.cpp

diff --git a/clang/test/CodeGenCoroutines/control-flow-in-expr-cleanup.cpp 
b/clang/test/CodeGenCoroutines/control-flow-in-expr-cleanup.cpp
new file mode 100644
index 00..d703532b5a10b9
--- /dev/null
+++ b/clang/test/CodeGenCoroutines/control-flow-in-expr-cleanup.cpp
@@ -0,0 +1,172 @@
+// RUN: %clang_cc1 --std=c++20 -triple x86_64-linux-gnu -emit-llvm %s -o - | 
FileCheck %s
+
+#include "Inputs/coroutine.h"
+
+struct Printy {
+  Printy(const char *name) : name(name) {}
+  ~Printy() {}
+  const char *name;
+};
+
+struct coroutine {
+  struct promise_type;
+  std::coroutine_handle handle;
+  ~coroutine() {
+if (handle) handle.destroy();
+  }
+};
+
+struct coroutine::promise_type {
+  coroutine get_return_object() {
+return {std::coroutine_handle::from_promise(*this)};
+  }
+  std::suspend_never initial_suspend() noexcept { return {}; }
+  std::suspend_always final_suspend() noexcept { return {}; }
+  void return_void() {}
+  void unhandled_exception() {}
+};
+
+struct Awaiter : 

[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-26 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

If we do keep mayBranchOut(), "asm goto" should also be added to the list of 
expressions that can branch out.  (I think JumpDiagnostics currently forbids 
actually branching out in cases that would require a cleanup, but better to be 
defensive here.)

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-26 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

Instead of Expr::mayBranchOut, I'd prefer to just unconditionally create the 
alloca, then delete it later if it turns out we didn't actually need to emit 
the branch.  Trying to explicitly compute whether there's a branch out seems 
both difficult, and potentially costly for compile-time.

I like the unified approach here for eh and non-eh cleanups.

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-26 Thread Richard Smith via cfe-commits


@@ -2503,6 +2506,29 @@ Stmt *BlockExpr::getBody() {
 // Generic Expression Routines
 
//===--===//
 
+bool Expr::mayBranchOut() const {

zygoloid wrote:

Computing this seems a little expensive in general. I wonder if we could track 
a bit on `FunctionDecl` that indicates whether it contains any branches out of 
statement expressions, and skip calling this if the enclosing function is not a 
coroutine and does not contain branches out of statement expressions.

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-25 Thread Utkarsh Saxena via cfe-commits

usx95 wrote:

> Perhaps we want this test to live in CodeGen rather than CodeGenCoroutines 
> given that it covers so many non-coroutine test cases as well?
Makes sense. I split the tests into coroutine and stmt-expr (didn't want to 
depend on "Inputs/coroutine.h" from CodegenCXX).



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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-25 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/85398

>From 0654f624b3b60026398e8b0168623a85e3129630 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 15 Mar 2024 13:19:36 +
Subject: [PATCH 1/6] [codegen] Emit cleanups for branch in stmt-expr and coro
 suspensions

---
 clang/lib/CodeGen/CGCleanup.cpp |  7 +--
 clang/lib/CodeGen/CGExprAgg.cpp | 13 +++--
 2 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp
index f87caf050eeaa7..c22d4da0fefc3c 100644
--- a/clang/lib/CodeGen/CGCleanup.cpp
+++ b/clang/lib/CodeGen/CGCleanup.cpp
@@ -694,7 +694,8 @@ void CodeGenFunction::PopCleanupBlock(bool 
FallthroughIsBranchThrough) {
 
   // - whether there's a fallthrough
   llvm::BasicBlock *FallthroughSource = Builder.GetInsertBlock();
-  bool HasFallthrough = (FallthroughSource != nullptr && IsActive);
+  bool HasFallthrough =
+  FallthroughSource != nullptr && (IsActive || HasExistingBranches);
 
   // Branch-through fall-throughs leave the insertion point set to the
   // end of the last cleanup, which points to the current scope.  The
@@ -719,7 +720,9 @@ void CodeGenFunction::PopCleanupBlock(bool 
FallthroughIsBranchThrough) {
 
   // If we have a prebranched fallthrough into an inactive normal
   // cleanup, rewrite it so that it leads to the appropriate place.
-  if (Scope.isNormalCleanup() && HasPrebranchedFallthrough && !IsActive) {
+  if (Scope.isNormalCleanup() && HasPrebranchedFallthrough &&
+  !RequiresNormalCleanup) {
+assert(!IsActive);
 llvm::BasicBlock *prebranchDest;
 
 // If the prebranch is semantically branching through the next
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index 5190b22bcc1622..7e62599089b8df 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -15,6 +15,7 @@
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
 #include "ConstantEmitter.h"
+#include "EHScopeStack.h"
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Attr.h"
@@ -1389,15 +1390,15 @@ AggExprEmitter::VisitLambdaExpr(LambdaExpr *E) {
 if (QualType::DestructionKind DtorKind =
 CurField->getType().isDestructedType()) {
   assert(LV.isSimple());
-  if (CGF.needsEHCleanup(DtorKind)) {
+  if (DtorKind) {
 if (!CleanupDominator)
   CleanupDominator = CGF.Builder.CreateAlignedLoad(
   CGF.Int8Ty,
   llvm::Constant::getNullValue(CGF.Int8PtrTy),
   CharUnits::One()); // placeholder
 
-CGF.pushDestroy(EHCleanup, LV.getAddress(CGF), CurField->getType(),
-CGF.getDestroyer(DtorKind), false);
+CGF.pushDestroy(NormalAndEHCleanup, LV.getAddress(CGF),
+CurField->getType(), CGF.getDestroyer(DtorKind), 
false);
 Cleanups.push_back(CGF.EHStack.stable_begin());
   }
 }
@@ -1806,9 +1807,9 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr(
 if (QualType::DestructionKind dtorKind
   = field->getType().isDestructedType()) {
   assert(LV.isSimple());
-  if (CGF.needsEHCleanup(dtorKind)) {
-CGF.pushDestroy(EHCleanup, LV.getAddress(CGF), field->getType(),
-CGF.getDestroyer(dtorKind), false);
+  if (dtorKind) {
+CGF.pushDestroy(NormalAndEHCleanup, LV.getAddress(CGF),
+field->getType(), CGF.getDestroyer(dtorKind), false);
 addCleanup(CGF.EHStack.stable_begin());
 pushedCleanup = true;
   }

>From 1b7c160b030f3a765d40723bbbf9a7daa4a1e090 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 15 Mar 2024 15:22:07 +
Subject: [PATCH 2/6] add tests

---
 .../control-flow-in-expr-cleanup.cpp  | 172 ++
 1 file changed, 172 insertions(+)
 create mode 100644 
clang/test/CodeGenCoroutines/control-flow-in-expr-cleanup.cpp

diff --git a/clang/test/CodeGenCoroutines/control-flow-in-expr-cleanup.cpp 
b/clang/test/CodeGenCoroutines/control-flow-in-expr-cleanup.cpp
new file mode 100644
index 00..d703532b5a10b9
--- /dev/null
+++ b/clang/test/CodeGenCoroutines/control-flow-in-expr-cleanup.cpp
@@ -0,0 +1,172 @@
+// RUN: %clang_cc1 --std=c++20 -triple x86_64-linux-gnu -emit-llvm %s -o - | 
FileCheck %s
+
+#include "Inputs/coroutine.h"
+
+struct Printy {
+  Printy(const char *name) : name(name) {}
+  ~Printy() {}
+  const char *name;
+};
+
+struct coroutine {
+  struct promise_type;
+  std::coroutine_handle handle;
+  ~coroutine() {
+if (handle) handle.destroy();
+  }
+};
+
+struct coroutine::promise_type {
+  coroutine get_return_object() {
+return {std::coroutine_handle::from_promise(*this)};
+  }
+  std::suspend_never initial_suspend() noexcept { return {}; }
+  std::suspend_always final_suspend() noexcept { return {}; }
+  void return_void() {}
+  void unhandled_exception() {}
+};
+
+struct Awaiter : 

[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-25 Thread Utkarsh Saxena via cfe-commits

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-25 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman commented:

I didn't look too hard at the codegen bits, but the Expr bits look good to me. 
Perhaps we want this test to live in CodeGen rather than CodeGenCoroutines 
given that it covers so many non-coroutine test cases as well?

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-25 Thread via cfe-commits

github-actions[bot] wrote:



:white_check_mark: With the latest revision this PR passed the Python code 
formatter.

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-25 Thread via cfe-commits

github-actions[bot] wrote:



:white_check_mark: With the latest revision this PR passed the C/C++ code 
formatter.

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-25 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/85398

>From 0654f624b3b60026398e8b0168623a85e3129630 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 15 Mar 2024 13:19:36 +
Subject: [PATCH 1/5] [codegen] Emit cleanups for branch in stmt-expr and coro
 suspensions

---
 clang/lib/CodeGen/CGCleanup.cpp |  7 +--
 clang/lib/CodeGen/CGExprAgg.cpp | 13 +++--
 2 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp
index f87caf050eeaa7..c22d4da0fefc3c 100644
--- a/clang/lib/CodeGen/CGCleanup.cpp
+++ b/clang/lib/CodeGen/CGCleanup.cpp
@@ -694,7 +694,8 @@ void CodeGenFunction::PopCleanupBlock(bool 
FallthroughIsBranchThrough) {
 
   // - whether there's a fallthrough
   llvm::BasicBlock *FallthroughSource = Builder.GetInsertBlock();
-  bool HasFallthrough = (FallthroughSource != nullptr && IsActive);
+  bool HasFallthrough =
+  FallthroughSource != nullptr && (IsActive || HasExistingBranches);
 
   // Branch-through fall-throughs leave the insertion point set to the
   // end of the last cleanup, which points to the current scope.  The
@@ -719,7 +720,9 @@ void CodeGenFunction::PopCleanupBlock(bool 
FallthroughIsBranchThrough) {
 
   // If we have a prebranched fallthrough into an inactive normal
   // cleanup, rewrite it so that it leads to the appropriate place.
-  if (Scope.isNormalCleanup() && HasPrebranchedFallthrough && !IsActive) {
+  if (Scope.isNormalCleanup() && HasPrebranchedFallthrough &&
+  !RequiresNormalCleanup) {
+assert(!IsActive);
 llvm::BasicBlock *prebranchDest;
 
 // If the prebranch is semantically branching through the next
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index 5190b22bcc1622..7e62599089b8df 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -15,6 +15,7 @@
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
 #include "ConstantEmitter.h"
+#include "EHScopeStack.h"
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Attr.h"
@@ -1389,15 +1390,15 @@ AggExprEmitter::VisitLambdaExpr(LambdaExpr *E) {
 if (QualType::DestructionKind DtorKind =
 CurField->getType().isDestructedType()) {
   assert(LV.isSimple());
-  if (CGF.needsEHCleanup(DtorKind)) {
+  if (DtorKind) {
 if (!CleanupDominator)
   CleanupDominator = CGF.Builder.CreateAlignedLoad(
   CGF.Int8Ty,
   llvm::Constant::getNullValue(CGF.Int8PtrTy),
   CharUnits::One()); // placeholder
 
-CGF.pushDestroy(EHCleanup, LV.getAddress(CGF), CurField->getType(),
-CGF.getDestroyer(DtorKind), false);
+CGF.pushDestroy(NormalAndEHCleanup, LV.getAddress(CGF),
+CurField->getType(), CGF.getDestroyer(DtorKind), 
false);
 Cleanups.push_back(CGF.EHStack.stable_begin());
   }
 }
@@ -1806,9 +1807,9 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr(
 if (QualType::DestructionKind dtorKind
   = field->getType().isDestructedType()) {
   assert(LV.isSimple());
-  if (CGF.needsEHCleanup(dtorKind)) {
-CGF.pushDestroy(EHCleanup, LV.getAddress(CGF), field->getType(),
-CGF.getDestroyer(dtorKind), false);
+  if (dtorKind) {
+CGF.pushDestroy(NormalAndEHCleanup, LV.getAddress(CGF),
+field->getType(), CGF.getDestroyer(dtorKind), false);
 addCleanup(CGF.EHStack.stable_begin());
 pushedCleanup = true;
   }

>From 1b7c160b030f3a765d40723bbbf9a7daa4a1e090 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 15 Mar 2024 15:22:07 +
Subject: [PATCH 2/5] add tests

---
 .../control-flow-in-expr-cleanup.cpp  | 172 ++
 1 file changed, 172 insertions(+)
 create mode 100644 
clang/test/CodeGenCoroutines/control-flow-in-expr-cleanup.cpp

diff --git a/clang/test/CodeGenCoroutines/control-flow-in-expr-cleanup.cpp 
b/clang/test/CodeGenCoroutines/control-flow-in-expr-cleanup.cpp
new file mode 100644
index 00..d703532b5a10b9
--- /dev/null
+++ b/clang/test/CodeGenCoroutines/control-flow-in-expr-cleanup.cpp
@@ -0,0 +1,172 @@
+// RUN: %clang_cc1 --std=c++20 -triple x86_64-linux-gnu -emit-llvm %s -o - | 
FileCheck %s
+
+#include "Inputs/coroutine.h"
+
+struct Printy {
+  Printy(const char *name) : name(name) {}
+  ~Printy() {}
+  const char *name;
+};
+
+struct coroutine {
+  struct promise_type;
+  std::coroutine_handle handle;
+  ~coroutine() {
+if (handle) handle.destroy();
+  }
+};
+
+struct coroutine::promise_type {
+  coroutine get_return_object() {
+return {std::coroutine_handle::from_promise(*this)};
+  }
+  std::suspend_never initial_suspend() noexcept { return {}; }
+  std::suspend_always final_suspend() noexcept { return {}; }
+  void return_void() {}
+  void unhandled_exception() {}
+};
+
+struct Awaiter : 

[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-25 Thread Utkarsh Saxena via cfe-commits

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-25 Thread Utkarsh Saxena via cfe-commits


@@ -2503,6 +2505,26 @@ Stmt *BlockExpr::getBody() {
 // Generic Expression Routines
 
//===--===//
 
+bool Expr::mayBranchOut() const {
+  struct BranchDetector : public RecursiveASTVisitor {
+bool HasBranch = false;
+bool activate() {
+  HasBranch = true;
+  return false;
+}
+// Coroutine suspensions.
+bool VisitCoawaitExpr(CoawaitExpr *) { return activate(); }
+bool VisitCoyieldExpr(CoyieldExpr *) { return activate(); }

usx95 wrote:

Done. Added tests.

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-25 Thread Utkarsh Saxena via cfe-commits


@@ -2503,6 +2505,26 @@ Stmt *BlockExpr::getBody() {
 // Generic Expression Routines
 
//===--===//
 
+bool Expr::mayBranchOut() const {
+  struct BranchDetector : public RecursiveASTVisitor {
+bool HasBranch = false;
+bool activate() {
+  HasBranch = true;
+  return false;
+}
+// Coroutine suspensions.
+bool VisitCoawaitExpr(CoawaitExpr *) { return activate(); }
+bool VisitCoyieldExpr(CoyieldExpr *) { return activate(); }
+// Control flow in stmt-expressions.
+bool VisitBreakStmt(BreakStmt *) { return activate(); }

usx95 wrote:

Yes. Added a test case for it as well.

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-25 Thread Utkarsh Saxena via cfe-commits


@@ -2503,6 +2505,26 @@ Stmt *BlockExpr::getBody() {
 // Generic Expression Routines
 
//===--===//
 
+bool Expr::mayBranchOut() const {
+  struct BranchDetector : public RecursiveASTVisitor {
+bool HasBranch = false;
+bool activate() {
+  HasBranch = true;
+  return false;
+}
+// Coroutine suspensions.
+bool VisitCoawaitExpr(CoawaitExpr *) { return activate(); }
+bool VisitCoyieldExpr(CoyieldExpr *) { return activate(); }
+// Control flow in stmt-expressions.
+bool VisitBreakStmt(BreakStmt *) { return activate(); }
+bool VisitReturnStmt(ReturnStmt *) { return activate(); }
+bool VisitGotoStmt(GotoStmt *) { return activate(); }
+  };

usx95 wrote:

I think it should be fine to stick to non-exceptional control flow out of this 
expression. `throw` or, for that matter, any call to a throwing function would 
be branching but that is already dealt with exceptions.

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-25 Thread Utkarsh Saxena via cfe-commits


@@ -2503,6 +2505,26 @@ Stmt *BlockExpr::getBody() {
 // Generic Expression Routines
 
//===--===//
 
+bool Expr::mayBranchOut() const {
+  struct BranchDetector : public RecursiveASTVisitor {
+bool HasBranch = false;
+bool activate() {
+  HasBranch = true;
+  return false;
+}
+// Coroutine suspensions.
+bool VisitCoawaitExpr(CoawaitExpr *) { return activate(); }
+bool VisitCoyieldExpr(CoyieldExpr *) { return activate(); }
+// Control flow in stmt-expressions.
+bool VisitBreakStmt(BreakStmt *) { return activate(); }
+bool VisitReturnStmt(ReturnStmt *) { return activate(); }
+bool VisitGotoStmt(GotoStmt *) { return activate(); }

usx95 wrote:

Added. 

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-25 Thread Aaron Ballman via cfe-commits


@@ -2503,6 +2505,26 @@ Stmt *BlockExpr::getBody() {
 // Generic Expression Routines
 
//===--===//
 
+bool Expr::mayBranchOut() const {
+  struct BranchDetector : public RecursiveASTVisitor {
+bool HasBranch = false;
+bool activate() {
+  HasBranch = true;
+  return false;
+}
+// Coroutine suspensions.
+bool VisitCoawaitExpr(CoawaitExpr *) { return activate(); }
+bool VisitCoyieldExpr(CoyieldExpr *) { return activate(); }

AaronBallman wrote:

Should this also handle `co_return` statements?

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-25 Thread Aaron Ballman via cfe-commits


@@ -2503,6 +2505,26 @@ Stmt *BlockExpr::getBody() {
 // Generic Expression Routines
 
//===--===//
 
+bool Expr::mayBranchOut() const {
+  struct BranchDetector : public RecursiveASTVisitor {
+bool HasBranch = false;
+bool activate() {
+  HasBranch = true;
+  return false;
+}
+// Coroutine suspensions.
+bool VisitCoawaitExpr(CoawaitExpr *) { return activate(); }
+bool VisitCoyieldExpr(CoyieldExpr *) { return activate(); }
+// Control flow in stmt-expressions.
+bool VisitBreakStmt(BreakStmt *) { return activate(); }
+bool VisitReturnStmt(ReturnStmt *) { return activate(); }
+bool VisitGotoStmt(GotoStmt *) { return activate(); }

AaronBallman wrote:

Should this also handle indirect goto statements?

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-25 Thread Aaron Ballman via cfe-commits


@@ -2503,6 +2505,26 @@ Stmt *BlockExpr::getBody() {
 // Generic Expression Routines
 
//===--===//
 
+bool Expr::mayBranchOut() const {
+  struct BranchDetector : public RecursiveASTVisitor {
+bool HasBranch = false;
+bool activate() {
+  HasBranch = true;
+  return false;
+}
+// Coroutine suspensions.
+bool VisitCoawaitExpr(CoawaitExpr *) { return activate(); }
+bool VisitCoyieldExpr(CoyieldExpr *) { return activate(); }
+// Control flow in stmt-expressions.
+bool VisitBreakStmt(BreakStmt *) { return activate(); }

AaronBallman wrote:

Should this also handle continue statements?

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-25 Thread Aaron Ballman via cfe-commits


@@ -2503,6 +2505,26 @@ Stmt *BlockExpr::getBody() {
 // Generic Expression Routines
 
//===--===//
 
+bool Expr::mayBranchOut() const {
+  struct BranchDetector : public RecursiveASTVisitor {
+bool HasBranch = false;
+bool activate() {
+  HasBranch = true;
+  return false;
+}
+// Coroutine suspensions.
+bool VisitCoawaitExpr(CoawaitExpr *) { return activate(); }
+bool VisitCoyieldExpr(CoyieldExpr *) { return activate(); }
+// Control flow in stmt-expressions.
+bool VisitBreakStmt(BreakStmt *) { return activate(); }
+bool VisitReturnStmt(ReturnStmt *) { return activate(); }
+bool VisitGotoStmt(GotoStmt *) { return activate(); }
+  };

AaronBallman wrote:

Should we consider `throw` to be a kind of branching control flow as well?

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-25 Thread Aaron Ballman via cfe-commits

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-25 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman commented:

Hopefully @rjmccall or @efriedma-quic can take a look at the codegen bits. I 
did have some questions about other kinds of flow control statements we might 
want to cover.

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-25 Thread via cfe-commits

Sirraide wrote:

I’m the wrong person to ping if it’s anything codegen-related; I’ll leave 
reviewing this to people more familiar w/ that part of Clang.

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-25 Thread Utkarsh Saxena via cfe-commits

usx95 wrote:

Ping for review: @AaronBallman @jyknight @efriedma-quic @zygoloid 
Could you please suggest other reviewers if you do not have the bandwidth for 
the same?

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-20 Thread Utkarsh Saxena via cfe-commits

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-20 Thread Utkarsh Saxena via cfe-commits

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-20 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/85398

>From 0654f624b3b60026398e8b0168623a85e3129630 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 15 Mar 2024 13:19:36 +
Subject: [PATCH 1/4] [codegen] Emit cleanups for branch in stmt-expr and coro
 suspensions

---
 clang/lib/CodeGen/CGCleanup.cpp |  7 +--
 clang/lib/CodeGen/CGExprAgg.cpp | 13 +++--
 2 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp
index f87caf050eeaa7..c22d4da0fefc3c 100644
--- a/clang/lib/CodeGen/CGCleanup.cpp
+++ b/clang/lib/CodeGen/CGCleanup.cpp
@@ -694,7 +694,8 @@ void CodeGenFunction::PopCleanupBlock(bool 
FallthroughIsBranchThrough) {
 
   // - whether there's a fallthrough
   llvm::BasicBlock *FallthroughSource = Builder.GetInsertBlock();
-  bool HasFallthrough = (FallthroughSource != nullptr && IsActive);
+  bool HasFallthrough =
+  FallthroughSource != nullptr && (IsActive || HasExistingBranches);
 
   // Branch-through fall-throughs leave the insertion point set to the
   // end of the last cleanup, which points to the current scope.  The
@@ -719,7 +720,9 @@ void CodeGenFunction::PopCleanupBlock(bool 
FallthroughIsBranchThrough) {
 
   // If we have a prebranched fallthrough into an inactive normal
   // cleanup, rewrite it so that it leads to the appropriate place.
-  if (Scope.isNormalCleanup() && HasPrebranchedFallthrough && !IsActive) {
+  if (Scope.isNormalCleanup() && HasPrebranchedFallthrough &&
+  !RequiresNormalCleanup) {
+assert(!IsActive);
 llvm::BasicBlock *prebranchDest;
 
 // If the prebranch is semantically branching through the next
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index 5190b22bcc1622..7e62599089b8df 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -15,6 +15,7 @@
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
 #include "ConstantEmitter.h"
+#include "EHScopeStack.h"
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Attr.h"
@@ -1389,15 +1390,15 @@ AggExprEmitter::VisitLambdaExpr(LambdaExpr *E) {
 if (QualType::DestructionKind DtorKind =
 CurField->getType().isDestructedType()) {
   assert(LV.isSimple());
-  if (CGF.needsEHCleanup(DtorKind)) {
+  if (DtorKind) {
 if (!CleanupDominator)
   CleanupDominator = CGF.Builder.CreateAlignedLoad(
   CGF.Int8Ty,
   llvm::Constant::getNullValue(CGF.Int8PtrTy),
   CharUnits::One()); // placeholder
 
-CGF.pushDestroy(EHCleanup, LV.getAddress(CGF), CurField->getType(),
-CGF.getDestroyer(DtorKind), false);
+CGF.pushDestroy(NormalAndEHCleanup, LV.getAddress(CGF),
+CurField->getType(), CGF.getDestroyer(DtorKind), 
false);
 Cleanups.push_back(CGF.EHStack.stable_begin());
   }
 }
@@ -1806,9 +1807,9 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr(
 if (QualType::DestructionKind dtorKind
   = field->getType().isDestructedType()) {
   assert(LV.isSimple());
-  if (CGF.needsEHCleanup(dtorKind)) {
-CGF.pushDestroy(EHCleanup, LV.getAddress(CGF), field->getType(),
-CGF.getDestroyer(dtorKind), false);
+  if (dtorKind) {
+CGF.pushDestroy(NormalAndEHCleanup, LV.getAddress(CGF),
+field->getType(), CGF.getDestroyer(dtorKind), false);
 addCleanup(CGF.EHStack.stable_begin());
 pushedCleanup = true;
   }

>From 1b7c160b030f3a765d40723bbbf9a7daa4a1e090 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 15 Mar 2024 15:22:07 +
Subject: [PATCH 2/4] add tests

---
 .../control-flow-in-expr-cleanup.cpp  | 172 ++
 1 file changed, 172 insertions(+)
 create mode 100644 
clang/test/CodeGenCoroutines/control-flow-in-expr-cleanup.cpp

diff --git a/clang/test/CodeGenCoroutines/control-flow-in-expr-cleanup.cpp 
b/clang/test/CodeGenCoroutines/control-flow-in-expr-cleanup.cpp
new file mode 100644
index 00..d703532b5a10b9
--- /dev/null
+++ b/clang/test/CodeGenCoroutines/control-flow-in-expr-cleanup.cpp
@@ -0,0 +1,172 @@
+// RUN: %clang_cc1 --std=c++20 -triple x86_64-linux-gnu -emit-llvm %s -o - | 
FileCheck %s
+
+#include "Inputs/coroutine.h"
+
+struct Printy {
+  Printy(const char *name) : name(name) {}
+  ~Printy() {}
+  const char *name;
+};
+
+struct coroutine {
+  struct promise_type;
+  std::coroutine_handle handle;
+  ~coroutine() {
+if (handle) handle.destroy();
+  }
+};
+
+struct coroutine::promise_type {
+  coroutine get_return_object() {
+return {std::coroutine_handle::from_promise(*this)};
+  }
+  std::suspend_never initial_suspend() noexcept { return {}; }
+  std::suspend_always final_suspend() noexcept { return {}; }
+  void return_void() {}
+  void unhandled_exception() {}
+};
+
+struct Awaiter : 

[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-20 Thread Utkarsh Saxena via cfe-commits

usx95 wrote:

Friendly ping for review: @jyknight @zygoloid @efriedma-quic

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-20 Thread Utkarsh Saxena via cfe-commits

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


[clang] [codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] (PR #85398)

2024-03-20 Thread Utkarsh Saxena via cfe-commits

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