[clang] [CIR] Upstream Exceptions EHTypeIdOp (PR #172558)
Amr Hesham via cfe-commits
cfe-commits at lists.llvm.org
Mon Jan 5 13:08:02 PST 2026
https://github.com/AmrDeveloper updated https://github.com/llvm/llvm-project/pull/172558
>From 3a6a82e705d8314c614c35f5016d6a7183b19250 Mon Sep 17 00:00:00 2001
From: Amr Hesham <amr96 at programmer.net>
Date: Tue, 16 Dec 2025 22:12:58 +0100
Subject: [PATCH 1/2] [CIR] Upstream Exceptions EHTypeIdOp
---
clang/include/clang/CIR/Dialect/IR/CIROps.td | 24 +++++++++++++++++++
clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 13 ++++++++++
.../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 14 +++++++++++
clang/test/CIR/IR/eh-type-id.cir | 22 +++++++++++++++++
clang/test/CIR/Lowering/eh-type-id.cir | 23 ++++++++++++++++++
5 files changed, 96 insertions(+)
create mode 100644 clang/test/CIR/IR/eh-type-id.cir
create mode 100644 clang/test/CIR/Lowering/eh-type-id.cir
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 8358b076ee7b6..3fa46be31430c 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -5519,6 +5519,30 @@ def CIR_EhInflightOp : CIR_Op<"eh.inflight_exception"> {
}];
}
+//===----------------------------------------------------------------------===//
+// Exception related: EhTypeIdOp
+//===----------------------------------------------------------------------===//
+
+def CIR_EhTypeIdOp : CIR_Op<"eh.typeid",
+ [Pure, DeclareOpInterfaceMethods<SymbolUserOpInterface>]> {
+ let summary = "Compute exception type id from it's global type symbol";
+ let description = [{
+ Returns the exception type id for a given global symbol representing
+ a type.
+
+ Example:
+ ```mlir
+ %type_id = cir.eh.typeid @_ZTIi
+ ```
+ }];
+
+ let arguments = (ins FlatSymbolRefAttr:$type_sym);
+ let results = (outs CIR_UInt32:$type_id);
+ let assemblyFormat = [{
+ $type_sym attr-dict
+ }];
+}
+
//===----------------------------------------------------------------------===//
// Atomic operations
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 8f0dc705181e6..399d88c2dd910 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -3508,6 +3508,19 @@ static mlir::ParseResult parseTryHandlerRegions(
return mlir::success();
}
+//===----------------------------------------------------------------------===//
+// EhTypeIdOp
+//===----------------------------------------------------------------------===//
+
+LogicalResult
+cir::EhTypeIdOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
+ Operation *op = symbolTable.lookupNearestSymbolFrom(*this, getTypeSymAttr());
+ if (!isa<GlobalOp>(op))
+ return emitOpError("'")
+ << getTypeSym() << "' does not reference a valid cir.global";
+ return success();
+}
+
//===----------------------------------------------------------------------===//
// TableGen'd op method definitions
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 7686add38250e..134e9ce69b3f8 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -3470,6 +3470,20 @@ mlir::LogicalResult CIRToLLVMResumeFlatOpLowering::matchAndRewrite(
return mlir::success();
}
+mlir::LogicalResult CIRToLLVMEhTypeIdOpLowering::matchAndRewrite(
+ cir::EhTypeIdOp op, OpAdaptor adaptor,
+ mlir::ConversionPatternRewriter &rewriter) const {
+ mlir::Value addrOp = mlir::LLVM::AddressOfOp::create(
+ rewriter, op.getLoc(),
+ mlir::LLVM::LLVMPointerType::get(rewriter.getContext()),
+ op.getTypeSymAttr());
+ mlir::LLVM::CallIntrinsicOp newOp = createCallLLVMIntrinsicOp(
+ rewriter, op.getLoc(), "llvm.eh.typeid.for.p0", rewriter.getI32Type(),
+ mlir::ValueRange{addrOp});
+ rewriter.replaceOp(op, newOp);
+ return mlir::success();
+}
+
mlir::LogicalResult CIRToLLVMTrapOpLowering::matchAndRewrite(
cir::TrapOp op, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const {
diff --git a/clang/test/CIR/IR/eh-type-id.cir b/clang/test/CIR/IR/eh-type-id.cir
new file mode 100644
index 0000000000000..d9acfa96b6230
--- /dev/null
+++ b/clang/test/CIR/IR/eh-type-id.cir
@@ -0,0 +1,22 @@
+// RUN: cir-opt %s --verify-roundtrip | FileCheck %s
+
+!u32i = !cir.int<u, 32>
+!u8i = !cir.int<u, 8>
+!void = !cir.void
+
+module {
+
+cir.global "private" constant external @_ZTIi : !cir.ptr<!u8i>
+
+cir.func private @exception_handling_type_id() {
+ %type_id = cir.eh.typeid @_ZTIi
+ cir.return
+}
+
+// CHECK: cir.func private @exception_handling_type_id() {
+// CHECK: %[[TYPE_ID:.*]] = cir.eh.typeid @_ZTIi
+// CHECK: cir.return
+// CHECK: }
+
+}
+
diff --git a/clang/test/CIR/Lowering/eh-type-id.cir b/clang/test/CIR/Lowering/eh-type-id.cir
new file mode 100644
index 0000000000000..84a39a9860f4a
--- /dev/null
+++ b/clang/test/CIR/Lowering/eh-type-id.cir
@@ -0,0 +1,23 @@
+// RUN: cir-opt %s -cir-to-llvm -o %t.cir
+
+!u32i = !cir.int<u, 32>
+!u8i = !cir.int<u, 8>
+!void = !cir.void
+
+module {
+
+cir.global "private" constant external @_ZTIi : !cir.ptr<!u8i>
+
+cir.func private @exception_handling_type_id() {
+ %type_id = cir.eh.typeid @_ZTIi
+ cir.return
+}
+
+// CHECK: llvm.func @exception_handling_type_id() attributes {sym_visibility = "private"} {
+// CHECK: %[[GV_ADDR_OF:.*]] = llvm.mlir.addressof @_ZTIi : !llvm.ptr
+// CHECK: %[[TYPE_ID:.*]] = llvm.call_intrinsic "llvm.eh.typeid.for.p0"(%[[GV_ADDR_OF]]) : (!llvm.ptr) -> i32
+// CHECK: llvm.return
+// CHECK: }
+
+}
+
>From 0535fdaf8bda4297f83b034e6e777e0c49d3018d Mon Sep 17 00:00:00 2001
From: Amr Hesham <amr96 at programmer.net>
Date: Wed, 17 Dec 2025 20:44:24 +0100
Subject: [PATCH 2/2] Address code review comments
---
clang/include/clang/CIR/Dialect/IR/CIROps.td | 2 +-
clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 2 +-
.../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 6 ++----
clang/test/CIR/IR/invalid-eh-type-id.cir | 16 ++++++++++++++++
clang/test/CIR/Lowering/eh-type-id.cir | 2 +-
5 files changed, 21 insertions(+), 7 deletions(-)
create mode 100644 clang/test/CIR/IR/invalid-eh-type-id.cir
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 3fa46be31430c..4274ed25542b1 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -5525,7 +5525,7 @@ def CIR_EhInflightOp : CIR_Op<"eh.inflight_exception"> {
def CIR_EhTypeIdOp : CIR_Op<"eh.typeid",
[Pure, DeclareOpInterfaceMethods<SymbolUserOpInterface>]> {
- let summary = "Compute exception type id from it's global type symbol";
+ let summary = "Compute exception type id from its global type symbol";
let description = [{
Returns the exception type id for a given global symbol representing
a type.
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 399d88c2dd910..e1df5d5185a04 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -3515,7 +3515,7 @@ static mlir::ParseResult parseTryHandlerRegions(
LogicalResult
cir::EhTypeIdOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
Operation *op = symbolTable.lookupNearestSymbolFrom(*this, getTypeSymAttr());
- if (!isa<GlobalOp>(op))
+ if (!isa_and_nonnull<GlobalOp>(op))
return emitOpError("'")
<< getTypeSym() << "' does not reference a valid cir.global";
return success();
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 134e9ce69b3f8..cbd4550056c51 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -3477,10 +3477,8 @@ mlir::LogicalResult CIRToLLVMEhTypeIdOpLowering::matchAndRewrite(
rewriter, op.getLoc(),
mlir::LLVM::LLVMPointerType::get(rewriter.getContext()),
op.getTypeSymAttr());
- mlir::LLVM::CallIntrinsicOp newOp = createCallLLVMIntrinsicOp(
- rewriter, op.getLoc(), "llvm.eh.typeid.for.p0", rewriter.getI32Type(),
- mlir::ValueRange{addrOp});
- rewriter.replaceOp(op, newOp);
+ rewriter.replaceOpWithNewOp<mlir::LLVM::EhTypeidForOp>(
+ op, rewriter.getI32Type(), addrOp);
return mlir::success();
}
diff --git a/clang/test/CIR/IR/invalid-eh-type-id.cir b/clang/test/CIR/IR/invalid-eh-type-id.cir
new file mode 100644
index 0000000000000..9c90af45dffef
--- /dev/null
+++ b/clang/test/CIR/IR/invalid-eh-type-id.cir
@@ -0,0 +1,16 @@
+// RUN: cir-opt %s -verify-diagnostics -split-input-file
+
+!u32i = !cir.int<u, 32>
+!u8i = !cir.int<u, 8>
+!void = !cir.void
+
+module {
+
+cir.func private @exception_handling_type_id() {
+ // expected-error at +1 {{'cir.eh.typeid' op '_ZTIi' does not reference a valid cir.global}}
+ %type_id = cir.eh.typeid @_ZTIi
+ cir.return
+}
+
+}
+
diff --git a/clang/test/CIR/Lowering/eh-type-id.cir b/clang/test/CIR/Lowering/eh-type-id.cir
index 84a39a9860f4a..ada9f22f86a72 100644
--- a/clang/test/CIR/Lowering/eh-type-id.cir
+++ b/clang/test/CIR/Lowering/eh-type-id.cir
@@ -15,7 +15,7 @@ cir.func private @exception_handling_type_id() {
// CHECK: llvm.func @exception_handling_type_id() attributes {sym_visibility = "private"} {
// CHECK: %[[GV_ADDR_OF:.*]] = llvm.mlir.addressof @_ZTIi : !llvm.ptr
-// CHECK: %[[TYPE_ID:.*]] = llvm.call_intrinsic "llvm.eh.typeid.for.p0"(%[[GV_ADDR_OF]]) : (!llvm.ptr) -> i32
+// CHECK: %[[TYPE_ID:.*]] = llvm.intr.eh.typeid.for %[[GV_ADDR_OF]] : (!llvm.ptr) -> i32
// CHECK: llvm.return
// CHECK: }
More information about the cfe-commits
mailing list