llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clangir

Author: Morris Hafner (mmha)

<details>
<summary>Changes</summary>

FlattenCFG retains `omp.parallel` regions, so landing pads for a `try/catch` 
inside a `#pragma omp parallel` must be created in the parallel region.

EHABILowering currently only erases `!cir.eh_token` block arguments in the top 
level function blocks and skips over nests like a parallel region.

Erase the token arguments recursively instead. Create the terminate landing pad 
in the region of the `catch` parameter.

That enables `catch(...)` inside a parallel region. Add a diagnostic for 
`catch(E)` in DirectToLLVM lowering. This requires the outliner to support 
`llvm.eh.typeid.for` (see #<!-- -->38893).

---

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


5 Files Affected:

- (modified) clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp (+17-18) 
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+4) 
- (added) clang/test/CIR/CodeGenOpenMP/try-catch.cpp (+154) 
- (modified) clang/test/CIR/Transforms/eh-abi-lowering-construct-catch.cir 
(+95-5) 
- (modified) clang/test/CIR/Transforms/eh-abi-lowering-itanium.cir (+47-1) 


``````````diff
diff --git a/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp 
b/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp
index 4b765b1f75fca7..278ac8109e6634 100644
--- a/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp
@@ -145,7 +145,7 @@ class ItaniumEHLowering : public EHABILowering {
   void ensureCxaThrowDecl(mlir::Location loc);
   void ensureCxaRethrowDecl(mlir::Location loc);
   void ensureCxaCallUnexpectedDecl(mlir::Location loc);
-  mlir::Block *buildTerminateBlock(cir::FuncOp funcOp, mlir::Location loc);
+  mlir::Block *buildTerminateBlock(mlir::Region &region, mlir::Location loc);
   mlir::FailureOr<cir::FuncOp>
   resolveCatchCopyThunk(cir::ConstructCatchParamOp op);
   mlir::LogicalResult lowerFunc(cir::FuncOp funcOp);
@@ -301,15 +301,16 @@ void 
ItaniumEHLowering::ensureCxaCallUnexpectedDecl(mlir::Location loc) {
       mod, loc, "__cxa_call_unexpected", unexpectedFuncTy);
 }
 
