diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp @@ -1263,6 +1263,21 @@ "llvm.landingpad needs to be in a function with a personality"); } + auto parentFunc = getOperation()->getParentOfType(); + if (!parentFunc) + return emitError("llvm.landingpad expects a parent operation implementing " + "FunctionOpInterface"); + + Type type = getType(); + if (parentFunc + .walk([type](LandingpadOp op) { + return op.getType() == type ? WalkResult::advance() + : WalkResult::interrupt(); + }) + .wasInterrupted()) + return emitError("llvm.landingpad expects other llvm.landingpad operations " + "in the same function to have the same type"); + if (!getCleanup() && getOperands().empty()) return emitError("landingpad instruction expects at least one clause or " "cleanup attribute"); diff --git a/mlir/test/Dialect/LLVMIR/invalid.mlir b/mlir/test/Dialect/LLVMIR/invalid.mlir --- a/mlir/test/Dialect/LLVMIR/invalid.mlir +++ b/mlir/test/Dialect/LLVMIR/invalid.mlir @@ -819,6 +819,35 @@ // ----- +"not.a.func"() ({ + // expected-error@+1 {{expects a parent operation implementing FunctionOpInterface}} + %0 = llvm.landingpad cleanup : !llvm.struct<(ptr, i32)> +}) : () -> () + +// ----- + +llvm.func @f0() -> i32 +llvm.func @f1(i32) -> i32 + +llvm.func @__gxx_personality_v0(...) -> i32 + +llvm.func @caller() -> i32 attributes { personality = @__gxx_personality_v0 } { + %0 = llvm.invoke @f0() to ^bb1 unwind ^bb2 : () -> i32 +^bb1: + %1 = llvm.invoke @f1(%0) to ^bb3 unwind ^bb4 : (i32) -> i32 +^bb2: + // expected-error@+1 {{llvm.landingpad expects other llvm.landingpad operations in the same function to have the same type}} + %2 = llvm.landingpad cleanup : !llvm.struct<(ptr, i32)> + llvm.resume %2 : !llvm.struct<(ptr, i32)> +^bb3: + llvm.return %1 : i32 +^bb4: + %3 = llvm.landingpad cleanup : i32 + llvm.resume %3 : i32 +} + +// ----- + func.func @invalid_ordering_in_fence() { // expected-error @+1 {{can be given only acquire, release, acq_rel, and seq_cst orderings}} llvm.fence syncscope("agent") monotonic