[clang] [CIR] Add flattened version of ResumeOp (PR #172534)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Dec 16 10:39:36 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clangir
Author: Amr Hesham (AmrDeveloper)
<details>
<summary>Changes</summary>
Add the flattened version of ResumeOp
Issue https://github.com/llvm/llvm-project/issues/154992
---
Full diff: https://github.com/llvm/llvm-project/pull/172534.diff
4 Files Affected:
- (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+30)
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+22)
- (added) clang/test/CIR/IR/resume-flat.cir (+25)
- (added) clang/test/CIR/Lowering/resume-flat.cir (+30)
``````````diff
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 240459428b22c..294f66c2ccda7 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -963,6 +963,36 @@ def CIR_ResumeOp : CIR_Op<"resume", [
let hasLLVMLowering = false;
}
+def CIR_ResumeFlatOp : CIR_Op<"resume.flat", [
+ ReturnLike, Terminator
+]> {
+ let summary = "A flattened version of `cir.resume`";
+ let description = [{
+ The `cir_resume.flat` operation is a region-less and simplified
+ version of the `cir_resume`.
+
+ Its representation is closer to LLVM IR dialect
+ than the C/C++ language feature.
+
+ This operation is used only after the CFG flatterning pass.
+
+ Examples:
+ ```mlir
+ cir.resume.flat %exception_ptr, %type_id
+ ```
+ }];
+
+ let arguments = (ins
+ CIR_VoidPtrType:$exception_ptr,
+ CIR_UInt32:$type_id
+ );
+
+ let assemblyFormat = [{
+ $exception_ptr `,` $type_id
+ attr-dict
+ }];
+}
+
//===----------------------------------------------------------------------===//
// ScopeOp
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 7d854997848aa..5bdd31f0a9c70 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -3418,6 +3418,28 @@ mlir::LogicalResult CIRToLLVMEhInflightOpLowering::matchAndRewrite(
return mlir::success();
}
+mlir::LogicalResult CIRToLLVMResumeFlatOpLowering::matchAndRewrite(
+ cir::ResumeFlatOp op, OpAdaptor adaptor,
+ mlir::ConversionPatternRewriter &rewriter) const {
+ // %lpad.val = insertvalue { ptr, i32 } poison, ptr %exception_ptr, 0
+ // %lpad.val2 = insertvalue { ptr, i32 } %lpad.val, i32 %selector, 1
+ // resume { ptr, i32 } %lpad.val2
+ auto llvmLandingPadStructTy = getLLVMLandingPadStructTy(rewriter);
+ mlir::Value poison = mlir::LLVM::PoisonOp::create(rewriter, op.getLoc(),
+ llvmLandingPadStructTy);
+
+ SmallVector<int64_t> slotIdx = {0};
+ mlir::Value slot = mlir::LLVM::InsertValueOp::create(
+ rewriter, op.getLoc(), poison, adaptor.getExceptionPtr(), slotIdx);
+
+ SmallVector<int64_t> selectorIdx = {1};
+ mlir::Value selector = mlir::LLVM::InsertValueOp::create(
+ rewriter, op.getLoc(), slot, adaptor.getTypeId(), selectorIdx);
+
+ rewriter.replaceOpWithNewOp<mlir::LLVM::ResumeOp>(op, selector);
+ return mlir::success();
+}
+
mlir::LogicalResult CIRToLLVMTrapOpLowering::matchAndRewrite(
cir::TrapOp op, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const {
diff --git a/clang/test/CIR/IR/resume-flat.cir b/clang/test/CIR/IR/resume-flat.cir
new file mode 100644
index 0000000000000..9c047dbf995a4
--- /dev/null
+++ b/clang/test/CIR/IR/resume-flat.cir
@@ -0,0 +1,25 @@
+// RUN: cir-opt %s --verify-roundtrip | FileCheck %s
+
+!u32i = !cir.int<u, 32>
+!void = !cir.void
+
+module {
+
+cir.func private @flattened_resume() {
+ %exception_addr = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["exception", init]
+ %type_id_addr = cir.alloca !u32i, !cir.ptr<!u32i>, ["type_id", init]
+ %exception = cir.load %exception_addr : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
+ %type_id = cir.load %type_id_addr : !cir.ptr<!u32i>, !u32i
+ cir.resume.flat %exception, %type_id
+}
+
+// CHECK: cir.func private @flattened_resume() {
+// CHECK: %[[EXCEPTION_ADDR:.*]] = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["exception", init]
+// CHECK: %[[TYPE_ID_ADDR:.*]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["type_id", init]
+// CHECK: %[[EXCEPTION:.*]] = cir.load %[[EXCEPTION_ADDR]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
+// CHECK: %[[TYPE_ID:.*]] = cir.load %[[TYPE_ID_ADDR]] : !cir.ptr<!u32i>, !u32i
+// CHECK: cir.resume.flat %[[EXCEPTION]], %[[TYPE_ID]]
+// CHECK: }
+
+}
+
diff --git a/clang/test/CIR/Lowering/resume-flat.cir b/clang/test/CIR/Lowering/resume-flat.cir
new file mode 100644
index 0000000000000..15690db6535ac
--- /dev/null
+++ b/clang/test/CIR/Lowering/resume-flat.cir
@@ -0,0 +1,30 @@
+// RUN: cir-opt %s -cir-to-llvm -o %t.cir
+
+!u32i = !cir.int<u, 32>
+!void = !cir.void
+
+module {
+
+cir.func private @flattened_resume() {
+ %exception_addr = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["exception", init] {alignment = 8 : i64}
+ %type_id_addr = cir.alloca !u32i, !cir.ptr<!u32i>, ["type_id", init] {alignment = 4 : i64}
+ %exception = cir.load %exception_addr : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
+ %type_id = cir.load %type_id_addr : !cir.ptr<!u32i>, !u32i
+ cir.resume.flat %exception, %type_id
+}
+
+
+// CHECK: llvm.func @flattened_resume() attributes {sym_visibility = "private"} {
+// CHECK: %[[CONST_1:.*]] = llvm.mlir.constant(1 : i64) : i64
+// CHECK: %[[EXCEPTION_ADDR:.*]] = llvm.alloca %[[CONST_1]] x !llvm.ptr {alignment = 8 : i64} : (i64) -> !llvm.ptr
+// CHECK: %[[CONST_1:.*]] = llvm.mlir.constant(1 : i64) : i64
+// CHECK: %[[TYPE_ID_ADDR:.*]] = llvm.alloca %[[CONST_1]] x i32 {alignment = 4 : i64} : (i64) -> !llvm.ptr
+// CHECK: %[[EXCEPTION:.*]] = llvm.load %[[EXCEPTION_ADDR]] {alignment = 8 : i64} : !llvm.ptr -> !llvm.ptr
+// CHECK: %[[TYPE_ID:.*]] = llvm.load %[[TYPE_ID_ADDR]] {alignment = 4 : i64} : !llvm.ptr -> i32
+// CHECK: %[[POISON:.*]] = llvm.mlir.poison : !llvm.struct<(ptr, i32)>
+// CHECK: %[[TMP_EXCEPTION_INFO:.*]] = llvm.insertvalue %[[EXCEPTION]], %[[POISON]][0] : !llvm.struct<(ptr, i32)>
+// CHECK: %[[EXCEPTION_INFO:.*]] = llvm.insertvalue %[[TYPE_ID]], %[[TMP_EXCEPTION_INFO]][1] : !llvm.struct<(ptr, i32)>
+// CHECK: llvm.resume %[[EXCEPTION_INFO]] : !llvm.struct<(ptr, i32)>
+// CHECK: }
+
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/172534
More information about the cfe-commits
mailing list