-/// Create a terminate landing pad block at the end of the specified function.
-mlir::Block *ItaniumEHLowering::buildTerminateBlock(cir::FuncOp funcOp,
+/// Create a terminate landing pad block at the end of \p region of the calls
+/// that unwind the block. Usually that is the function body but can also be
+/// a omp.parallel region nest.
+mlir::Block *ItaniumEHLowering::buildTerminateBlock(mlir::Region &region,
                                                     mlir::Location loc) {
   // TODO(cir): set the runtime calling convention on the runtime calls below.
   assert(!cir::MissingFeatures::opFuncCallingConv());
   assert(clangCallTerminateFunc &&
          "ensureClangCallTerminate must run before buildTerminateBlock");
-  mlir::Region &body = funcOp.getRegion();
-  mlir::Block *terminateBlock = builder.createBlock(&body, body.end());
+  mlir::Block *terminateBlock = builder.createBlock(&region, region.end());
   auto inflight = cir::EhInflightOp::create(
       builder, loc, /*cleanup=*/false, /*catch_all=*/true,
       /*catch_type_list=*/mlir::ArrayAttr{},
@@ -441,13 +442,13 @@ mlir::LogicalResult 
ItaniumEHLowering::lowerFunc(cir::FuncOp funcOp) {
   }
 
   // Remove the !cir.eh_token block arguments that were replaced by (ptr, u32)
-  // pairs. Iterate in reverse to preserve argument indices during removal.
-  for (mlir::Block &block : funcOp.getBody()) {
-    for (int i = block.getNumArguments() - 1; i >= 0; --i) {
-      if (mlir::isa<cir::EhTokenType>(block.getArgument(i).getType()))
-        block.eraseArgument(i);
-    }
-  }
+  // pairs. The landing pads can be in nested regions, so visit every block in
+  // the function recursively.
+  funcOp.walk([](mlir::Block *block) {
+    block->eraseArguments([](mlir::BlockArgument arg) {
+      return mlir::isa<cir::EhTokenType>(arg.getType());
+    });
+  });
 
   // Lower any cir.init_catch_param ops in this function. These materialize
   // the catch parameter local from the (already lowered) begin_catch result,
@@ -898,6 +899,7 @@ 
ItaniumEHLowering::lowerConstructCatchParam(cir::ConstructCatchParamOp op,
       if (!callOp.getNothrow())
         throwingCalls.push_back(callOp);
   }
+  mlir::Region &region = *op->getParentRegion();
   op.erase();
 
   if (throwingCalls.empty())
@@ -905,14 +907,11 @@ 
ItaniumEHLowering::lowerConstructCatchParam(cir::ConstructCatchParamOp op,
 
   // All calls in the copy (which is usually just a single call) need to
   // unwind to a terminate block if it throws an exception.
+  mlir::Block *terminateBlock =
+      buildTerminateBlock(region, throwingCalls.front().getLoc());
   mlir::IRRewriter rewriter(builder);
-  mlir::Block *terminateBlock = nullptr;
-  for (cir::CallOp call : throwingCalls) {
-    if (!terminateBlock)
-      terminateBlock = 
buildTerminateBlock(call->getParentOfType<cir::FuncOp>(),
-                                           call.getLoc());
+  for (cir::CallOp call : throwingCalls)
     cir::replaceCallWithTryCall(call, terminateBlock, call.getLoc(), rewriter);
-  }
   return mlir::success();
 }
 
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 7a1e61b5262642..a19dd4b3069922 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -4927,6 +4927,10 @@ mlir::LogicalResult 
CIRToLLVMResumeFlatOpLowering::matchAndRewrite(
 mlir::LogicalResult CIRToLLVMEhTypeIdOpLowering::matchAndRewrite(
     cir::EhTypeIdOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {
+  if (op->getParentOfType<mlir::omp::ParallelOp>())
+    return op.emitError("catching a specific exception type inside an OpenMP "
+                        "parallel region is not yet implemented");
+
   mlir::Value addrOp = mlir::LLVM::AddressOfOp::create(
       rewriter, op.getLoc(),
       mlir::LLVM::LLVMPointerType::get(rewriter.getContext()),
diff --git a/clang/test/CIR/CodeGenOpenMP/try-catch.cpp 
b/clang/test/CIR/CodeGenOpenMP/try-catch.cpp
new file mode 100644
index 00000000000000..86ee94a1eb16ed
--- /dev/null
+++ b/clang/test/CIR/CodeGenOpenMP/try-catch.cpp
@@ -0,0 +1,154 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp -fcxx-exceptions 
-fexceptions -fclangir -emit-cir %s -o %t.parallel.cir
+// RUN: FileCheck --input-file=%t.parallel.cir %s --check-prefix=PARALLEL-CIR
+// RUN: cir-opt -cir-hoist-allocas -cir-flatten-cfg -cir-eh-abi-lowering 
%t.parallel.cir -o %t.parallel.eh.cir
+// RUN: FileCheck --input-file=%t.parallel.eh.cir %s 
--check-prefix=PARALLEL-EH --implicit-check-not='!cir.eh_token'
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp -fcxx-exceptions 
-fexceptions -fclangir -emit-llvm -DOMIT_PARALLEL_TYPED_CATCH %s -o 
%t.parallel-cir.ll
+// RUN: FileCheck --input-file=%t.parallel-cir.ll %s 
--check-prefix=PARALLEL-LLVM
+// RUN: not %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp 
-fcxx-exceptions -fexceptions -fclangir -emit-llvm %s -o /dev/null 2>&1 | 
FileCheck %s --check-prefix=PARALLEL-TYPED-ERR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp -fcxx-exceptions 
-fexceptions -emit-llvm %s -o %t.parallel.ll
+// RUN: FileCheck --input-file=%t.parallel.ll %s --check-prefix=PARALLEL-OGCG
+
+void mayThrow();
+
+struct MyException {
+  MyException();
+  MyException(const MyException &);
+  ~MyException();
+  int get();
+};
+
+// Test whether landing pads are in the omp.parallel region, not in the 
function body.
+// Also test whether EH ABI lowering performs its lowering within those 
regions.
+
+void catch_all_in_parallel() {
+#pragma omp parallel
+  {
+    try {
+      mayThrow();
+    } catch (...) {
+    }
+  }
+}
+
+// PARALLEL-CIR-LABEL: cir.func {{.*}} @_Z21catch_all_in_parallelv()
+// PARALLEL-CIR:         omp.parallel {
+// PARALLEL-CIR:           cir.try {
+// PARALLEL-CIR:             cir.call @_Z8mayThrowv()
+// PARALLEL-CIR:           } catch all (%{{.*}}: !cir.eh_token {{.*}}) {
+// PARALLEL-CIR:           omp.terminator
+
+// PARALLEL-EH-LABEL: cir.func {{.*}} @_Z21catch_all_in_parallelv()
+// PARALLEL-EH:         omp.parallel {
+// PARALLEL-EH:           cir.try_call @_Z8mayThrowv() ^{{.*}}, 
^[[LPAD:bb[0-9]+]]
+// PARALLEL-EH:         ^[[LPAD]]:
+// PARALLEL-EH:           %[[EXN:.*]], %[[TID:.*]] = cir.eh.inflight_exception 
catch_all
+// PARALLEL-EH:           cir.br ^[[DISPATCH:bb[0-9]+]](%[[EXN]], %[[TID]] : 
!cir.ptr<!void>, !u32i)
+// PARALLEL-EH:         ^[[DISPATCH]](%[[D_EXN:.*]]: !cir.ptr<!void>, 
%[[D_TID:.*]]: !u32i):
+// PARALLEL-EH:           cir.br ^[[CATCH:bb[0-9]+]](%[[D_EXN]], %[[D_TID]] : 
!cir.ptr<!void>, !u32i)
+// PARALLEL-EH:         ^[[CATCH]](%[[C_EXN:.*]]: !cir.ptr<!void>, %{{.*}}: 
!u32i):
+// PARALLEL-EH:           cir.call @__cxa_begin_catch(%[[C_EXN]])
+// PARALLEL-EH:           cir.call @__cxa_end_catch()
+// PARALLEL-EH:           omp.terminator
+// PARALLEL-EH-NEXT:    }
+// PARALLEL-EH-NEXT:    cir.return
+
+// PARALLEL-LLVM-LABEL: define dso_local void @_Z21catch_all_in_parallelv()
+// PARALLEL-LLVM:         call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr 
@{{.*}}, i32 0, ptr @_Z21catch_all_in_parallelv..omp_par)
+
+// PARALLEL-LLVM-LABEL: define internal void 
@_Z21catch_all_in_parallelv..omp_par(
+// PARALLEL-LLVM-SAME:    personality ptr @__gxx_personality_v0
+// PARALLEL-LLVM:         invoke void @_Z8mayThrowv()
+// PARALLEL-LLVM-NEXT:            to label %{{.*}} unwind label %[[LPAD:.*]]
+// PARALLEL-LLVM:       [[LPAD]]:
+// PARALLEL-LLVM-NEXT:    %{{.*}} = landingpad { ptr, i32 }
+// PARALLEL-LLVM-NEXT:            catch ptr null
+// PARALLEL-LLVM:         call ptr @__cxa_begin_catch(ptr %{{.*}})
+// FIXME: Classic CodeGen invokes __cxa_end_catch with a terminate landing pad.
+// PARALLEL-LLVM:         call void @__cxa_end_catch()
+
+// PARALLEL-OGCG-LABEL: define dso_local void @_Z21catch_all_in_parallelv()
+// PARALLEL-OGCG:         call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr 
@{{.*}}, i32 0, ptr @_Z21catch_all_in_parallelv.omp_outlined)
+
+// PARALLEL-OGCG-LABEL: define internal void 
@_Z21catch_all_in_parallelv.omp_outlined(
+// PARALLEL-OGCG-SAME:    personality ptr @__gxx_personality_v0
+// PARALLEL-OGCG:         invoke void @_Z8mayThrowv()
+// PARALLEL-OGCG-NEXT:            to label %{{.*}} unwind label %[[LPAD:.*]]
+// PARALLEL-OGCG:       [[LPAD]]:
+// PARALLEL-OGCG-NEXT:    %{{.*}} = landingpad { ptr, i32 }
+// PARALLEL-OGCG-NEXT:            catch ptr null
+// PARALLEL-OGCG:         call ptr @__cxa_begin_catch(ptr %{{.*}})
+// PARALLEL-OGCG:         invoke void @__cxa_end_catch()
+
+// PARALLEL-TYPED-ERR: try-catch.cpp:[[#@LINE+5]]:5: error: catching a 
specific exception type inside an OpenMP parallel region is not yet implemented
+#ifndef OMIT_PARALLEL_TYPED_CATCH
+void catch_by_copy_in_parallel() {
+#pragma omp parallel
+  {
+    try {
+      mayThrow();
+    } catch (MyException e) {
+    }
+  }
+}
+#endif
+
+// PARALLEL-CIR-LABEL: cir.func {{.*}} @_Z25catch_by_copy_in_parallelv()
+// PARALLEL-CIR:         omp.parallel {
+// PARALLEL-CIR:           %[[E:.*]] = cir.alloca "e"
+// PARALLEL-CIR:           cir.try {
+// PARALLEL-CIR:             cir.call @_Z8mayThrowv()
+// PARALLEL-CIR:           } catch [type #cir.global_view<@_ZTI11MyException> 
: !cir.ptr<!u8i>] (%[[TOK:.*]]: !cir.eh_token {{.*}}) {
+// PARALLEL-CIR:             cir.construct_catch_param non_trivial_copy 
%[[TOK]] to %[[E]] using @__clang_cir_catch_copy__ZTS11MyException
+// PARALLEL-CIR:           } unwind (%[[UTOK:.*]]: !cir.eh_token {{.*}}) {
+// PARALLEL-CIR:             cir.resume %[[UTOK]] : !cir.eh_token
+// PARALLEL-CIR:           omp.terminator
+
+// The copy constructor can throw, so it unwinds to a terminate landing pad,
+// which must be in the omp.parallel region with the call.
+// PARALLEL-EH-LABEL: cir.func {{.*}} @_Z25catch_by_copy_in_parallelv()
+// PARALLEL-EH:         omp.parallel {
+// PARALLEL-EH:           %[[E:.*]] = cir.alloca "e"
+// PARALLEL-EH:           cir.try_call @_Z8mayThrowv() ^{{.*}}, 
^[[LPAD:bb[0-9]+]]
+// PARALLEL-EH:         ^[[LPAD]]:
+// PARALLEL-EH:           %[[EXN:.*]], %[[TID:.*]] = cir.eh.inflight_exception 
[@_ZTI11MyException]
+// PARALLEL-EH:           cir.br ^[[DISPATCH:bb[0-9]+]](%[[EXN]], %[[TID]] : 
!cir.ptr<!void>, !u32i)
+// PARALLEL-EH:         ^[[DISPATCH]](%[[D_EXN:.*]]: !cir.ptr<!void>, 
%[[D_TID:.*]]: !u32i):
+// PARALLEL-EH:           cir.br ^[[CMP:bb[0-9]+]](%[[D_EXN]], %[[D_TID]] : 
!cir.ptr<!void>, !u32i)
+// PARALLEL-EH:         ^[[CMP]](%[[CMP_EXN:.*]]: !cir.ptr<!void>, 
%[[CMP_TID:.*]]: !u32i):
+// PARALLEL-EH:           %[[TYPEID:.*]] = cir.eh.typeid @_ZTI11MyException
+// PARALLEL-EH:           %[[MATCH:.*]] = cir.cmp eq %[[CMP_TID]], %[[TYPEID]] 
: !u32i
+// PARALLEL-EH:           cir.brcond %[[MATCH]] 
^[[CATCH:bb[0-9]+]](%[[CMP_EXN]], %[[CMP_TID]] : !cir.ptr<!void>, !u32i), 
^[[RESUME:bb[0-9]+]](%[[CMP_EXN]], %[[CMP_TID]] : !cir.ptr<!void>, !u32i)
+// PARALLEL-EH:         ^[[CATCH]](%[[C_EXN:.*]]: !cir.ptr<!void>, %{{.*}}: 
!u32i):
+// PARALLEL-EH:           %[[EXN_OBJ:.*]] = cir.call 
@__cxa_get_exception_ptr(%[[C_EXN]]) nothrow
+// PARALLEL-EH:           %[[EXN_E:.*]] = cir.cast bitcast %[[EXN_OBJ]] : 
!cir.ptr<!u8i> -> !cir.ptr<!rec_MyException>
+// PARALLEL-EH:           cir.try_call @_ZN11MyExceptionC1ERKS_(%[[E]], 
%[[EXN_E]]) ^[[COPIED:bb[0-9]+]], ^[[TERMINATE:bb[0-9]+]]
+// PARALLEL-EH:         ^[[COPIED]]:
+// PARALLEL-EH:           cir.call @__cxa_begin_catch(%[[C_EXN]])
+// PARALLEL-EH:           cir.call @_ZN11MyExceptionD1Ev(%[[E]]) nothrow
+// PARALLEL-EH:           cir.call @__cxa_end_catch()
+// FIXME: Classic CodeGen calls __clang_call_terminate for an unmatched
+// exception instead of resuming it out of the parallel region.
+// PARALLEL-EH:         ^[[RESUME]](%[[R_EXN:.*]]: !cir.ptr<!void>, 
%[[R_TID:.*]]: !u32i):
+// PARALLEL-EH:           cir.resume.flat %[[R_EXN]], %[[R_TID]]
+// PARALLEL-EH:           omp.terminator
+// PARALLEL-EH:         ^[[TERMINATE]]:
+// PARALLEL-EH-NEXT:      %[[T_EXN:.*]], %{{.*}} = cir.eh.inflight_exception 
catch_all
+// PARALLEL-EH-NEXT:      cir.call @__clang_call_terminate(%[[T_EXN]]) nothrow 
{noreturn}
+// PARALLEL-EH-NEXT:      cir.unreachable
+// PARALLEL-EH-NEXT:    }
+// PARALLEL-EH-NEXT:    cir.return
+
+// PARALLEL-OGCG-LABEL: define internal void 
@_Z25catch_by_copy_in_parallelv.omp_outlined(
+// PARALLEL-OGCG-SAME:    personality ptr @__gxx_personality_v0
+// PARALLEL-OGCG:         invoke void @_Z8mayThrowv()
+// PARALLEL-OGCG:         landingpad { ptr, i32 }
+// PARALLEL-OGCG-NEXT:            catch ptr @_ZTI11MyException
+// PARALLEL-OGCG-NEXT:            catch ptr null
+// PARALLEL-OGCG:         call ptr @__cxa_get_exception_ptr(ptr %{{.*}})
+// PARALLEL-OGCG:         invoke void @_ZN11MyExceptionC1ERKS_(ptr {{.*}} %e, 
ptr {{.*}})
+// PARALLEL-OGCG-NEXT:            to label %{{.*}} unwind label 
%[[TERMINATE:.*]]
+// PARALLEL-OGCG:       [[TERMINATE]]:
+// PARALLEL-OGCG-NEXT:    %[[T_LP:.*]] = landingpad { ptr, i32 }
+// PARALLEL-OGCG-NEXT:            catch ptr null
+// PARALLEL-OGCG-NEXT:    %[[T_EXN:.*]] = extractvalue { ptr, i32 } %[[T_LP]], 0
+// PARALLEL-OGCG-NEXT:    call void @__clang_call_terminate(ptr %[[T_EXN]])
diff --git a/clang/test/CIR/Transforms/eh-abi-lowering-construct-catch.cir 
b/clang/test/CIR/Transforms/eh-abi-lowering-construct-catch.cir
index 25c8e5695c0d5b..2f422868e890b7 100644
--- a/clang/test/CIR/Transforms/eh-abi-lowering-construct-catch.cir
+++ b/clang/test/CIR/Transforms/eh-abi-lowering-construct-catch.cir
@@ -1,5 +1,5 @@
 // RUN: cir-opt %s -cir-eh-abi-lowering -o %t.cir
