@@ -2581,22 +2581,69 @@ void createLLVMFuncOpIfNotExist(mlir::ConversionPatternRewriter &rewriter,
25812581mlir::LogicalResult CIRToLLVMThrowOpLowering::matchAndRewrite (
25822582    cir::ThrowOp op, OpAdaptor adaptor,
25832583    mlir::ConversionPatternRewriter &rewriter) const  {
2584-   if  (op.rethrows ()) {
2585-     auto  voidTy = mlir::LLVM::LLVMVoidType::get (getContext ());
2586-     auto  funcTy =
2587-         mlir::LLVM::LLVMFunctionType::get (getContext (), voidTy, {}, false );
2584+   mlir::Location loc = op.getLoc ();
2585+   auto  voidTy = mlir::LLVM::LLVMVoidType::get (getContext ());
25882586
2589-      auto  mlirModule = op-> getParentOfType <mlir::ModuleOp>(); 
2590-     rewriter. setInsertionPointToStart (&mlirModule. getBodyRegion (). front () );
2587+   if  (op. rethrows ()) { 
2588+     auto  funcTy =  mlir::LLVM::LLVMFunctionType::get (voidTy, {} );
25912589
2590+     //  Get or create `declare void @__cxa_rethrow()`
25922591    const  llvm::StringRef functionName = " __cxa_rethrow"  ;
25932592    createLLVMFuncOpIfNotExist (rewriter, op, functionName, funcTy);
25942593
2595-     rewriter.setInsertionPointAfter (op.getOperation ());
2596-     rewriter.replaceOpWithNewOp <mlir::LLVM::CallOp>(
2597-         op, mlir::TypeRange{}, functionName, mlir::ValueRange{});
2594+     auto  cxaRethrow = mlir::LLVM::CallOp::create (
2595+         rewriter, loc, mlir::TypeRange{}, functionName);
2596+ 
2597+     rewriter.replaceOp (op, cxaRethrow);
2598+     return  mlir::success ();
25982599  }
25992600
2601+   auto  llvmPtrTy = mlir::LLVM::LLVMPointerType::get (rewriter.getContext ());
2602+   auto  fnTy = mlir::LLVM::LLVMFunctionType::get (
2603+       voidTy, {llvmPtrTy, llvmPtrTy, llvmPtrTy});
2604+ 
2605+   //  Get or create `declare void @__cxa_throw(ptr, ptr, ptr)`
2606+   const  llvm::StringRef fnName = " __cxa_throw"  ;
2607+   createLLVMFuncOpIfNotExist (rewriter, op, fnName, fnTy);
2608+ 
2609+   mlir::Value typeInfo = mlir::LLVM::AddressOfOp::create (
2610+       rewriter, loc, mlir::LLVM::LLVMPointerType::get (rewriter.getContext ()),
2611+       adaptor.getTypeInfoAttr ());
2612+ 
2613+   mlir::Value dtor;
2614+   if  (op.getDtor ()) {
2615+     dtor = mlir::LLVM::AddressOfOp::create (rewriter, loc, llvmPtrTy,
2616+                                            adaptor.getDtorAttr ());
2617+   } else  {
2618+     dtor = mlir::LLVM::ZeroOp::create (rewriter, loc, llvmPtrTy);
2619+   }
2620+ 
2621+   auto  cxaThrowCall = mlir::LLVM::CallOp::create (
2622+       rewriter, loc, mlir::TypeRange{}, fnName,
2623+       mlir::ValueRange{adaptor.getExceptionPtr (), typeInfo, dtor});
2624+ 
2625+   rewriter.replaceOp (op, cxaThrowCall);
2626+   return  mlir::success ();
2627+ }
2628+ 
2629+ mlir::LogicalResult CIRToLLVMAllocExceptionOpLowering::matchAndRewrite (
2630+     cir::AllocExceptionOp op, OpAdaptor adaptor,
2631+     mlir::ConversionPatternRewriter &rewriter) const  {
2632+   //  Get or create `declare ptr @__cxa_allocate_exception(i64)`
2633+   StringRef fnName = " __cxa_allocate_exception"  ;
2634+   auto  llvmPtrTy = mlir::LLVM::LLVMPointerType::get (rewriter.getContext ());
2635+   auto  int64Ty = mlir::IntegerType::get (rewriter.getContext (), 64 );
2636+   auto  fnTy = mlir::LLVM::LLVMFunctionType::get (llvmPtrTy, {int64Ty});
2637+ 
2638+   createLLVMFuncOpIfNotExist (rewriter, op, fnName, fnTy);
2639+   auto  exceptionSize = mlir::LLVM::ConstantOp::create (rewriter, op.getLoc (),
2640+                                                       adaptor.getSizeAttr ());
2641+ 
2642+   auto  allocaExceptionCall = mlir::LLVM::CallOp::create (
2643+       rewriter, op.getLoc (), mlir::TypeRange{llvmPtrTy}, fnName,
2644+       mlir::ValueRange{exceptionSize});
2645+ 
2646+   rewriter.replaceOp (op, allocaExceptionCall);
26002647  return  mlir::success ();
26012648}
26022649
0 commit comments