Index: mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
===================================================================
--- mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -1542,6 +1542,15 @@
   let assemblyFormat = "$handle attr-dict";
 }
 
+//
+// Exception handling intrinsics.
+//
+
+def LLVM_EhTypeidForOp : LLVM_OneResultIntrOp<"eh.typeid.for"> {
+    let arguments = (ins LLVM_i8Ptr:$type_info);
+    let assemblyFormat = "$type_info attr-dict `:` type($res)";
+}
+
 //
 // Stack save/restore intrinsics.
 //
Index: mlir/test/Dialect/LLVMIR/roundtrip.mlir
===================================================================
--- mlir/test/Dialect/LLVMIR/roundtrip.mlir
+++ mlir/test/Dialect/LLVMIR/roundtrip.mlir
@@ -332,9 +332,11 @@
 
 // CHECK: ^[[BB1]]:
 // CHECK:   %[[lp:.*]] = llvm.landingpad cleanup (catch %[[a3]] : !llvm.ptr<ptr<i8>>) (catch %[[a6]] : !llvm.ptr<i8>) (filter %[[a2]] : !llvm.array<1 x i8>) : !llvm.struct<(ptr<i8>, i32)>
+// CHECK:   %{{.*}} = llvm.intr.eh.typeid.for %6 : i32
 // CHECK:   llvm.resume %[[lp]] : !llvm.struct<(ptr<i8>, i32)>
 ^bb1:
   %10 = llvm.landingpad cleanup (catch %3 : !llvm.ptr<ptr<i8>>) (catch %6 : !llvm.ptr<i8>) (filter %2 : !llvm.array<1 x i8>) : !llvm.struct<(ptr<i8>, i32)>
+  %11 = llvm.intr.eh.typeid.for %6 : i32
   llvm.resume %10 : !llvm.struct<(ptr<i8>, i32)>
 
 // CHECK: ^[[BB2]]:
Index: mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
===================================================================
--- mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
+++ mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
@@ -485,6 +485,13 @@
   llvm.return
 }
 
+// CHECK-LABEL: @eh_typeid_for
+llvm.func @eh_typeid_for(%arg0 : !llvm.ptr<i8>) {
+    // CHECK: call i32 @llvm.eh.typeid.for
+    %0 = llvm.intr.eh.typeid.for %arg0 : i32
+    llvm.return
+}
+
 // CHECK-LABEL: @stack_save
 llvm.func @stack_save() {
   // CHECK: call i8* @llvm.stacksave