[clang] ac46db6 - [CIR] Use HasAncestor trait in place of hand-written verifiers (#197271)
via cfe-commits
cfe-commits at lists.llvm.org
Tue May 12 12:49:37 PDT 2026
Author: Henrich Lauko
Date: 2026-05-12T21:49:32+02:00
New Revision: ac46db6dc49eb9fd8e35298e6c35aa6a5ac02f43
URL: https://github.com/llvm/llvm-project/commit/ac46db6dc49eb9fd8e35298e6c35aa6a5ac02f43
DIFF: https://github.com/llvm/llvm-project/commit/ac46db6dc49eb9fd8e35298e6c35aa6a5ac02f43.diff
LOG: [CIR] Use HasAncestor trait in place of hand-written verifiers (#197271)
Replace the verify() functions on BreakOp, ContinueOp, LocalInitOp, and
CoReturnOp - each of which just checked for a specific ancestor op -
with
the declarative MLIR HasAncestor / AncestorOneOf traits.
Added:
Modified:
clang/include/clang/CIR/Dialect/IR/CIROps.td
clang/lib/CIR/Dialect/IR/CIRDialect.cpp
clang/test/CIR/IR/invalid-co-return.cir
clang/test/CIR/IR/invalid-static-local.cir
Removed:
################################################################################
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 9d9aaec1b275a..7c4abd794be68 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -1023,7 +1023,12 @@ def CIR_YieldOp : CIR_Op<"yield", [
// BreakOp
//===----------------------------------------------------------------------===//
-def CIR_BreakOp : CIR_Op<"break", [Terminator]> {
+defvar CIR_LoopScopes = ["WhileOp", "DoWhileOp", "ForOp"];
+defvar CIR_BreakableScopes = !listconcat(CIR_LoopScopes, ["SwitchOp"]);
+
+def CIR_BreakOp : CIR_Op<"break", [
+ Terminator, AncestorOneOf<CIR_BreakableScopes>
+]> {
let summary = "C/C++ `break` statement equivalent";
let description = [{
The `cir.break` operation is used to cease the execution of the current loop
@@ -1031,7 +1036,6 @@ def CIR_BreakOp : CIR_Op<"break", [Terminator]> {
allowed within a breakable operations (loops and switches).
}];
let assemblyFormat = "attr-dict";
- let hasVerifier = 1;
let hasLLVMLowering = false;
}
@@ -1039,7 +1043,9 @@ def CIR_BreakOp : CIR_Op<"break", [Terminator]> {
// ContinueOp
//===----------------------------------------------------------------------===//
-def CIR_ContinueOp : CIR_Op<"continue", [Terminator]> {
+def CIR_ContinueOp : CIR_Op<"continue", [
+ Terminator, AncestorOneOf<CIR_LoopScopes>
+]> {
let summary = "C/C++ `continue` statement equivalent";
let description = [{
The `cir.continue` operation is used to end execution of the current
@@ -1047,7 +1053,6 @@ def CIR_ContinueOp : CIR_Op<"continue", [Terminator]> {
It is only allowed within loop regions.
}];
let assemblyFormat = "attr-dict";
- let hasVerifier = 1;
let hasLLVMLowering = false;
}
@@ -3846,7 +3851,8 @@ def CIR_FuncOp : CIR_Op<"func", [
//===----------------------------------------------------------------------===//
def CIR_LocalInitOp : CIR_Op<"local_init", [
- DeclareOpInterfaceMethods<SymbolUserOpInterface>, NoRegionArguments
+ DeclareOpInterfaceMethods<SymbolUserOpInterface>, NoRegionArguments,
+ HasAncestor<"FuncOp">
]> {
let summary = "initialize a static or thread local object";
let description = [{
@@ -3901,7 +3907,6 @@ def CIR_LocalInitOp : CIR_Op<"local_init", [
}
}];
- let hasVerifier = 1;
let hasLLVMLowering = false;
}
@@ -4317,7 +4322,7 @@ def CIR_CoroBodyOp : CIR_Op<"coro.body", [
//===----------------------------------------------------------------------===//
def CIR_CoReturnOp : CIR_Op<"co_return", [
- ReturnLike, Pure, Terminator
+ ReturnLike, Pure, Terminator, HasAncestor<"CoroBodyOp">
]> {
let summary = "Coroutine return operation";
let description = [{
@@ -4331,8 +4336,6 @@ def CIR_CoReturnOp : CIR_Op<"co_return", [
attr-dict
}];
- let hasVerifier = 1;
-
let hasLLVMLowering = false;
}
@@ -7209,7 +7212,7 @@ def CIR_TryOp : CIR_Op<"try",[
// CatchParamOp
//===----------------------------------------------------------------------===//
-def CIR_CatchParamOp : CIR_Op<"catch_param", [HasParent<"cir::TryOp">]> {
+def CIR_CatchParamOp : CIR_Op<"catch_param", [HasParent<"TryOp">]> {
let summary = "Represents the catch clause formal parameter";
let description = [{
The `cir.catch_param` is used to retrieve the exception object inside
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 74ef856c5a067..99b38be47121b 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -372,27 +372,10 @@ LogicalResult cir::DeleteArrayOp::verify() {
return success();
}
-//===----------------------------------------------------------------------===//
-// BreakOp
-//===----------------------------------------------------------------------===//
-
-LogicalResult cir::BreakOp::verify() {
- if (!getOperation()->getParentOfType<LoopOpInterface>() &&
- !getOperation()->getParentOfType<SwitchOp>())
- return emitOpError("must be within a loop");
- return success();
-}
-
//===----------------------------------------------------------------------===//
// LocalInitOp
//===----------------------------------------------------------------------===//
-LogicalResult cir::LocalInitOp::verify() {
- if (!getOperation()->getParentOfType<FuncOp>())
- return emitOpError("must be inside of a 'cir.func'");
- return success();
-}
-
LogicalResult
cir::LocalInitOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
cir::GlobalOp global = getReferencedGlobal(symbolTable);
@@ -525,16 +508,6 @@ OpFoldResult cir::ConstantOp::fold(FoldAdaptor /*adaptor*/) {
return getValue();
}
-//===----------------------------------------------------------------------===//
-// ContinueOp
-//===----------------------------------------------------------------------===//
-
-LogicalResult cir::ContinueOp::verify() {
- if (!getOperation()->getParentOfType<LoopOpInterface>())
- return emitOpError("must be within a loop");
- return success();
-}
-
//===----------------------------------------------------------------------===//
// CastOp
//===----------------------------------------------------------------------===//
@@ -3102,12 +3075,6 @@ LogicalResult cir::AwaitOp::verify() {
return success();
}
-LogicalResult cir::CoReturnOp::verify() {
- if (!getOperation()->getParentOfType<CoroBodyOp>())
- return emitOpError("must be inside a cir.coro.body");
- return success();
-}
-
//===----------------------------------------------------------------------===//
// CoroBody
//===----------------------------------------------------------------------===//
diff --git a/clang/test/CIR/IR/invalid-co-return.cir b/clang/test/CIR/IR/invalid-co-return.cir
index 6085bcfe3a408..115bfbac26d42 100644
--- a/clang/test/CIR/IR/invalid-co-return.cir
+++ b/clang/test/CIR/IR/invalid-co-return.cir
@@ -1,5 +1,5 @@
// RUN: cir-opt %s -verify-diagnostics -split-input-file
cir.func @must_be_inside_coro_body() {
- cir.co_return // expected-error {{must be inside a cir.coro.body}}
+ cir.co_return // expected-error {{expects ancestor op 'cir.coro.body'}}
}
diff --git a/clang/test/CIR/IR/invalid-static-local.cir b/clang/test/CIR/IR/invalid-static-local.cir
index 033d80e071ed9..2a4d22d9ceae0 100644
--- a/clang/test/CIR/IR/invalid-static-local.cir
+++ b/clang/test/CIR/IR/invalid-static-local.cir
@@ -65,7 +65,7 @@ module {
cir.global "private" internal static_local_guard<"_ZGVZ1fvE1y"> @_ZZ1fvE1y : !s32i
cir.global "private" internal @_AnotherGlobal = ctor : !s32i {
- // expected-error @below {{'cir.local_init' op must be inside of a 'cir.func'}}
+ // expected-error @below {{'cir.local_init' op expects ancestor op 'cir.func'}}
cir.local_init static_local @_ZZ1fvE1y ctor {
cir.yield
} dtor {
More information about the cfe-commits
mailing list