@@ -3104,6 +3104,90 @@ mlir::LogicalResult CIRToLLVMAllocExceptionOpLowering::matchAndRewrite(
31043104 return mlir::success ();
31053105}
31063106
3107+ static mlir::LLVM::LLVMStructType
3108+ getLLVMLandingPadStructTy (mlir::ConversionPatternRewriter &rewriter) {
3109+ // Create the landing pad type: struct { ptr, i32 }
3110+ mlir::MLIRContext *ctx = rewriter.getContext ();
3111+ auto llvmPtr = mlir::LLVM::LLVMPointerType::get (ctx);
3112+ llvm::SmallVector<mlir::Type> structFields = {llvmPtr, rewriter.getI32Type ()};
3113+ return mlir::LLVM::LLVMStructType::getLiteral (ctx, structFields);
3114+ }
3115+
3116+ mlir::LogicalResult CIRToLLVMEhInflightOpLowering::matchAndRewrite (
3117+ cir::EhInflightOp op, OpAdaptor adaptor,
3118+ mlir::ConversionPatternRewriter &rewriter) const {
3119+ auto llvmFn = op->getParentOfType <mlir::LLVM::LLVMFuncOp>();
3120+ assert (llvmFn && " expected LLVM function parent" );
3121+ mlir::Block *entryBlock = &llvmFn.getRegion ().front ();
3122+ assert (entryBlock->isEntryBlock ());
3123+
3124+ mlir::ArrayAttr catchListAttr = op.getCatchTypeListAttr ();
3125+ mlir::SmallVector<mlir::Value> catchSymAddrs;
3126+
3127+ auto llvmPtrTy = mlir::LLVM::LLVMPointerType::get (rewriter.getContext ());
3128+ mlir::Location loc = op.getLoc ();
3129+
3130+ // %landingpad = landingpad { ptr, i32 }
3131+ // Note that since llvm.landingpad has to be the first operation on the
3132+ // block, any needed value for its operands has to be added somewhere else.
3133+ if (catchListAttr) {
3134+ // catch ptr @_ZTIi
3135+ // catch ptr @_ZTIPKc
3136+ for (mlir::Attribute catchAttr : catchListAttr) {
3137+ auto symAttr = cast<mlir::FlatSymbolRefAttr>(catchAttr);
3138+ // Generate `llvm.mlir.addressof` for each symbol, and place those
3139+ // operations in the LLVM function entry basic block.
3140+ mlir::OpBuilder::InsertionGuard guard (rewriter);
3141+ rewriter.setInsertionPointToStart (entryBlock);
3142+ mlir::Value addrOp = mlir::LLVM::AddressOfOp::create (
3143+ rewriter, loc, llvmPtrTy, symAttr.getValue ());
3144+ catchSymAddrs.push_back (addrOp);
3145+ }
3146+ } else if (!op.getCleanup ()) {
3147+ // We need to emit catch-all only if cleanup is not set, because when we
3148+ // have catch-all handler, there is no case when we set would unwind past
3149+ // the handler
3150+ mlir::OpBuilder::InsertionGuard guard (rewriter);
3151+ rewriter.setInsertionPointToStart (entryBlock);
3152+ mlir::Value nullOp = mlir::LLVM::ZeroOp::create (rewriter, loc, llvmPtrTy);
3153+ catchSymAddrs.push_back (nullOp);
3154+ }
3155+
3156+ // %slot = extractvalue { ptr, i32 } %x, 0
3157+ // %selector = extractvalue { ptr, i32 } %x, 1
3158+ mlir::LLVM::LLVMStructType llvmLandingPadStructTy =
3159+ getLLVMLandingPadStructTy (rewriter);
3160+ auto landingPadOp = mlir::LLVM::LandingpadOp::create (
3161+ rewriter, loc, llvmLandingPadStructTy, catchSymAddrs);
3162+
3163+ if (op.getCleanup ())
3164+ landingPadOp.setCleanup (true );
3165+
3166+ mlir::Value slot =
3167+ mlir::LLVM::ExtractValueOp::create (rewriter, loc, landingPadOp, 0 );
3168+ mlir::Value selector =
3169+ mlir::LLVM::ExtractValueOp::create (rewriter, loc, landingPadOp, 1 );
3170+ rewriter.replaceOp (op, mlir::ValueRange{slot, selector});
3171+
3172+ // Landing pads are required to be in LLVM functions with personality
3173+ // attribute.
3174+ // TODO(cir): for now hardcode personality creation in order to start
3175+ // adding exception tests, once we annotate CIR with such information,
3176+ // change it to be in FuncOp lowering instead.
3177+ mlir::OpBuilder::InsertionGuard guard (rewriter);
3178+ // Insert personality decl before the current function.
3179+ rewriter.setInsertionPoint (llvmFn);
3180+ auto personalityFnTy =
3181+ mlir::LLVM::LLVMFunctionType::get (rewriter.getI32Type (), {},
3182+ /* isVarArg=*/ true );
3183+
3184+ const StringRef fnName = " __gxx_personality_v0" ;
3185+ createLLVMFuncOpIfNotExist (rewriter, op, fnName, personalityFnTy);
3186+ llvmFn.setPersonality (fnName);
3187+
3188+ return mlir::success ();
3189+ }
3190+
31073191mlir::LogicalResult CIRToLLVMTrapOpLowering::matchAndRewrite (
31083192 cir::TrapOp op, OpAdaptor adaptor,
31093193 mlir::ConversionPatternRewriter &rewriter) const {
0 commit comments