From 90abedc4620a539830ea7777bceb13db82fb9d99 Mon Sep 17 00:00:00 2001 From: TB Schardl Date: Fri, 22 Nov 2024 08:34:19 -0500 Subject: [PATCH] [CGCilk] Fix code generation of normal cleanup destination slot around unassociated taskframes. --- clang/lib/CodeGen/CGCilk.cpp | 14 ++++----- clang/lib/CodeGen/CodeGenFunction.h | 1 - .../Cilk/cilkscope-try-normal-cleanup.cpp | 29 +++++++++++++++++++ 3 files changed, 35 insertions(+), 9 deletions(-) create mode 100644 clang/test/Cilk/cilkscope-try-normal-cleanup.cpp diff --git a/clang/lib/CodeGen/CGCilk.cpp b/clang/lib/CodeGen/CGCilk.cpp index 72a9faaf66e8..c29d82d7a9f0 100644 --- a/clang/lib/CodeGen/CGCilk.cpp +++ b/clang/lib/CodeGen/CGCilk.cpp @@ -347,6 +347,10 @@ CodeGenFunction::TaskFrameScope::TaskFrameScope(CodeGenFunction &CGF) CGF.CGM.getIntrinsic(llvm::Intrinsic::taskframe_create); TaskFrame = CGF.Builder.CreateCall(TaskFrameCreate); + // Make sure the normal cleanup dest slot is allocated before changing the + // alloca insertion point. + CGF.getNormalCleanupDestSlot(); + // Create a new alloca insertion point within the task frame. OldAllocaInsertPt = CGF.AllocaInsertPt; llvm::Value *Undef = llvm::UndefValue::get(CGF.Int32Ty); @@ -360,8 +364,6 @@ CodeGenFunction::TaskFrameScope::TaskFrameScope(CodeGenFunction &CGF) CGF.ExceptionSlot = nullptr; OldEHSelectorSlot = CGF.EHSelectorSlot; CGF.EHSelectorSlot = nullptr; - OldNormalCleanupDest = CGF.NormalCleanupDest; - CGF.NormalCleanupDest = Address::invalid(); CGF.pushFullExprCleanup( static_cast(NormalAndEHCleanup | LifetimeMarker | TaskExit), @@ -375,7 +377,7 @@ CodeGenFunction::TaskFrameScope::~TaskFrameScope() { return; // Pop the taskframe. - CGF.PopCleanupBlock(); + CGF.PopCleanupBlock(true); // Restore the alloca insertion point. { @@ -389,7 +391,6 @@ CodeGenFunction::TaskFrameScope::~TaskFrameScope() { CGF.EHResumeBlock = OldEHResumeBlock; CGF.ExceptionSlot = OldExceptionSlot; CGF.EHSelectorSlot = OldEHSelectorSlot; - CGF.NormalCleanupDest = OldNormalCleanupDest; if (TempInvokeDest) { if (llvm::BasicBlock *InvokeDest = CGF.getInvokeDest()) { @@ -475,16 +476,13 @@ void CodeGenFunction::EmitCilkScopeStmt(const CilkScopeStmt &S) { TapirRTStart); } // Create a nested synced scope. - SyncedScopeRAII SyncedScp(*this); - PushSyncRegion()->addImplicitSync(); + SyncRegionRAII SyncReg(*this); bool BodyIsCompoundStmt = isa(S.getBody()); if (BodyIsCompoundStmt) ScopeIsSynced = true; // Emit the spawned statement. EmitStmt(S.getBody()); - - PopSyncRegion(); } // If this _Cilk_scope is outermost in the function, mark that CodeGen is no diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 678f373f99ab..86d2a38ddd1a 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -1638,7 +1638,6 @@ class CodeGenFunction : public CodeGenTypeCache { llvm::BasicBlock *OldEHResumeBlock = nullptr; llvm::Value *OldExceptionSlot = nullptr; llvm::AllocaInst *OldEHSelectorSlot = nullptr; - Address OldNormalCleanupDest = Address::invalid(); // Taskframe created separately from detach. llvm::Value *TaskFrame = nullptr; diff --git a/clang/test/Cilk/cilkscope-try-normal-cleanup.cpp b/clang/test/Cilk/cilkscope-try-normal-cleanup.cpp new file mode 100644 index 000000000000..99c62bd0a2d3 --- /dev/null +++ b/clang/test/Cilk/cilkscope-try-normal-cleanup.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 %s -x c++ -O1 -fcxx-exceptions -fexceptions -fopencilk -mllvm -use-opencilk-runtime-bc=false -mllvm -debug-abi-calls=true -verify -S -emit-llvm -o - | FileCheck %s +// expected-no-diagnostics +extern int maybe_throws(int); + +// CHECK-LABEL: _Z9function4v +int function4() +{ + _Cilk_scope { + try { +// CHECK: i32 @_Z12maybe_throwsi +// CHECK-NEXT: to label %[[NORMAL:.+]] unwind label %[[LPAD:.+]] + maybe_throws(1); +// CHECK: [[LPAD]]: +// CHECK: invoke +// CHECK-NECT: to label %[[NORMAL]] unwind label %[[LPAD1:.+]] + return 1; + } catch (...) { +// CHECK: [[NORMAL]]: +// CHECK-NEXT: %[[RETVAL:.+]] = phi i32 +// CHECK-DAG: [ 2, %[[LPAD]] ] +// CHECK-DAG: [ 1, %entry ] +// CHECK: ret i32 %[[RETVAL]] + return 2; + } + } +// This return is unreachable. +// CHECK-NOT: ret i32 3 + return 3; +} \ No newline at end of file