-// RUN: FileCheck --input-file=%t.cir %s
+// RUN: FileCheck --input-file=%t.cir %s --implicit-check-not='!cir.eh_token'
 
 // Test the Itanium ABI lowering of cir.construct_catch_param.
 //
@@ -13,8 +13,8 @@
 //     thunk's body in place; any potentially-throwing `cir.call` becomes a
 //     `cir.try_call` whose unwind path runs `__clang_call_terminate`
 //     (Itanium's terminate scope around the catch-parameter copy). The
-//     terminate block is appended at the end of the function as a cold
-//     landing pad.
+//     terminate block is appended at the end of the enclosing region (the
+//     function body here) as a cold landing pad.
 //   - Drop any catch-copy thunks that end up uncalled after lowering.
 
 !s8i = !cir.int<s, 8>
@@ -111,8 +111,8 @@ cir.func @test_basic_construct_catch() {
 // CHECK:       ^[[RETURN]]:
 // CHECK:         cir.return
 //
-// Terminate scope appended at the end of the function: control reaches it
-// only if the catch-parameter copy throws.
+// Terminate scope appended at the end of the enclosing region, here the
+// function body: control reaches it only if the catch-parameter copy throws.
 // CHECK:       ^[[TERMINATE]]:
 // CHECK:         %[[T_EXN:.*]], %{{.*}} = cir.eh.inflight_exception catch_all
 // CHECK:         cir.call @__clang_call_terminate(%[[T_EXN]]){{.*}}noreturn
@@ -206,6 +206,96 @@ cir.func linkonce_odr hidden 
@__clang_cir_catch_copy__ZTS1E_unused(
   cir.return
 }
 
+//===----------------------------------------------------------------------===//
+// Case 4: catch (E) with a throwing copy in the function body and in a nested
+// omp.parallel region.
+//===----------------------------------------------------------------------===//
+
+cir.func @test_catch_copy_in_body_and_parallel() {
+  %0 = cir.alloca "e" align(1) : !cir.ptr<!rec_E>
+  cir.try_call @_Z8mayThrowv() ^bb1, ^bb2 : () -> ()
+^bb1:
+  cir.br ^bb6
+^bb2:
+  %1 = cir.eh.initiate : !cir.eh_token
+  cir.br ^bb3(%1 : !cir.eh_token)
+^bb3(%eh_token: !cir.eh_token):
+  cir.eh.dispatch %eh_token : !cir.eh_token [
+    catch(#cir.global_view<@_ZTI1E> : !cir.ptr<!u8i>) : ^bb4,
+    unwind : ^bb5
+  ]
+^bb4(%eh_token.1: !cir.eh_token):
+  cir.construct_catch_param non_trivial_copy %eh_token.1 to %0
+      using @__clang_cir_catch_copy__ZTS1E : !cir.ptr<!rec_E>
+  %ct, %exn = cir.begin_catch %eh_token.1
+      : !cir.eh_token -> (!cir.catch_token, !cir.ptr<!void>)
+  cir.call @_ZN1ED1Ev(%0) nothrow : (!cir.ptr<!rec_E>) -> ()
+  cir.end_catch %ct : !cir.catch_token
+  cir.br ^bb6
+^bb5(%eh_token.2: !cir.eh_token):
+  cir.resume %eh_token.2 : !cir.eh_token
+^bb6:
+  omp.parallel {
+    %2 = cir.alloca "e" align(1) : !cir.ptr<!rec_E>
+    cir.try_call @_Z8mayThrowv() ^bb1, ^bb2 : () -> ()
+  ^bb1:
+    cir.br ^bb6
+  ^bb2:
+    %3 = cir.eh.initiate : !cir.eh_token
+    cir.br ^bb3(%3 : !cir.eh_token)
+  ^bb3(%eh_token.3: !cir.eh_token):
+    cir.eh.dispatch %eh_token.3 : !cir.eh_token [
+      catch(#cir.global_view<@_ZTI1E> : !cir.ptr<!u8i>) : ^bb4,
+      unwind : ^bb5
+    ]
+  ^bb4(%eh_token.4: !cir.eh_token):
+    cir.construct_catch_param non_trivial_copy %eh_token.4 to %2
+        using @__clang_cir_catch_copy__ZTS1E : !cir.ptr<!rec_E>
+    %ct.1, %exn.1 = cir.begin_catch %eh_token.4
+        : !cir.eh_token -> (!cir.catch_token, !cir.ptr<!void>)
+    cir.call @_ZN1ED1Ev(%2) nothrow : (!cir.ptr<!rec_E>) -> ()
+    cir.end_catch %ct.1 : !cir.catch_token
+    cir.br ^bb6
+  ^bb5(%eh_token.5: !cir.eh_token):
+    cir.resume %eh_token.5 : !cir.eh_token
+  ^bb6:
+    omp.terminator
+  }
+  cir.return
+}
+
+// CHECK-LABEL: cir.func @test_catch_copy_in_body_and_parallel()
+// CHECK-SAME:    personality(@__gxx_personality_v0)
+// CHECK:         %[[E:.*]] = cir.alloca "e"
+// CHECK:         cir.try_call @_Z8mayThrowv() ^{{bb[0-9]+}}, 
^[[UNWIND:bb[0-9]+]]
+// CHECK:       ^[[UNWIND]]:
+// CHECK:         cir.eh.inflight_exception [@_ZTI1E]
+// CHECK:         cir.call @__cxa_get_exception_ptr
+// CHECK:         cir.try_call @_ZN1EC1ERKS_(%[[E]], %{{.*}}) ^{{bb[0-9]+}}, 
^[[TERMINATE:bb[0-9]+]]
+// CHECK:         cir.resume.flat
+//
+// CHECK:         omp.parallel {
+// CHECK:           %[[P_E:.*]] = cir.alloca "e"
+// CHECK:           cir.try_call @_Z8mayThrowv() ^{{bb[0-9]+}}, 
^[[P_UNWIND:bb[0-9]+]]
+// CHECK:         ^[[P_UNWIND]]:
+// CHECK:           cir.eh.inflight_exception [@_ZTI1E]
+// CHECK:           cir.call @__cxa_get_exception_ptr
+// CHECK:           cir.try_call @_ZN1EC1ERKS_(%[[P_E]], %{{.*}}) 
^{{bb[0-9]+}}, ^[[P_TERMINATE:bb[0-9]+]]
+// CHECK:           cir.resume.flat
+// CHECK:           omp.terminator
+// CHECK:         ^[[P_TERMINATE]]:
+// CHECK-NEXT:      %[[P_T_EXN:.*]], %{{.*}} = cir.eh.inflight_exception 
catch_all
+// CHECK-NEXT:      cir.call @__clang_call_terminate(%[[P_T_EXN]]) nothrow 
{noreturn}
+// CHECK-NEXT:      cir.unreachable
+// CHECK-NEXT:    }
+// CHECK-NEXT:    cir.return
+//
+// CHECK:       ^[[TERMINATE]]:
+// CHECK-NEXT:    %[[T_EXN:.*]], %{{.*}} = cir.eh.inflight_exception catch_all
+// CHECK-NEXT:    cir.call @__clang_call_terminate(%[[T_EXN]]) nothrow 
{noreturn}
+// CHECK-NEXT:    cir.unreachable
+// CHECK-NEXT:  }
+
 // All three catch-copy thunks above (basic, shared, unused) are unreferenced
 // after inlining and must be erased by the lowering pass.
 // CHECK-NOT: cir.eh.catch_copy_thunk
diff --git a/clang/test/CIR/Transforms/eh-abi-lowering-itanium.cir 
b/clang/test/CIR/Transforms/eh-abi-lowering-itanium.cir
index 06bae1fbdc5bcc..ba230250c18cc3 100644
--- a/clang/test/CIR/Transforms/eh-abi-lowering-itanium.cir
+++ b/clang/test/CIR/Transforms/eh-abi-lowering-itanium.cir
@@ -1,5 +1,5 @@
 // RUN: cir-opt %s -cir-eh-abi-lowering -o %t.cir
-// RUN: FileCheck --input-file=%t.cir %s
+// RUN: FileCheck --input-file=%t.cir %s --implicit-check-not='!cir.eh_token'
 
 // Test Itanium ABI lowering of flattened CIR exception handling operations.
 // The input is the f...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/230509
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to