https://github.com/AmrDeveloper created 
https://github.com/llvm/llvm-project/pull/190612

Change the design of BeginCatchOp to be target-independent and handle the 
target-specific lowering in the EHLowering pass

>From 46f455b7aadeec287ae5b31f213bb920f1bcaad2 Mon Sep 17 00:00:00 2001
From: Amr Hesham <[email protected]>
Date: Mon, 6 Apr 2026 15:57:11 +0200
Subject: [PATCH] [CIR] Make BeginCatch target-independent

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 22 +++--
 clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp | 74 +++++------------
 .../CIR/Dialect/Transforms/EHABILowering.cpp  | 81 +++++++++++++++++--
 .../CodeGen/try-catch-all-with-cleanup.cpp    | 16 ++--
 clang/test/CIR/CodeGen/try-catch.cpp          | 65 ++++++---------
 clang/test/CIR/IR/catch-param.cir             |  4 +-
 clang/test/CIR/IR/eh-flat.cir                 | 20 +++--
 clang/test/CIR/IR/try-catch.cir               | 16 ++--
 8 files changed, 165 insertions(+), 133 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index f72d891ecd941..7c67c87540a59 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -7236,6 +7236,14 @@ def CIR_EndCleanupOp : CIR_Op<"end_cleanup"> {
 // EH Operations: BeginCatchOp
 
//===----------------------------------------------------------------------===//
 
+def CIR_BeginCatchKind : CIR_I32EnumAttr<"BeginCatchKind", "beginCatchKind", [
+    I32EnumAttrCase<"Default", 0, "default">,
+    I32EnumAttrCase<"LoadStore", 1, "load_store">,
+    I32EnumAttrCase<"Store", 2, "store">,
+    I32EnumAttrCase<"Memcopy", 3, "memcopy">,
+    I32EnumAttrCase<"Reference", 4, "reference">,
+]>;
+
 def CIR_BeginCatchOp : CIR_Op<"begin_catch"> {
   let summary = "Begin a catch handler";
   let description = [{
@@ -7283,13 +7291,17 @@ def CIR_BeginCatchOp : CIR_Op<"begin_catch"> {
     ```
   }];
 
-  let arguments = (ins CIR_EhTokenType:$eh_token);
-  let results = (outs CIR_CatchTokenType:$catch_token,
-                      CIR_PointerType:$exn_ptr);
+  let arguments = (ins
+      CIR_EhTokenType:$eh_token,
+      Optional<CIR_PointerType>:$exn_ptr,
+      CIR_BeginCatchKind:$kind
+  );
+
+  let results = (outs CIR_CatchTokenType:$catch_token);
 
   let assemblyFormat = [{
-    $eh_token `:` type($eh_token) `->` `(` type($catch_token) `,`
-       qualified(type($exn_ptr)) `)` attr-dict
+    $kind $eh_token `:` type($eh_token) (`,` $exn_ptr^ `:` 
qualified(type($exn_ptr)))?
+      `->` type($catch_token) attr-dict
   }];
 
   let hasLLVMLowering = false;
diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp 
b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
index 75658b23790bf..471c48da8d2b8 100644
--- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
@@ -2523,12 +2523,14 @@ struct CallEndCatch final : EHScopeStack::Cleanup {
 };
 } // namespace
 
-static mlir::Value callBeginCatch(CIRGenFunction &cgf, mlir::Value ehToken,
-                                  mlir::Type exnPtrTy, bool endMightThrow) {
+static mlir::Value
+callBeginCatch(CIRGenFunction &cgf, mlir::Value ehToken, mlir::Value exnPtr,
+               mlir::Type exnPtrTy, bool endMightThrow,
+               cir::BeginCatchKind kind = cir::BeginCatchKind::Default) {
   auto catchTokenTy = cir::CatchTokenType::get(cgf.getBuilder().getContext());
-  auto beginCatch = cir::BeginCatchOp::create(cgf.getBuilder(),
-                                              cgf.getBuilder().getUnknownLoc(),
-                                              catchTokenTy, exnPtrTy, ehToken);
+  auto beginCatch = cir::BeginCatchOp::create(
+      cgf.getBuilder(), cgf.getBuilder().getUnknownLoc(), catchTokenTy, 
ehToken,
+      exnPtr, kind);
 
   cgf.ehStack.pushCleanup<CallEndCatch>(
       NormalAndEHCleanup,
@@ -2553,8 +2555,8 @@ static void initCatchParam(CIRGenFunction &cgf, 
mlir::Value ehToken,
     QualType caughtType = cast<ReferenceType>(catchType)->getPointeeType();
     bool endCatchMightThrow = caughtType->isRecordType();
 
-    mlir::Value adjustedExn =
-        callBeginCatch(cgf, ehToken, cirCatchTy, endCatchMightThrow);
+    callBeginCatch(cgf, ehToken, paramAddr.getPointer(), cirCatchTy,
+                   endCatchMightThrow, cir::BeginCatchKind::Reference);
 
     // We have no way to tell the personality function that we're
     // catching by reference, so if we're catching a pointer,
@@ -2566,24 +2568,8 @@ static void initCatchParam(CIRGenFunction &cgf, 
mlir::Value ehToken,
       if (!pointeeType->isRecordType()) {
         cgf.cgm.errorNYI(loc,
                          "initCatchParam: catching a pointer of non-record");
-      } else {
-        // Pull the pointer for the reference type off.
-        mlir::Type ptrTy = cgf.convertTypeForMem(caughtType);
-
-        // Create the temporary and write the adjusted pointer into it.
-        Address exnPtrTmp = cgf.createTempAlloca(
-            ptrTy, cgf.getPointerAlign(), cgf.getLoc(loc), "exn.byref.tmp");
-        mlir::Value casted = cgf.getBuilder().createBitcast(adjustedExn, 
ptrTy);
-        cgf.getBuilder().createStore(cgf.getLoc(loc), casted, exnPtrTmp);
-
-        // Bind the reference to the temporary.
-        adjustedExn = exnPtrTmp.emitRawPointer();
       }
     }
-
-    mlir::Value exnCast =
-        cgf.getBuilder().createBitcast(adjustedExn, cirCatchTy);
-    cgf.getBuilder().createStore(cgf.getLoc(loc), exnCast, paramAddr);
     return;
   }
 
@@ -2594,8 +2580,8 @@ static void initCatchParam(CIRGenFunction &cgf, 
mlir::Value ehToken,
     // If the catch type is a pointer type, __cxa_begin_catch returns
     // the pointer by value.
     if (catchType->hasPointerRepresentation()) {
-      mlir::Value catchParam =
-          callBeginCatch(cgf, ehToken, cirCatchTy, /*endMightThrow=*/false);
+      callBeginCatch(cgf, ehToken, paramAddr.getPointer(), cirCatchTy,
+                     /*endMightThrow=*/false, cir::BeginCatchKind::Store);
       switch (catchType.getQualifiers().getObjCLifetime()) {
       case Qualifiers::OCL_Strong:
         cgf.cgm.errorNYI(loc,
@@ -2609,7 +2595,6 @@ static void initCatchParam(CIRGenFunction &cgf, 
mlir::Value ehToken,
         return;
 
       case Qualifiers::OCL_None:
-        cgf.getBuilder().createStore(cgf.getLoc(loc), catchParam, paramAddr);
         return;
 
       case Qualifiers::OCL_Weak:
@@ -2622,44 +2607,21 @@ static void initCatchParam(CIRGenFunction &cgf, 
mlir::Value ehToken,
 
     // Otherwise, it returns a pointer into the exception object.
     mlir::Type cirCatchTy = cgf.convertTypeForMem(catchType);
-    mlir::Value catchParam =
-        callBeginCatch(cgf, ehToken, cgf.getBuilder().getPointerTo(cirCatchTy),
-                       /*endMightThrow=*/false);
-    LValue srcLV = cgf.makeNaturalAlignAddrLValue(catchParam, catchType);
-    LValue destLV = cgf.makeAddrLValue(paramAddr, catchType);
-    switch (tek) {
-    case cir::TEK_Complex: {
-      mlir::Value load = cgf.emitLoadOfComplex(srcLV, loc);
-      cgf.emitStoreOfComplex(cgf.getLoc(loc), load, destLV, /*isInit=*/true);
-      return;
-    }
-    case cir::TEK_Scalar: {
-      mlir::Value exnLoad = cgf.emitLoadOfScalar(srcLV, loc);
-      cgf.emitStoreOfScalar(exnLoad, destLV, /*isInit=*/true);
-      return;
-    }
-    case cir::TEK_Aggregate:
-      llvm_unreachable("evaluation kind filtered out!");
-    }
-
-    llvm_unreachable("bad evaluation kind");
+    callBeginCatch(cgf, ehToken, paramAddr.getPointer(),
+                   cgf.getBuilder().getPointerTo(cirCatchTy),
+                   /*endMightThrow=*/false, cir::BeginCatchKind::LoadStore);
+    return;
   }
 
   assert(isa<RecordType>(catchType) && "unexpected catch type!");
-  auto *catchRD = catchType->getAsCXXRecordDecl();
-  CharUnits caughtExnAlignment = cgf.cgm.getClassPointerAlignment(catchRD);
 
   // Check for a copy expression.  If we don't have a copy expression,
   // that means a trivial copy is okay.
   const Expr *copyExpr = catchParam.getInit();
   if (!copyExpr) {
     mlir::Type cirCatchPtrTy = cgf.getBuilder().getPointerTo(cirCatchTy);
-    mlir::Value rawAdjustedExn =
-        callBeginCatch(cgf, ehToken, cirCatchPtrTy, /*endMightThrow=*/true);
-    Address adjustedExn(rawAdjustedExn, cirCatchTy, caughtExnAlignment);
-    LValue dest = cgf.makeAddrLValue(paramAddr, catchType);
-    LValue src = cgf.makeAddrLValue(adjustedExn, catchType);
-    cgf.emitAggregateCopy(dest, src, catchType, AggValueSlot::DoesNotOverlap);
+    callBeginCatch(cgf, ehToken, paramAddr.getPointer(), cirCatchPtrTy,
+                   /*endMightThrow=*/true, cir::BeginCatchKind::Memcopy);
     return;
   }
 
@@ -2696,7 +2658,7 @@ void CIRGenItaniumCXXABI::emitBeginCatch(CIRGenFunction 
&cgf,
 
   VarDecl *catchParam = catchStmt->getExceptionDecl();
   if (!catchParam) {
-    callBeginCatch(cgf, ehToken, cgf.getBuilder().getVoidPtrTy(),
+    callBeginCatch(cgf, ehToken, {}, cgf.getBuilder().getVoidPtrTy(),
                    /*endMightThrow=*/true);
     return;
   }
diff --git a/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp 
b/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp
index abdc32951f857..771203213dc49 100644
--- a/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/EHABILowering.cpp
@@ -395,13 +395,82 @@ void ItaniumEHLowering::lowerEhInitiate(
             builder, op.getLoc(), mlir::FlatSymbolRefAttr::get(beginCatchFunc),
             u8PtrType, mlir::ValueRange{exnPtr});
         mlir::Value castResult = callOp.getResult();
-        mlir::Type expectedPtrType = op.getExnPtr().getType();
-        if (castResult.getType() != expectedPtrType)
-          castResult =
-              cir::CastOp::create(builder, op.getLoc(), expectedPtrType,
-                                  cir::CastKind::bitcast, callOp.getResult());
-        op.getExnPtr().replaceAllUsesWith(castResult);
+
+        mlir::TypedValue<cir::PointerType> exnPtrAddr = op.getExnPtr();
+        if (exnPtrAddr) {
+          mlir::Type expectedPtrType = op.getExnPtr().getType();
+          if (castResult.getType() != expectedPtrType)
+            castResult =
+                cir::CastOp::create(builder, op.getLoc(), expectedPtrType,
+                                    cir::CastKind::bitcast, 
callOp.getResult());
+          op.getExnPtr().replaceAllUsesWith(castResult);
+
+          switch (op.getKind()) {
+          case cir::BeginCatchKind::LoadStore: {
+            auto loadExnPtr =
+                cir::LoadOp::create(builder, op->getLoc(), castResult);
+            cir::StoreOp::create(builder, op.getLoc(), loadExnPtr, exnPtrAddr,
+                                 {}, {}, {}, {});
+            break;
+          }
+          case cir::BeginCatchKind::Store: {
+            mlir::Type exceptionType =
+                mlir::cast<cir::PointerType>(expectedPtrType).getPointee();
+            castResult =
+                cir::CastOp::create(builder, op.getLoc(), exceptionType,
+                                    cir::CastKind::bitcast, 
callOp.getResult());
+            cir::StoreOp::create(builder, op.getLoc(), castResult, exnPtrAddr,
+                                 {}, {}, {}, {});
+            break;
+          }
+          case cir::BeginCatchKind::Memcopy: {
+            cir::CopyOp::create(builder, op->getLoc(), exnPtrAddr, castResult);
+            break;
+          }
+          case cir::BeginCatchKind::Reference: {
+            mlir::Type exceptionType =
+                mlir::cast<cir::PointerType>(expectedPtrType).getPointee();
+            mlir::Type exceptionTypePointee =
+                mlir::cast<cir::PointerType>(exceptionType).getPointee();
+            bool isPointer = mlir::isa<cir::PointerType>(exceptionTypePointee);
+            if (isPointer) {
+              cir::FuncOp parentFunc = op->getParentOfType<cir::FuncOp>();
+              mlir::Block *entryBlock = &parentFunc.getRegion().front();
+
+              mlir::Value exnPtrTmp;
+              {
+                mlir::OpBuilder::InsertionGuard guard(builder);
+                builder.setInsertionPointToStart(entryBlock);
+                exnPtrTmp = cir::AllocaOp::create(
+                    builder, op->getLoc(), expectedPtrType, exceptionType,
+                    "exn.byref.tmp", builder.getI64IntegerAttr(8));
+              }
+
+              castResult = cir::CastOp::create(
+                  builder, op.getLoc(), exceptionType, cir::CastKind::bitcast,
+                  callOp.getResult());
+
+              cir::StoreOp::create(builder, op.getLoc(), castResult, exnPtrTmp,
+                                   {}, {}, {}, {});
+
+              castResult = exnPtrTmp;
+            }
+
+            castResult =
+                cir::CastOp::create(builder, op.getLoc(), exceptionType,
+                                    cir::CastKind::bitcast, castResult);
+            cir::StoreOp::create(builder, op.getLoc(), castResult, exnPtrAddr,
+                                 {}, {}, {}, {});
+            break;
+          }
+          case cir::BeginCatchKind::Default: {
+            break;
+          }
+          }
+        }
+
         op.erase();
+        // Extra load and store
       } else if (auto op = mlir::dyn_cast<cir::EhDispatchOp>(user)) {
         // Read catch types from the dispatch and set them on the inflight op.
         mlir::ArrayAttr catchTypes = op.getCatchTypesAttr();
diff --git a/clang/test/CIR/CodeGen/try-catch-all-with-cleanup.cpp 
b/clang/test/CIR/CodeGen/try-catch-all-with-cleanup.cpp
index 3827275bfc1be..2e93d096237af 100644
--- a/clang/test/CIR/CodeGen/try-catch-all-with-cleanup.cpp
+++ b/clang/test/CIR/CodeGen/try-catch-all-with-cleanup.cpp
@@ -36,7 +36,7 @@ void test_catch_all_with_cleanup() {
 // CIR:       }
 // CIR:       cir.yield
 // CIR:     } catch all (%{{.*}}: !cir.eh_token {{.*}}) {
-// CIR:       %{{.*}}, %{{.*}} = cir.begin_catch
+// CIR:       %{{.*}} = cir.begin_catch
 // CIR:       cir.cleanup.scope {
 // CIR:         cir.yield
 // CIR:       } cleanup all {
@@ -88,7 +88,7 @@ void test_catch_all_with_cleanup() {
 //
 // Catch handler.
 // CIR-FLAT:       ^[[CATCH_ALL]](%[[CA_ET:.*]]: !cir.eh_token):
-// CIR-FLAT:         %{{.*}}, %{{.*}} = cir.begin_catch %[[CA_ET]]
+// CIR-FLAT:         %{{.*}} = cir.begin_catch default %[[CA_ET]]
 // CIR-FLAT:         cir.end_catch
 // CIR-FLAT:         cir.return
 
@@ -161,10 +161,8 @@ void test_catch_all_and_specific_with_cleanup() {
 // CIR:       }
 // CIR:       cir.yield
 // CIR:     } catch [type #cir.global_view<@_ZTIi> : !cir.ptr<!u8i>] (%{{.*}}: 
!cir.eh_token {{.*}}) {
-// CIR:       %{{.*}}, %[[EXN:.*]] = cir.begin_catch %{{.*}} : !cir.eh_token 
-> (!cir.catch_token, !cir.ptr<!s32i>)
+// CIR:       %{{.*}} = cir.begin_catch load_store %{{.*}} : !cir.eh_token, 
%[[E]] : !cir.ptr<!s32i> -> !cir.catch_token
 // CIR:       cir.cleanup.scope {
-// CIR:         cir.load{{.*}} %[[EXN]] : !cir.ptr<!s32i>, !s32i
-// CIR:         cir.store{{.*}} %{{.*}}, %[[E]] : !s32i, !cir.ptr<!s32i>
 // CIR:         cir.yield
 // CIR:       } cleanup all {
 // CIR:         cir.end_catch %{{.*}} : !cir.catch_token
@@ -172,7 +170,7 @@ void test_catch_all_and_specific_with_cleanup() {
 // CIR:       }
 // CIR:       cir.yield
 // CIR:     } catch all (%{{.*}}: !cir.eh_token {{.*}}) {
-// CIR:       %{{.*}}, %{{.*}} = cir.begin_catch %{{.*}} : !cir.eh_token -> 
(!cir.catch_token, !cir.ptr<!void>)
+// CIR:       %{{.*}} = cir.begin_catch default %{{.*}} : !cir.eh_token -> 
!cir.catch_token
 // CIR:       cir.cleanup.scope {
 // CIR:         cir.yield
 // CIR:       } cleanup all {
@@ -226,15 +224,13 @@ void test_catch_all_and_specific_with_cleanup() {
 //
 // Catch (int): bind e, end_catch, merge to return.
 // CIR-FLAT:       ^[[CATCH_INT]](%{{.*}}: !cir.eh_token):
-// CIR-FLAT:         %{{.*}}, %[[EXN_PTR:.*]] = cir.begin_catch %{{.*}} : 
!cir.eh_token -> (!cir.catch_token, !cir.ptr<!s32i>)
-// CIR-FLAT:         cir.load{{.*}} %[[EXN_PTR]] : !cir.ptr<!s32i>, !s32i
-// CIR-FLAT:         cir.store{{.*}} %{{.*}}, %[[E]] : !s32i, !cir.ptr<!s32i>
+// CIR-FLAT:         %{{.*}}= cir.begin_catch load_store %{{.*}} : 
!cir.eh_token, %[[E]] : !cir.ptr<!s32i> -> !cir.catch_token
 // CIR-FLAT:         cir.end_catch %{{.*}} : !cir.catch_token
 // CIR-FLAT:         cir.br ^{{.*}}
 //
 // Catch-all handler.
 // CIR-FLAT:       ^[[CATCH_ALL]](%[[CA_ET:.*]]: !cir.eh_token):
-// CIR-FLAT:         %{{.*}}, %{{.*}} = cir.begin_catch %[[CA_ET]]
+// CIR-FLAT:         %{{.*}} = cir.begin_catch default %[[CA_ET]]
 // CIR-FLAT:         cir.br ^{{.*}}
 // CIR-FLAT:         cir.end_catch %{{.*}} : !cir.catch_token
 // CIR-FLAT:         cir.br ^{{.*}}
diff --git a/clang/test/CIR/CodeGen/try-catch.cpp 
b/clang/test/CIR/CodeGen/try-catch.cpp
index fd8b9294c9f92..1679a75ffe476 100644
--- a/clang/test/CIR/CodeGen/try-catch.cpp
+++ b/clang/test/CIR/CodeGen/try-catch.cpp
@@ -210,7 +210,7 @@ void call_function_inside_try_catch_all() {
 // CIR:       %[[CALL:.*]] = cir.call @_Z8divisionv()
 // CIR:       cir.yield
 // CIR:   } catch all (%[[EH_TOKEN:.*]]: !cir.eh_token{{.*}}) {
-// CIR:       %[[CATCH_TOKEN:.*]], %[[EXN_PTR:.*]] = cir.begin_catch 
%[[EH_TOKEN]] : !cir.eh_token -> (!cir.catch_token, !cir.ptr<!void>)
+// CIR:       %[[CATCH_TOKEN:.*]] = cir.begin_catch default %[[EH_TOKEN]] : 
!cir.eh_token -> !cir.catch_token
 // CIR:       cir.cleanup.scope {
 // CIR:         cir.yield
 // CIR:       } cleanup {{.*}} {
@@ -296,10 +296,8 @@ void call_function_inside_try_catch_with_exception_type() {
 // CIR:     %[[CALL:.*]] = cir.call @_Z8divisionv()
 // CIR:     cir.yield
 // CIR:   } catch [type #cir.global_view<@_ZTIi> : !cir.ptr<!u8i>] 
(%[[EH_TOKEN:.*]]: !cir.eh_token{{.*}}) {
-// CIR:     %[[CATCH_TOKEN:.*]], %[[EXN_PTR:.*]] = cir.begin_catch 
%[[EH_TOKEN]] : !cir.eh_token -> (!cir.catch_token, !cir.ptr<!s32i>)
+// CIR:     %[[CATCH_TOKEN:.*]] = cir.begin_catch load_store %[[EH_TOKEN]] : 
!cir.eh_token, %[[EXCEPTION_ADDR]] : !cir.ptr<!s32i> -> !cir.catch_token
 // CIR:     cir.cleanup.scope {
-// CIR:       %[[TMP:.*]] = cir.load {{.*}} %[[EXN_PTR]] : !cir.ptr<!s32i>, 
!s32i
-// CIR:       cir.store {{.*}} %[[TMP]], %[[EXCEPTION_ADDR]] : !s32i, 
!cir.ptr<!s32i>
 // CIR:       cir.yield
 // CIR:     } cleanup {{.*}} {
 // CIR:       cir.end_catch %[[CATCH_TOKEN]] : !cir.catch_token
@@ -340,10 +338,10 @@ void call_function_inside_try_catch_with_exception_type() 
{
 // LLVM:   %[[EXN_OBJ_PHI2:.*]] = phi ptr [ %[[EXN_OBJ_PHI1:.*]], 
%[[DISPATCH:.*]] ]
 // LLVM:   %[[EH_SELECTOR_PHI2:.*]] = phi i32 [ %[[EH_SELECTOR_PHI1:.*]], 
%[[DISPATCH:.*]] ]
 // LLVM:   %[[TOKEN:.*]] = call ptr @__cxa_begin_catch(ptr %[[EXN_OBJ_PHI2]])
-// LLVM:   br label %[[CATCH_BODY:.*]]
-// LLVM: [[CATCH_BODY]]:
 // LLVM:   %[[LOAD:.*]] = load i32, ptr %[[TOKEN]], align 4
 // LLVM:   store i32 %[[LOAD]], ptr {{.*}}, align 4
+// LLVM:   br label %[[CATCH_BODY:.*]]
+// LLVM: [[CATCH_BODY]]:
 // LLVM:   br label %[[END_CATCH:.*]]
 // LLVM: [[END_CATCH]]:
 // LLVM:   call void @__cxa_end_catch()
@@ -414,9 +412,8 @@ void 
call_function_inside_try_catch_with_ref_exception_type() {
 // CIR:     %[[CALL:.*]] = cir.call @_Z8divisionv()
 // CIR:     cir.yield
 // CIR:   } catch [type #cir.global_view<@_ZTIi> : !cir.ptr<!u8i>] (%{{.*}}: 
!cir.eh_token {{.*}}) {
-// CIR:     %[[CATCH_TOKEN:.*]], %[[EXN_PTR:.*]] = cir.begin_catch %{{.*}} : 
!cir.eh_token -> (!cir.catch_token, !cir.ptr<!s32i>)
+// CIR:     %[[CATCH_TOKEN:.*]] = cir.begin_catch reference %{{.*}} : 
!cir.eh_token, %[[EXCEPTION_ADDR]] : !cir.ptr<!cir.ptr<!s32i>> -> 
!cir.catch_token
 // CIR:     cir.cleanup.scope {
-// CIR:       cir.store {{.*}} %[[EXN_PTR]], %[[EXCEPTION_ADDR]] : 
!cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
 // CIR:       cir.yield
 // CIR:     } cleanup all {
 // CIR:       cir.end_catch %[[CATCH_TOKEN]] : !cir.catch_token
@@ -457,9 +454,9 @@ void 
call_function_inside_try_catch_with_ref_exception_type() {
 // LLVM:   %[[EXN_OBJ_PHI2:.*]] = phi ptr [ %[[EXN_OBJ_PHI1:.*]], 
%[[DISPATCH:.*]] ]
 // LLVM:   %[[EH_SELECTOR_PHI2:.*]] = phi i32 [ %[[EH_SELECTOR_PHI1:.*]], 
%[[DISPATCH:.*]] ]
 // LLVM:   %[[TOKEN:.*]] = call ptr @__cxa_begin_catch(ptr %[[EXN_OBJ_PHI2]])
+// LLVM:   store ptr %[[TOKEN]], ptr %{{.*}}, align 8
 // LLVM:   br label %[[CATCH_BODY:.*]]
 // LLVM: [[CATCH_BODY]]:
-// LLVM:   store ptr %[[TOKEN]], ptr %{{.*}}, align 8
 // LLVM:   br label %[[END_CATCH:.*]]
 // LLVM: [[END_CATCH]]:
 // LLVM:   call void @__cxa_end_catch()
@@ -529,10 +526,8 @@ void 
call_function_inside_try_catch_with_complex_exception_type() {
 // CIR:     %[[CALL:.*]] = cir.call @_Z8divisionv()
 // CIR:     cir.yield
 // CIR:   } catch [type #cir.global_view<@_ZTICi> : !cir.ptr<!u8i>] 
(%[[EH_TOKEN:.*]]: !cir.eh_token{{.*}}) {
-// CIR:     %[[CATCH_TOKEN:.*]], %[[EXN_PTR:.*]] = cir.begin_catch 
%[[EH_TOKEN]] : !cir.eh_token -> (!cir.catch_token, 
!cir.ptr<!cir.complex<!s32i>>)
+// CIR:     %[[CATCH_TOKEN:.*]] = cir.begin_catch load_store %[[EH_TOKEN]] : 
!cir.eh_token, %[[EXCEPTION_ADDR]] : !cir.ptr<!cir.complex<!s32i>> -> 
!cir.catch_token
 // CIR:     cir.cleanup.scope {
-// CIR:       %[[TMP:.*]] = cir.load {{.*}} %[[EXN_PTR]] : 
!cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
-// CIR:       cir.store {{.*}} %[[TMP]], %[[EXCEPTION_ADDR]] : 
!cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>
 // CIR:       cir.yield
 // CIR:     } cleanup {{.*}} {
 // CIR:       cir.end_catch %[[CATCH_TOKEN]] : !cir.catch_token
@@ -573,10 +568,10 @@ void 
call_function_inside_try_catch_with_complex_exception_type() {
 // LLVM:   %[[EXN_OBJ_PHI2:.*]] = phi ptr [ %[[EXN_OBJ_PHI1:.*]], 
%[[DISPATCH:.*]] ]
 // LLVM:   %[[EH_SELECTOR_PHI2:.*]] = phi i32 [ %[[EH_SELECTOR_PHI1:.*]], 
%[[DISPATCH:.*]] ]
 // LLVM:   %[[TOKEN:.*]] = call ptr @__cxa_begin_catch(ptr %[[EXN_OBJ_PHI2]])
-// LLVM:   br label %[[CATCH_BODY:.*]]
-// LLVM: [[CATCH_BODY]]:
 // LLVM:   %[[LOAD:.*]] = load { i32, i32 }, ptr %[[TOKEN]], align 4
 // LLVM:   store { i32, i32 } %[[LOAD]], ptr {{.*}}, align 4
+// LLVM:   br label %[[CATCH_BODY:.*]]
+// LLVM: [[CATCH_BODY]]:
 // LLVM:   br label %[[END_CATCH:.*]]
 // LLVM: [[END_CATCH]]:
 // LLVM:   call void @__cxa_end_catch()
@@ -653,9 +648,8 @@ void 
call_function_inside_try_catch_with_array_exception_type() {
 // CIR:     %[[CALL:.*]] = cir.call @_Z8divisionv()
 // CIR:     cir.yield
 // CIR:   } catch [type #cir.global_view<@_ZTIPi> : !cir.ptr<!u8i>] 
(%[[EH_TOKEN:.*]]: !cir.eh_token{{.*}}) {
-// CIR:     %[[CATCH_TOKEN:.*]], %[[EXN_PTR:.*]] = cir.begin_catch 
%[[EH_TOKEN]] : !cir.eh_token -> (!cir.catch_token, !cir.ptr<!s32i>)
+// CIR:     %[[CATCH_TOKEN:.*]] = cir.begin_catch store %[[EH_TOKEN]] : 
!cir.eh_token, %[[E_ADDR]] : !cir.ptr<!cir.ptr<!s32i>> -> !cir.catch_token
 // CIR:     cir.cleanup.scope {
-// CIR:       cir.store {{.*}} %[[EXN_PTR]], %[[E_ADDR]] : !cir.ptr<!s32i>, 
!cir.ptr<!cir.ptr<!s32i>>
 // CIR:       cir.yield
 // CIR:     } cleanup {{.*}} {
 // CIR:       cir.end_catch %[[CATCH_TOKEN]] : !cir.catch_token
@@ -696,9 +690,9 @@ void 
call_function_inside_try_catch_with_array_exception_type() {
 // LLVM:   %[[EXN_OBJ_PHI2:.*]] = phi ptr [ %[[EXN_OBJ_PHI1:.*]], 
%[[DISPATCH:.*]] ]
 // LLVM:   %[[EH_SELECTOR_PHI2:.*]] = phi i32 [ %[[EH_SELECTOR_PHI1:.*]], 
%[[DISPATCH:.*]] ]
 // LLVM:   %[[TOKEN:.*]] = call ptr @__cxa_begin_catch(ptr %[[EXN_OBJ_PHI2]])
+// LLVM:   store ptr %[[TOKEN]], ptr {{.*}}, align 8
 // LLVM:   br label %[[CATCH_BODY:.*]]
 // LLVM: [[CATCH_BODY]]:
-// LLVM:   store ptr %[[TOKEN]], ptr {{.*}}, align 8
 // LLVM:   br label %[[END_CATCH:.*]]
 // LLVM: [[END_CATCH]]:
 // LLVM:   call void @__cxa_end_catch()
@@ -769,10 +763,8 @@ void 
call_function_inside_try_catch_with_exception_type_and_catch_all() {
 // CIR:     %[[CALL:.*]] = cir.call @_Z8divisionv()
 // CIR:     cir.yield
 // CIR:   } catch [type #cir.global_view<@_ZTIi> : !cir.ptr<!u8i>] 
(%[[EH_TOKEN:.*]]: !cir.eh_token{{.*}}) {
-// CIR:     %[[CATCH_TOKEN:.*]], %[[EXN_PTR:.*]] = cir.begin_catch 
%[[EH_TOKEN]] : !cir.eh_token -> (!cir.catch_token, !cir.ptr<!s32i>)
+// CIR:     %[[CATCH_TOKEN:.*]] = cir.begin_catch load_store %[[EH_TOKEN]] : 
!cir.eh_token, %[[EXCEPTION_ADDR]] : !cir.ptr<!s32i> -> !cir.catch_token
 // CIR:     cir.cleanup.scope {
-// CIR:       %[[TMP:.*]] = cir.load {{.*}} %[[EXN_PTR]] : !cir.ptr<!s32i>, 
!s32i
-// CIR:       cir.store {{.*}} %[[TMP]], %[[EXCEPTION_ADDR]] : !s32i, 
!cir.ptr<!s32i>
 // CIR:       cir.yield
 // CIR:     } cleanup {{.*}} {
 // CIR:       cir.end_catch %[[CATCH_TOKEN]] : !cir.catch_token
@@ -780,7 +772,7 @@ void 
call_function_inside_try_catch_with_exception_type_and_catch_all() {
 // CIR:     }
 // CIR:     cir.yield
 // CIR:   } catch all (%[[EH_TOKEN2:.*]]: !cir.eh_token{{.*}}) {
-// CIR:     %[[CATCH_TOKEN2:.*]], %{{.*}} = cir.begin_catch %[[EH_TOKEN2]] : 
!cir.eh_token -> (!cir.catch_token, !cir.ptr<!void>)
+// CIR:     %[[CATCH_TOKEN2:.*]] = cir.begin_catch default %[[EH_TOKEN2]] : 
!cir.eh_token -> !cir.catch_token
 // CIR:     cir.cleanup.scope {
 // CIR:       cir.yield
 // CIR:     } cleanup {{.*}} {
@@ -820,10 +812,10 @@ void 
call_function_inside_try_catch_with_exception_type_and_catch_all() {
 // LLVM:   %[[EXN_OBJ_PHI2:.*]] = phi ptr [ %[[EXN_OBJ_PHI1:.*]], 
%[[DISPATCH:.*]] ]
 // LLVM:   %[[EH_SELECTOR_PHI2:.*]] = phi i32 [ %[[EH_SELECTOR_PHI1:.*]], 
%[[DISPATCH:.*]] ]
 // LLVM:   %[[TOKEN:.*]] = call ptr @__cxa_begin_catch(ptr %[[EXN_OBJ_PHI2]])
-// LLVM:   br label %[[CATCH_BODY:.*]]
-// LLVM: [[CATCH_BODY]]:
 // LLVM:   %[[LOAD:.*]] = load i32, ptr %[[TOKEN]], align 4
 // LLVM:   store i32 %[[LOAD]], ptr {{.*}}, align 4
+// LLVM:   br label %[[CATCH_BODY:.*]]
+// LLVM: [[CATCH_BODY]]:
 // LLVM:   br label %[[END_CATCH:.*]]
 // LLVM: [[END_CATCH]]:
 // LLVM:   call void @__cxa_end_catch()
@@ -912,7 +904,7 @@ void cleanup_inside_try_body() {
 // CIR:     }
 // CIR:     cir.yield
 // CIR:   } catch all (%[[TOKEN:.*]]: !cir.eh_token {{.*}}) {
-// CIR:     %[[CATCH_TOKEN:.*]], %[[EXN_PTR:.*]] = cir.begin_catch %[[TOKEN]] 
: !cir.eh_token -> (!cir.catch_token, !cir.ptr<!void>)
+// CIR:     %[[CATCH_TOKEN:.*]] = cir.begin_catch default %[[TOKEN]] : 
!cir.eh_token -> !cir.catch_token
 // CIR:     cir.cleanup.scope {
 // CIR:       cir.yield
 // CIR:     } cleanup  all {
@@ -1016,9 +1008,8 @@ void 
call_function_inside_try_catch_with_aggregate_exception_type() {
 // CIR:     %[[CALL:.*]] = cir.call @_Z8divisionv() : () -> (!s32i 
{llvm.noundef})
 // CIR:     cir.yield
 // CIR:   } catch [type #cir.global_view<@_ZTI11CustomError> : !cir.ptr<!u8i>] 
(%{{.*}}: !cir.eh_token {{.*}}) {
-// CIR:     %[[CATCH_TOKEN:.*]], %[[EXN_PTR:.*]] = cir.begin_catch %{{.*}} : 
!cir.eh_token -> (!cir.catch_token, !cir.ptr<!rec_CustomError>)
+// CIR:     %[[CATCH_TOKEN:.*]] = cir.begin_catch memcopy {{.*}} : 
!cir.eh_token, %[[E_ADDR]] : !cir.ptr<!rec_CustomError> -> !cir.catch_token
 // CIR:     cir.cleanup.scope {
-// CIR:       cir.copy %[[EXN_PTR]] to %[[E_ADDR]] : !cir.ptr<!rec_CustomError>
 // CIR:       cir.yield
 // CIR:     } cleanup all {
 // CIR:       cir.end_catch %[[CATCH_TOKEN]] : !cir.catch_token
@@ -1059,9 +1050,9 @@ void 
call_function_inside_try_catch_with_aggregate_exception_type() {
 // LLVM:   %[[EXN_OBJ_PHI2:.*]] = phi ptr [ %[[EXN_OBJ_PHI1:.*]], 
%[[DISPATCH:.*]] ]
 // LLVM:   %[[EH_SELECTOR_PHI2:.*]] = phi i32 [ %[[EH_SELECTOR_PHI1:.*]], 
%[[DISPATCH:.*]] ]
 // LLVM:   %[[TOKEN:.*]] = call ptr @__cxa_begin_catch(ptr %[[EXN_OBJ_PHI2]])
+// LLVM:   call void @llvm.memcpy.p0.p0.i64(ptr %{{.*}}, ptr %[[TOKEN]], i64 
4, i1 false)
 // LLVM:   br label %[[CATCH_BODY:.*]]
 // LLVM: [[CATCH_BODY]]:
-// LLVM:   call void @llvm.memcpy.p0.p0.i64(ptr %{{.*}}, ptr %[[TOKEN]], i64 
4, i1 false)
 // LLVM:   br label %[[END_CATCH:.*]]
 // LLVM: [[END_CATCH]]:
 // LLVM:   call void @__cxa_end_catch()
@@ -1131,16 +1122,12 @@ void 
call_function_inside_try_catch_with_ref_ptr_of_record_exception_type() {
 
 // CIR: cir.func {{.*}} 
@_Z68call_function_inside_try_catch_with_ref_ptr_of_record_exception_typev(){{.*}}
 personality(@__gxx_personality_v0) {
 // CIR:   %[[E_ADDR:.*]] = cir.alloca !cir.ptr<!cir.ptr<!rec_Record>>, 
!cir.ptr<!cir.ptr<!cir.ptr<!rec_Record>>>, ["ref_ptr", const]
-// CIR:   %[[EXN_BYREF_TMP:.*]] = cir.alloca !cir.ptr<!rec_Record>, 
!cir.ptr<!cir.ptr<!rec_Record>>, ["exn.byref.tmp"]
 // CIR:   cir.try {
 // CIR:     %[[CALL:.*]] = cir.call @_Z8divisionv() : () -> (!s32i 
{llvm.noundef})
 // CIR:     cir.yield
 // CIR:   } catch [type #cir.global_view<@_ZTIP6Record> : !cir.ptr<!u8i>] 
(%[[EH_TOKEN:.*]]: !cir.eh_token {{.*}}) {
-// CIR:     %[[CATCH_TOKEN:.*]], %[[EXN_PTR:.*]] = cir.begin_catch 
%[[EH_TOKEN]] : !cir.eh_token -> (!cir.catch_token, 
!cir.ptr<!cir.ptr<!rec_Record>>)
+// CIR:     %[[CATCH_TOKEN:.*]] = cir.begin_catch reference %[[EH_TOKEN]] : 
!cir.eh_token, %[[E_ADDR]] : !cir.ptr<!cir.ptr<!cir.ptr<!rec_Record>>> -> 
!cir.catch_token
 // CIR:     cir.cleanup.scope {
-// CIR:       %[[EXN_PTR_REC_PTR:.*]] = cir.cast bitcast %[[EXN_PTR]] : 
!cir.ptr<!cir.ptr<!rec_Record>> -> !cir.ptr<!rec_Record>
-// CIR:       cir.store {{.*}} %[[EXN_PTR_REC_PTR]], %[[EXN_BYREF_TMP]] : 
!cir.ptr<!rec_Record>, !cir.ptr<!cir.ptr<!rec_Record>>
-// CIR:       cir.store {{.*}} %[[EXN_BYREF_TMP]], %[[E_ADDR]] : 
!cir.ptr<!cir.ptr<!rec_Record>>, !cir.ptr<!cir.ptr<!cir.ptr<!rec_Record>>>
 // CIR:       cir.yield
 // CIR:     } cleanup all {
 // CIR:       cir.end_catch %[[CATCH_TOKEN]] : !cir.catch_token
@@ -1153,8 +1140,8 @@ void 
call_function_inside_try_catch_with_ref_ptr_of_record_exception_type() {
 // CIR: }
 
 // LLVM: define {{.*}} void 
@_Z68call_function_inside_try_catch_with_ref_ptr_of_record_exception_typev() 
{{.*}} personality ptr @__gxx_personality_v0
-// LLVM:   %[[E_ADDR:.*]] = alloca ptr
 // LLVM:   %[[EXN_BYREF_TMP:.*]] = alloca ptr
+// LLVM:   %[[E_ADDR:.*]] = alloca ptr
 // LLVM:   br label %[[TRY_SCOPE:.*]]
 // LLVM: [[TRY_SCOPE]]:
 // LLVM:   br label %[[TRY_BEGIN:.*]]
@@ -1183,10 +1170,10 @@ void 
call_function_inside_try_catch_with_ref_ptr_of_record_exception_type() {
 // LLVM:   %[[EXN_OBJ_PHI2:.*]] = phi ptr [ %[[EXN_OBJ_PHI1:.*]], 
%[[DISPATCH:.*]] ]
 // LLVM:   %[[EH_SELECTOR_PHI2:.*]] = phi i32 [ %[[EH_SELECTOR_PHI1:.*]], 
%[[DISPATCH:.*]] ]
 // LLVM:   %[[TOKEN:.*]] = call ptr @__cxa_begin_catch(ptr %[[EXN_OBJ_PHI2]])
-// LLVM:   br label %[[CATCH_BODY:.*]]
-// LLVM: [[CATCH_BODY]]:
 // LLVM:   store ptr %[[TOKEN]], ptr %[[EXN_BYREF_TMP]], align 8
 // LLVM:   store ptr %[[EXN_BYREF_TMP]], ptr %[[E_ADDR]], align 8
+// LLVM:   br label %[[CATCH_BODY:.*]]
+// LLVM: [[CATCH_BODY]]:
 // LLVM:   br label %[[END_CATCH:.*]]
 // LLVM: [[END_CATCH]]:
 // LLVM:   call void @__cxa_end_catch()
@@ -1258,10 +1245,8 @@ void 
call_function_inside_try_catch_with_exception_member_ptr_type() {
 // CIR:     %[[CALL:.*]] = cir.call @_Z8divisionv() : () -> (!s32i 
{llvm.noundef})
 // CIR:     cir.yield
 // CIR:   } catch [type #cir.global_view<@_ZTIM6Recordi> : !cir.ptr<!u8i>] 
(%{{.*}}: !cir.eh_token {{.*}} {
-// CIR:     %[[CATCH_TOKEN:.*]], %[[EXN_PTR:.*]] = cir.begin_catch %{{.*}} : 
!cir.eh_token -> (!cir.catch_token, !cir.ptr<!s64i>)
+// CIR:     %[[CATCH_TOKEN:.*]] = cir.begin_catch load_store %{{.*}} : 
!cir.eh_token, %[[E_ADDR]] : !cir.ptr<!s64i> -> !cir.catch_token
 // CIR:     cir.cleanup.scope {
-// CIR:       %[[TMP:.*]] = cir.load {{.*}} %[[EXN_PTR]] : !cir.ptr<!s64i>, 
!s64i
-// CIR:       cir.store {{.*}} %[[TMP]], %[[E_ADDR]] : !s64i, !cir.ptr<!s64i>
 // CIR:       cir.yield
 // CIR:     } cleanup all {
 // CIR:       cir.end_catch %[[CATCH_TOKEN]] : !cir.catch_token
@@ -1302,10 +1287,10 @@ void 
call_function_inside_try_catch_with_exception_member_ptr_type() {
 // LLVM:   %[[EXN_OBJ_PHI2:.*]] = phi ptr [ %[[EXN_OBJ_PHI1:.*]], 
%[[DISPATCH:.*]] ]
 // LLVM:   %[[EH_SELECTOR_PHI2:.*]] = phi i32 [ %[[EH_SELECTOR_PHI1:.*]], 
%[[DISPATCH:.*]] ]
 // LLVM:   %[[TOKEN:.*]] = call ptr @__cxa_begin_catch(ptr %[[EXN_OBJ_PHI2]])
-// LLVM:   br label %[[CATCH_BODY:.*]]
-// LLVM: [[CATCH_BODY]]:
 // LLVM:   %[[LOAD:.*]] = load i64, ptr %[[TOKEN]], align 8
 // LLVM:   store i64 %[[LOAD]], ptr {{.*}}, align 8
+// LLVM:   br label %[[CATCH_BODY:.*]]
+// LLVM: [[CATCH_BODY]]:
 // LLVM:   br label %[[END_CATCH:.*]]
 // LLVM: [[END_CATCH]]:
 // LLVM:   call void @__cxa_end_catch()
diff --git a/clang/test/CIR/IR/catch-param.cir 
b/clang/test/CIR/IR/catch-param.cir
index 3734917c35877..6f1fb08cb66ae 100644
--- a/clang/test/CIR/IR/catch-param.cir
+++ b/clang/test/CIR/IR/catch-param.cir
@@ -10,7 +10,7 @@ cir.func @begin_catch_inside_catch() {
     cir.try {
       cir.yield
     } catch all (%eh_token : !cir.eh_token) {
-      %catch_token, %exception = cir.begin_catch %eh_token : !cir.eh_token -> 
(!cir.catch_token, !cir.ptr<!void>)
+      %catch_token = cir.begin_catch default %eh_token : !cir.eh_token -> 
!cir.catch_token
       cir.cleanup.scope {
         cir.yield
       } cleanup eh {
@@ -28,7 +28,7 @@ cir.func @begin_catch_inside_catch() {
 // CHECK:     cir.try {
 // CHECK:       cir.yield
 // CHECK:     } catch all (%[[EH_TOKEN:.*]]: !cir.eh_token) {
-// CHECK:       %[[CATCH_TOKEN:.*]], %[[EXCEPTION:.*]] = cir.begin_catch 
%[[EH_TOKEN]] : !cir.eh_token -> (!cir.catch_token, !cir.ptr<!void>)
+// CHECK:       %[[CATCH_TOKEN:.*]] = cir.begin_catch default %[[EH_TOKEN]] : 
!cir.eh_token -> !cir.catch_token
 // CHECK:       cir.cleanup.scope {
 // CHECK:         cir.yield
 // CHECK:       } cleanup eh {
diff --git a/clang/test/CIR/IR/eh-flat.cir b/clang/test/CIR/IR/eh-flat.cir
index c6799dcda766c..b6aab9099f4bc 100644
--- a/clang/test/CIR/IR/eh-flat.cir
+++ b/clang/test/CIR/IR/eh-flat.cir
@@ -148,26 +148,28 @@ cir.func @cleanup_ops(%eh_token: !cir.eh_token) {
 
 // Test cir.begin_catch and cir.end_catch
 cir.func @catch_ops(%eh_token: !cir.eh_token) {
-  %catch_token, %exn_ptr = cir.begin_catch %eh_token : !cir.eh_token -> 
(!cir.catch_token, !cir.ptr<!s32i>)
+  %exn_addr = cir.alloca !s32i, !cir.ptr<!s32i>, ["e"] {alignment = 4 : i64} 
+  %catch_token = cir.begin_catch load_store %eh_token : !cir.eh_token, 
%exn_addr : !cir.ptr<!s32i> -> !cir.catch_token
   cir.end_catch %catch_token : !cir.catch_token
   cir.return
 }
 
 // CHECK: cir.func @catch_ops(%arg0: !cir.eh_token) {
-// CHECK:   %[[CATCH:.*]], %[[EXN:.*]] = cir.begin_catch %arg0 : !cir.eh_token 
-> (!cir.catch_token, !cir.ptr<!s32i>)
+// CHECK:   %[[EXN_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["e"] 
{alignment = 4 : i64} 
+// CHECK:   %[[CATCH:.*]] = cir.begin_catch load_store %arg0 : !cir.eh_token, 
%[[EXN_ADDR]] : !cir.ptr<!s32i> -> !cir.catch_token
 // CHECK:   cir.end_catch %[[CATCH]] : !cir.catch_token
 // CHECK:   cir.return
 // CHECK: }
 
 // Test cir.begin_catch with void pointer (catch all)
 cir.func @catch_all_ops(%eh_token: !cir.eh_token) {
-  %catch_token, %exn_ptr = cir.begin_catch %eh_token : !cir.eh_token -> 
(!cir.catch_token, !cir.ptr<!void>)
+  %catch_token = cir.begin_catch default %eh_token : !cir.eh_token -> 
!cir.catch_token
   cir.end_catch %catch_token : !cir.catch_token
   cir.return
 }
 
 // CHECK: cir.func @catch_all_ops(%arg0: !cir.eh_token) {
-// CHECK:   %[[CATCH:.*]], %[[EXN:.*]] = cir.begin_catch %arg0 : !cir.eh_token 
-> (!cir.catch_token, !cir.ptr<!void>)
+// CHECK:   %[[CATCH:.*]] = cir.begin_catch default %arg0 : !cir.eh_token -> 
!cir.catch_token 
 // CHECK:   cir.end_catch %[[CATCH]] : !cir.catch_token
 // CHECK:   cir.return
 // CHECK: }
@@ -177,6 +179,7 @@ cir.func private @mayThrow() -> ()
 cir.func private @destructor() -> ()
 
 cir.func @complete_example() {
+  %exn_addr = cir.alloca !s32i, !cir.ptr<!s32i>, ["e"] {alignment = 4 : i64} 
   cir.try_call @mayThrow() ^bb1, ^bb2 : () -> ()
 ^bb1:  // Normal return
   cir.return
@@ -190,16 +193,17 @@ cir.func @complete_example() {
     catch_all : ^catch_all
   ]
 ^catch_int:
-  %catch_token, %exn_ptr = cir.begin_catch %eh_token : !cir.eh_token -> 
(!cir.catch_token, !cir.ptr<!s32i>)
+  %catch_token = cir.begin_catch load_store %eh_token : !cir.eh_token, 
%exn_addr : !cir.ptr<!s32i> -> !cir.catch_token
   cir.end_catch %catch_token : !cir.catch_token
   cir.return
 ^catch_all:
-  %catch_token2, %exn_ptr2 = cir.begin_catch %eh_token : !cir.eh_token -> 
(!cir.catch_token, !cir.ptr<!void>)
+  %catch_token2= cir.begin_catch default  %eh_token : !cir.eh_token -> 
!cir.catch_token
   cir.end_catch %catch_token2 : !cir.catch_token
   cir.return
 }
 
 // CHECK: cir.func @complete_example()
+// CHECK:   %[[EXN_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["e"] 
 // CHECK:   cir.try_call @mayThrow() ^bb1, ^bb2 : () -> ()
 // CHECK: ^bb1:
 // CHECK:   cir.return
@@ -213,11 +217,11 @@ cir.func @complete_example() {
 // CHECK:     catch_all : ^bb4
 // CHECK:   ]
 // CHECK: ^bb3:
-// CHECK:   %[[CATCH1:.*]], %{{.*}} = cir.begin_catch %[[EH]] : !cir.eh_token 
-> (!cir.catch_token, !cir.ptr<!s32i>)
+// CHECK:   %[[CATCH1:.*]] = cir.begin_catch load_store %[[EH]] : 
!cir.eh_token, %[[EXN_ADDR]] : !cir.ptr<!s32i> -> !cir.catch_token
 // CHECK:   cir.end_catch %[[CATCH1]] : !cir.catch_token
 // CHECK:   cir.return
 // CHECK: ^bb4:
-// CHECK:   %[[CATCH2:.*]], %{{.*}} = cir.begin_catch %[[EH]] : !cir.eh_token 
-> (!cir.catch_token, !cir.ptr<!void>)
+// CHECK:   %[[CATCH2:.*]] = cir.begin_catch default %[[EH]] : !cir.eh_token 
-> !cir.catch_token
 // CHECK:   cir.end_catch %[[CATCH2]] : !cir.catch_token
 // CHECK:   cir.return
 // CHECK: }
diff --git a/clang/test/CIR/IR/try-catch.cir b/clang/test/CIR/IR/try-catch.cir
index 203ec340d7f6e..d865038198bf5 100644
--- a/clang/test/CIR/IR/try-catch.cir
+++ b/clang/test/CIR/IR/try-catch.cir
@@ -14,7 +14,7 @@ cir.func dso_local @empty_try_block_with_catch_all() {
     cir.try {
       cir.yield
     } catch all (%eh_token : !cir.eh_token) {
-      %catch_token, %0 = cir.begin_catch %eh_token : !cir.eh_token -> 
(!cir.catch_token, !cir.ptr<!void>)
+      %catch_token= cir.begin_catch default %eh_token : !cir.eh_token -> 
!cir.catch_token
       cir.cleanup.scope {
         cir.yield
       } cleanup eh {
@@ -32,7 +32,7 @@ cir.func dso_local @empty_try_block_with_catch_all() {
 // CHECK:     cir.try {
 // CHECK:       cir.yield
 // CHECK:     } catch all (%[[EH_TOKEN:.*]]: !cir.eh_token) {
-// CHECK:       %[[CATCH_TOKEN:.*]], %[[EXN_PTR:.*]] = cir.begin_catch 
%[[EH_TOKEN]] : !cir.eh_token -> (!cir.catch_token, !cir.ptr<!void>)
+// CHECK:       %[[CATCH_TOKEN:.*]] = cir.begin_catch default %[[EH_TOKEN]] : 
!cir.eh_token -> !cir.catch_token
 // CHECK:       cir.cleanup.scope {
 // CHECK:         cir.yield
 // CHECK:       } cleanup eh {
@@ -68,11 +68,13 @@ cir.func dso_local @empty_try_block_with_catch_unwind() {
 // CHECK: }
 
 cir.func dso_local @empty_try_block_with_catch_ist() {
+  %exn_addr = cir.alloca !s32i, !cir.ptr<!s32i>, ["e"] {alignment = 4 : i64} 
+  %exn_addr_2 = cir.alloca !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>, ["e2"] 
{alignment = 4 : i64} 
   cir.scope {
     cir.try {
       cir.yield
     } catch [type #cir.global_view<@_ZTIi> : !cir.ptr<!u8i>] (%eh_token : 
!cir.eh_token) {
-      %catch_token, %0 = cir.begin_catch %eh_token : !cir.eh_token -> 
(!cir.catch_token, !cir.ptr<!s32i>)
+      %catch_token = cir.begin_catch load_store %eh_token : !cir.eh_token, 
%exn_addr : !cir.ptr<!s32i> -> !cir.catch_token
       cir.cleanup.scope {
         cir.yield
       } cleanup eh {
@@ -81,7 +83,7 @@ cir.func dso_local @empty_try_block_with_catch_ist() {
       }
       cir.yield
     } catch [type #cir.global_view<@_ZTIPKc> : !cir.ptr<!u8i>] (%eh_token_1 : 
!cir.eh_token) {
-      %catch_token_1, %1 = cir.begin_catch %eh_token_1 : !cir.eh_token -> 
(!cir.catch_token, !cir.ptr<!cir.ptr<!u8i>>)
+      %catch_token_1 = cir.begin_catch store %eh_token_1 : !cir.eh_token, 
%exn_addr_2 : !cir.ptr<!cir.ptr<!u8i>> -> !cir.catch_token
       cir.cleanup.scope {
         cir.yield
       } cleanup eh {
@@ -97,11 +99,13 @@ cir.func dso_local @empty_try_block_with_catch_ist() {
 }
 
 // CHECK: cir.func dso_local @empty_try_block_with_catch_ist() {
+// CHECK:   %[[EXN_ADDR1:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["e"]
+// CHECK:   %[[EXN_ADDR2:.*]] = cir.alloca !cir.ptr<!u8i>, 
!cir.ptr<!cir.ptr<!u8i>>
 // CHECK:   cir.scope {
 // CHECK:     cir.try {
 // CHECK:       cir.yield
 // CHECK:     } catch [type #cir.global_view<@_ZTIi> : !cir.ptr<!u8i>] 
(%[[EH1:.*]]: !cir.eh_token) {
-// CHECK:       %[[CT1:.*]], %{{.*}} = cir.begin_catch %[[EH1]] : 
!cir.eh_token -> (!cir.catch_token, !cir.ptr<!s32i>)
+// CHECK:       %[[CT1:.*]] = cir.begin_catch load_store %[[EH1]] : 
!cir.eh_token, %[[EXN_ADDR1]] : !cir.ptr<!s32i> -> !cir.catch_token
 // CHECK:       cir.cleanup.scope {
 // CHECK:         cir.yield
 // CHECK:       } cleanup eh {
@@ -110,7 +114,7 @@ cir.func dso_local @empty_try_block_with_catch_ist() {
 // CHECK:       }
 // CHECK:       cir.yield
 // CHECK:     } catch [type #cir.global_view<@_ZTIPKc> : !cir.ptr<!u8i>] 
(%[[EH2:.*]]: !cir.eh_token) {
-// CHECK:       %[[CT2:.*]], %{{.*}} = cir.begin_catch %[[EH2]] : 
!cir.eh_token -> (!cir.catch_token, !cir.ptr<!cir.ptr<!u8i>>)
+// CHECK:       %[[CT2:.*]] = cir.begin_catch store %[[EH2]] : !cir.eh_token, 
%[[EXN_ADDR2]] : !cir.ptr<!cir.ptr<!u8i>> -> !cir.catch_token
 // CHECK:       cir.cleanup.scope {
 // CHECK:         cir.yield
 // CHECK:       } cleanup eh {

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

Reply via email to