@@ -3196,6 +3196,90 @@ mlir::LogicalResult CIRToLLVMAllocExceptionOpLowering::matchAndRewrite(
31963196 return mlir::success ();
31973197}
31983198
3199+ static mlir::LLVM::LLVMStructType
3200+ getLLVMLandingPadStructTy (mlir::ConversionPatternRewriter &rewriter) {
3201+ // Create the landing pad type: struct { ptr, i32 }
3202+ mlir::MLIRContext *ctx = rewriter.getContext ();
3203+ auto llvmPtr = mlir::LLVM::LLVMPointerType::get (ctx);
3204+ llvm::SmallVector<mlir::Type> structFields = {llvmPtr, rewriter.getI32Type ()};
3205+ return mlir::LLVM::LLVMStructType::getLiteral (ctx, structFields);
3206+ }
3207+
3208+ mlir::LogicalResult CIRToLLVMEhInflightOpLowering::matchAndRewrite (
3209+ cir::EhInflightOp op, OpAdaptor adaptor,
3210+ mlir::ConversionPatternRewriter &rewriter) const {
3211+ auto llvmFn = op->getParentOfType <mlir::LLVM::LLVMFuncOp>();
3212+ assert (llvmFn && " expected LLVM function parent" );
3213+ mlir::Block *entryBlock = &llvmFn.getRegion ().front ();
3214+ assert (entryBlock->isEntryBlock ());
3215+
3216+ mlir::ArrayAttr catchListAttr = op.getCatchTypeListAttr ();
3217+ mlir::SmallVector<mlir::Value> catchSymAddrs;
3218+
3219+ auto llvmPtrTy = mlir::LLVM::LLVMPointerType::get (rewriter.getContext ());
3220+ mlir::Location loc = op.getLoc ();
3221+
3222+ // %landingpad = landingpad { ptr, i32 }
3223+ // Note that since llvm.landingpad has to be the first operation on the
3224+ // block, any needed value for its operands has to be added somewhere else.
3225+ if (catchListAttr) {
3226+ // catch ptr @_ZTIi
3227+ // catch ptr @_ZTIPKc
3228+ for (mlir::Attribute catchAttr : catchListAttr) {
3229+ auto symAttr = cast<mlir::FlatSymbolRefAttr>(catchAttr);
3230+ // Generate `llvm.mlir.addressof` for each symbol, and place those
3231+ // operations in the LLVM function entry basic block.
3232+ mlir::OpBuilder::InsertionGuard guard (rewriter);
3233+ rewriter.setInsertionPointToStart (entryBlock);
3234+ mlir::Value addrOp = mlir::LLVM::AddressOfOp::create (
3235+ rewriter, loc, llvmPtrTy, symAttr.getValue ());
3236+ catchSymAddrs.push_back (addrOp);
3237+ }
3238+ } else if (!op.getCleanup ()) {
3239+ // We need to emit catch-all only if cleanup is not set, because when we
3240+ // have catch-all handler, there is no case when we set would unwind past
3241+ // the handler
3242+ mlir::OpBuilder::InsertionGuard guard (rewriter);
3243+ rewriter.setInsertionPointToStart (entryBlock);
3244+ mlir::Value nullOp = mlir::LLVM::ZeroOp::create (rewriter, loc, llvmPtrTy);
3245+ catchSymAddrs.push_back (nullOp);
3246+ }
3247+
3248+ // %slot = extractvalue { ptr, i32 } %x, 0
3249+ // %selector = extractvalue { ptr, i32 } %x, 1
3250+ mlir::LLVM::LLVMStructType llvmLandingPadStructTy =
3251+ getLLVMLandingPadStructTy (rewriter);
3252+ auto landingPadOp = mlir::LLVM::LandingpadOp::create (
3253+ rewriter, loc, llvmLandingPadStructTy, catchSymAddrs);
3254+
3255+ if (op.getCleanup ())
3256+ landingPadOp.setCleanup (true );
3257+
3258+ mlir::Value slot =
3259+ mlir::LLVM::ExtractValueOp::create (rewriter, loc, landingPadOp, 0 );
3260+ mlir::Value selector =
3261+ mlir::LLVM::ExtractValueOp::create (rewriter, loc, landingPadOp, 1 );
3262+ rewriter.replaceOp (op, mlir::ValueRange{slot, selector});
3263+
3264+ // Landing pads are required to be in LLVM functions with personality
3265+ // attribute.
3266+ // TODO(cir): for now hardcode personality creation in order to start
3267+ // adding exception tests, once we annotate CIR with such information,
3268+ // change it to be in FuncOp lowering instead.
3269+ mlir::OpBuilder::InsertionGuard guard (rewriter);
3270+ // Insert personality decl before the current function.
3271+ rewriter.setInsertionPoint (llvmFn);
3272+ auto personalityFnTy =
3273+ mlir::LLVM::LLVMFunctionType::get (rewriter.getI32Type (), {},
3274+ /* isVarArg=*/ true );
3275+
3276+ const StringRef fnName = " __gxx_personality_v0" ;
3277+ createLLVMFuncOpIfNotExist (rewriter, op, fnName, personalityFnTy);
3278+ llvmFn.setPersonality (fnName);
3279+
3280+ return mlir::success ();
3281+ }
3282+
31993283mlir::LogicalResult CIRToLLVMTrapOpLowering::matchAndRewrite (
32003284 cir::TrapOp op, OpAdaptor adaptor,
32013285 mlir::ConversionPatternRewriter &rewriter) const {
0 commit comments