[clang] [CIR] Add is_implicit to ReturnOp (PR #174832)
Jasmine Tang via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 8 12:53:27 PST 2026
https://github.com/badumbatish updated https://github.com/llvm/llvm-project/pull/174832
>From bd5547ab1b9fed9cd932f2abf875e57c839e1a36 Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Mon, 15 Dec 2025 13:14:39 -0800
Subject: [PATCH 1/4] Add implicit return to return op
---
clang/include/clang/CIR/Dialect/IR/CIROps.td | 2 +-
clang/lib/CIR/CodeGen/CIRGenFunction.cpp | 8 ++++----
clang/lib/CIR/CodeGen/CIRGenFunction.h | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 8358b076ee7b6..7b4ae2bd51fb7 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -714,7 +714,7 @@ def CIR_ReturnOp : CIR_Op<"return", [
// The return operation takes an optional input operand to return. This
// value must match the return type of the enclosing function.
- let arguments = (ins Variadic<CIR_AnyType>:$input);
+ let arguments = (ins Variadic<CIR_AnyType>:$input, UnitAttr:$is_implicit);
// The return operation only emits the input in the format if it is present.
let assemblyFormat = "($input^ `:` type($input))? attr-dict ";
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index ac66d00950f05..48039747d5a33 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -352,7 +352,7 @@ void CIRGenFunction::LexicalScope::cleanup() {
insertCleanupAndLeave(curBlock);
}
-cir::ReturnOp CIRGenFunction::LexicalScope::emitReturn(mlir::Location loc) {
+cir::ReturnOp CIRGenFunction::LexicalScope::emitReturn(mlir::Location loc, bool isImplicit) {
CIRGenBuilderTy &builder = cgf.getBuilder();
// If we are on a coroutine, add the coro_end builtin call.
@@ -365,9 +365,9 @@ cir::ReturnOp CIRGenFunction::LexicalScope::emitReturn(mlir::Location loc) {
auto value = cir::LoadOp::create(
builder, loc, fn.getFunctionType().getReturnType(), *cgf.fnRetAlloca);
return cir::ReturnOp::create(builder, loc,
- llvm::ArrayRef(value.getResult()));
+ llvm::ArrayRef(value.getResult()), isImplicit);
}
- return cir::ReturnOp::create(builder, loc);
+ return cir::ReturnOp::create(builder, loc, {}, isImplicit);
}
// This is copied from CodeGenModule::MayDropFunctionReturn. This is a
@@ -410,7 +410,7 @@ void CIRGenFunction::LexicalScope::emitImplicitReturn() {
}
}
- (void)emitReturn(localScope->endLoc);
+ (void)emitReturn(localScope->endLoc, /*isImplicit=*/true);
}
cir::TryOp CIRGenFunction::LexicalScope::getClosestTryParent() {
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 49ebccc221950..721f4fd9622b4 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -1206,7 +1206,7 @@ class CIRGenFunction : public CIRGenTypeCache {
return b;
}
- cir::ReturnOp emitReturn(mlir::Location loc);
+ cir::ReturnOp emitReturn(mlir::Location loc, bool isImplicit = false);
void emitImplicitReturn();
public:
>From 02cd548294b05d4ccec6ef1eb29ad82525032732 Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Wed, 7 Jan 2026 10:57:10 -0800
Subject: [PATCH 2/4] Update test case
---
clang/test/CIR/CodeGen/basic.c | 10 +++++-----
clang/test/CIR/CodeGen/loop.cpp | 6 +++---
clang/test/CIR/CodeGen/member-functions.cpp | 6 +++---
clang/test/CIR/CodeGen/nullptr-init.cpp | 2 +-
4 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/clang/test/CIR/CodeGen/basic.c b/clang/test/CIR/CodeGen/basic.c
index 9268615bc9fb0..b2e180bcca1f1 100644
--- a/clang/test/CIR/CodeGen/basic.c
+++ b/clang/test/CIR/CodeGen/basic.c
@@ -94,7 +94,7 @@ int f3(void) {
// CIR-NEXT: %[[I:.*]] = cir.load{{.*}} %[[I_PTR]] : !cir.ptr<!s32i>, !s32i
// CIR-NEXT: cir.store{{.*}} %[[I]], %[[RV]] : !s32i, !cir.ptr<!s32i>
// CIR-NEXT: %[[R:.*]] = cir.load{{.*}} %[[RV]] : !cir.ptr<!s32i>, !s32i
-// CIR-NEXT: cir.return %[[R]] : !s32i
+// CIR-NEXT: cir.return %[[R]] : !s32i
// LLVM: define{{.*}} i32 @f3()
// LLVM-NEXT: %[[RV:.*]] = alloca i32, i64 1, align 4
@@ -118,7 +118,7 @@ void f4(void) {
}
// CIR: cir.func{{.*}} @f4()
-// CIR-NEXT: cir.return
+// CIR-NEXT: cir.return {is_implicit}
// LLVM: define{{.*}} void @f4()
// LLVM-NEXT: ret void
@@ -144,7 +144,7 @@ void f5(void) {
// CIR-NEXT: cir.yield
// CIR-NEXT: }
// CIR-NEXT: }
-// CIR-NEXT: cir.return
+// CIR-NEXT: cir.return {is_implicit}
// CIR-NEXT: }
// LLVM: define{{.*}} void @f5()
@@ -258,7 +258,7 @@ int f8(int *p) {
void f9() {}
// CIR: cir.func{{.*}} @f9()
-// CIR-NEXT: cir.return
+// CIR-NEXT: cir.return {is_implicit}
// LLVM: define{{.*}} void @f9()
// LLVM-NEXT: ret void
@@ -272,7 +272,7 @@ void f10(int arg0, ...) {}
// CIR: cir.func{{.*}} @f10(%[[ARG0:.*]]: !s32i loc({{.*}}), ...)
// CIR-NEXT: %[[ARG0_PTR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["arg0", init] {alignment = 4 : i64}
// CIR-NEXT: cir.store{{.*}} %[[ARG0]], %[[ARG0_PTR]] : !s32i, !cir.ptr<!s32i>
-// CIR-NEXT: cir.return
+// CIR-NEXT: cir.return {is_implicit}
// LLVM: define{{.*}} void @f10(i32 %[[ARG0:.*]], ...)
// LLVM-NEXT: %[[ARG0_PTR:.*]] = alloca i32, i64 1, align 4
diff --git a/clang/test/CIR/CodeGen/loop.cpp b/clang/test/CIR/CodeGen/loop.cpp
index 463434c38a1af..61713f60cb101 100644
--- a/clang/test/CIR/CodeGen/loop.cpp
+++ b/clang/test/CIR/CodeGen/loop.cpp
@@ -64,7 +64,7 @@ void l1() {
// CIR-NEXT: cir.yield
// CIR-NEXT: }
// CIR-NEXT: }
-// CIR-NEXT: cir.return
+// CIR-NEXT: cir.return {is_implicit}
// CIR-NEXT: }
// LLVM: define{{.*}} void @_Z2l1v(){{.*}}
@@ -114,7 +114,7 @@ void l2() {
// CIR-NEXT: cir.yield
// CIR-NEXT: }
// CIR-NEXT: }
-// CIR-NEXT: cir.return
+// CIR-NEXT: cir.return {is_implicit}
// CIR-NEXT: }
// LLVM: define{{.*}} void @_Z2l2v(){{.*}}
@@ -162,7 +162,7 @@ void l3() {
// CIR-NEXT: cir.yield
// CIR-NEXT: }
// CIR-NEXT: }
-// CIR-NEXT: cir.return
+// CIR-NEXT: cir.return {is_implicit}
// CIR-NEXT: }
// LLVM: define{{.*}} void @_Z2l3v(){{.*}}
diff --git a/clang/test/CIR/CodeGen/member-functions.cpp b/clang/test/CIR/CodeGen/member-functions.cpp
index d46345dbadd6d..f60a838075749 100644
--- a/clang/test/CIR/CodeGen/member-functions.cpp
+++ b/clang/test/CIR/CodeGen/member-functions.cpp
@@ -14,7 +14,7 @@ void C::f() {}
// CIR: %[[THIS_ADDR:.*]] = cir.alloca !cir.ptr<!rec_C>, !cir.ptr<!cir.ptr<!rec_C>>, ["this", init]
// CIR: cir.store %[[THIS_ARG]], %[[THIS_ADDR]] : !cir.ptr<!rec_C>, !cir.ptr<!cir.ptr<!rec_C>>
// CIR: %[[THIS:.*]] = cir.load %[[THIS_ADDR]] : !cir.ptr<!cir.ptr<!rec_C>>, !cir.ptr<!rec_C>
-// CIR: cir.return
+// CIR: cir.return {is_implicit}
// CIR: }
void C::f2(int a, int b) {}
@@ -27,7 +27,7 @@ void C::f2(int a, int b) {}
// CIR-NEXT: cir.store %[[A_ARG]], %[[A_ADDR]] : !s32i, !cir.ptr<!s32i>
// CIR-NEXT: cir.store %[[B_ARG]], %[[B_ADDR]] : !s32i, !cir.ptr<!s32i>
// CIR-NEXT: %[[THIS:.*]] = cir.load %[[THIS_ADDR]] : !cir.ptr<!cir.ptr<!rec_C>>, !cir.ptr<!rec_C>
-// CIR-NEXT: cir.return
+// CIR-NEXT: cir.return {is_implicit}
// CIR-NEXT: }
void test1() {
@@ -42,5 +42,5 @@ void test1() {
// CIR-NEXT: %[[ONE:.*]] = cir.const #cir.int<1> : !s32i
// CIR-NEXT: %[[TWO:.*]] = cir.const #cir.int<2> : !s32i
// CIR-NEXT: cir.call @_ZN1C2f2Eii(%[[C_ADDR]], %[[ONE]], %[[TWO]]) : (!cir.ptr<!rec_C>, !s32i, !s32i) -> ()
-// CIR-NEXT: cir.return
+// CIR-NEXT: cir.return {is_implicit}
// CIR-NEXT: }
diff --git a/clang/test/CIR/CodeGen/nullptr-init.cpp b/clang/test/CIR/CodeGen/nullptr-init.cpp
index 091269d09c985..73b01d4cad6b4 100644
--- a/clang/test/CIR/CodeGen/nullptr-init.cpp
+++ b/clang/test/CIR/CodeGen/nullptr-init.cpp
@@ -21,7 +21,7 @@ void t1() {
// CIR-NEXT: cir.store{{.*}} %[[NULLPTR2]], %[[P2]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
// CIR-NEXT: %[[NULLPTR3:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!s32i>
// CIR-NEXT: cir.store{{.*}} %[[NULLPTR3]], %[[P3]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
-// CIR-NEXT: cir.return
+// CIR-NEXT: cir.return {is_implicit}
// CIR-NEXT: }
// LLVM: define{{.*}} @_Z2t1v()
>From 0a76931c7d7bc43158c600df6f6c19271575b4d4 Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Wed, 7 Jan 2026 14:18:08 -0800
Subject: [PATCH 3/4] Reformat
---
clang/lib/CIR/CodeGen/CIRGenFunction.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index 48039747d5a33..0447a11f0aefa 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -352,7 +352,8 @@ void CIRGenFunction::LexicalScope::cleanup() {
insertCleanupAndLeave(curBlock);
}
-cir::ReturnOp CIRGenFunction::LexicalScope::emitReturn(mlir::Location loc, bool isImplicit) {
+cir::ReturnOp CIRGenFunction::LexicalScope::emitReturn(mlir::Location loc,
+ bool isImplicit) {
CIRGenBuilderTy &builder = cgf.getBuilder();
// If we are on a coroutine, add the coro_end builtin call.
>From cabb7699ae217a0b7047c37342b8f323b1e26527 Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Thu, 8 Jan 2026 12:53:13 -0800
Subject: [PATCH 4/4] Revert unnecessary spaces
---
clang/test/CIR/CodeGen/basic.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/test/CIR/CodeGen/basic.c b/clang/test/CIR/CodeGen/basic.c
index b2e180bcca1f1..2cbdd8fc5705e 100644
--- a/clang/test/CIR/CodeGen/basic.c
+++ b/clang/test/CIR/CodeGen/basic.c
@@ -94,7 +94,7 @@ int f3(void) {
// CIR-NEXT: %[[I:.*]] = cir.load{{.*}} %[[I_PTR]] : !cir.ptr<!s32i>, !s32i
// CIR-NEXT: cir.store{{.*}} %[[I]], %[[RV]] : !s32i, !cir.ptr<!s32i>
// CIR-NEXT: %[[R:.*]] = cir.load{{.*}} %[[RV]] : !cir.ptr<!s32i>, !s32i
-// CIR-NEXT: cir.return %[[R]] : !s32i
+// CIR-NEXT: cir.return %[[R]] : !s32i
// LLVM: define{{.*}} i32 @f3()
// LLVM-NEXT: %[[RV:.*]] = alloca i32, i64 1, align 4
More information about the cfe-commits
mailing list