[clang] [CIR] Upstream emitAndUpdateRetAlloca (PR #129933)
Amr Hesham via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 5 12:43:14 PST 2025
https://github.com/AmrDeveloper created https://github.com/llvm/llvm-project/pull/129933
This change adds support for the basic case of emitAndUpdateRetAlloca
>From 1db2baafe9ed0ab360517810144300db0e7410f6 Mon Sep 17 00:00:00 2001
From: AmrDeveloper <amr96 at programmer.net>
Date: Wed, 5 Mar 2025 18:18:07 +0100
Subject: [PATCH] [CIR] Upstream emitAndUpdateRetAlloca
---
clang/lib/CIR/CodeGen/CIRGenFunction.cpp | 22 +++++++++++++
clang/lib/CIR/CodeGen/CIRGenFunction.h | 5 +++
clang/test/CIR/func-simple.cpp | 40 ++++++++++++++----------
3 files changed, 51 insertions(+), 16 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index 7861a48c93244..69f29826d5ab0 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -195,7 +195,16 @@ void CIRGenFunction::startFunction(GlobalDecl gd, QualType returnType,
mlir::Location fnBodyBegin = getLoc(fd->getBody()->getBeginLoc());
builder.CIRBaseBuilderTy::createStore(fnBodyBegin, paramVal, addrVal);
}
+
assert(builder.getInsertionBlock() && "Should be valid");
+
+ auto fnEndLoc = getLoc(fd->getBody()->getEndLoc());
+
+ // When the current function is not void, create an address to store the
+ // result value.
+ if (fnRetCIRTy.has_value())
+ emitAndUpdateRetAlloca(fnRetQualTy, fnEndLoc,
+ getContext().getTypeAlignInChars(fnRetQualTy));
}
void CIRGenFunction::finishFunction(SourceLocation endLoc) {}
@@ -213,6 +222,11 @@ mlir::LogicalResult CIRGenFunction::emitFunctionBody(const clang::Stmt *body) {
cir::FuncOp CIRGenFunction::generateCode(clang::GlobalDecl gd, cir::FuncOp fn,
cir::FuncType funcType) {
const auto funcDecl = cast<FunctionDecl>(gd.getDecl());
+ fnRetQualTy = funcDecl->getReturnType();
+ if (!fnRetQualTy->isVoidType()) {
+ fnRetCIRTy = convertType(fnRetQualTy);
+ }
+
SourceLocation loc = funcDecl->getLocation();
Stmt *body = funcDecl->getBody();
SourceRange bodyRange =
@@ -312,4 +326,12 @@ LValue CIRGenFunction::emitLValue(const Expr *e) {
}
}
+void CIRGenFunction::emitAndUpdateRetAlloca(QualType ty, mlir::Location loc,
+ CharUnits alignment) {
+ if (ty->isVoidType()) {
+ return;
+ }
+
+ emitAlloca("__retval", convertType(ty), loc, alignment);
+}
} // namespace clang::CIRGen
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 6b383378ae764..482f0e219a299 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -49,6 +49,8 @@ class CIRGenFunction : public CIRGenTypeCache {
public:
clang::QualType fnRetTy;
+ clang::QualType fnRetQualTy;
+ std::optional<mlir::Type> fnRetCIRTy;
/// This is the current function or global initializer that is generated code
/// for.
@@ -101,6 +103,9 @@ class CIRGenFunction : public CIRGenTypeCache {
clang::QualType ty, mlir::Location loc,
clang::CharUnits alignment, bool isParam = false);
+ void emitAndUpdateRetAlloca(clang::QualType ty, mlir::Location loc,
+ clang::CharUnits alignment);
+
public:
mlir::Value emitAlloca(llvm::StringRef name, mlir::Type ty,
mlir::Location loc, clang::CharUnits alignment);
diff --git a/clang/test/CIR/func-simple.cpp b/clang/test/CIR/func-simple.cpp
index d37ccc7229f22..a8488d628d8f7 100644
--- a/clang/test/CIR/func-simple.cpp
+++ b/clang/test/CIR/func-simple.cpp
@@ -13,8 +13,9 @@ void voidret() { return; }
int intfunc() { return 42; }
// CHECK: cir.func @intfunc() -> !cir.int<s, 32> {
-// CHECK: %0 = cir.const #cir.int<42> : !cir.int<s, 32>
-// CHECK: cir.return %0 : !cir.int<s, 32>
+// CHECK: %0 = cir.alloca !cir.int<s, 32>, !cir.ptr<!cir.int<s, 32>>, ["__retval"] {alignment = 4 : i64}
+// CHECK: %1 = cir.const #cir.int<42> : !cir.int<s, 32>
+// CHECK: cir.return %1 : !cir.int<s, 32>
// CHECK: }
int scopes() {
@@ -25,10 +26,11 @@ int scopes() {
}
}
// CHECK: cir.func @scopes() -> !cir.int<s, 32> {
+// CHECK: %0 = cir.alloca !cir.int<s, 32>, !cir.ptr<!cir.int<s, 32>>, ["__retval"] {alignment = 4 : i64}
// CHECK: cir.scope {
// CHECK: cir.scope {
-// CHECK: %0 = cir.const #cir.int<99> : !cir.int<s, 32>
-// CHECK: cir.return %0 : !cir.int<s, 32>
+// CHECK: %1 = cir.const #cir.int<99> : !cir.int<s, 32>
+// CHECK: cir.return %1 : !cir.int<s, 32>
// CHECK: }
// CHECK: }
// CHECK: cir.trap
@@ -36,36 +38,42 @@ int scopes() {
long longfunc() { return 42l; }
// CHECK: cir.func @longfunc() -> !cir.int<s, 64>
-// CHECK: %0 = cir.const #cir.int<42> : !cir.int<s, 64>
-// CHECK: cir.return %0 : !cir.int<s, 64>
+// CHECK: %0 = cir.alloca !cir.int<s, 64>, !cir.ptr<!cir.int<s, 64>>, ["__retval"] {alignment = 8 : i64}
+// CHECK: %1 = cir.const #cir.int<42> : !cir.int<s, 64>
+// CHECK: cir.return %1 : !cir.int<s, 64>
// CHECK: }
unsigned unsignedfunc() { return 42u; }
// CHECK: cir.func @unsignedfunc() -> !cir.int<u, 32>
-// CHECK: %0 = cir.const #cir.int<42> : !cir.int<u, 32>
-// CHECK: cir.return %0 : !cir.int<u, 32>
+// CHECK: %0 = cir.alloca !cir.int<u, 32>, !cir.ptr<!cir.int<u, 32>>, ["__retval"] {alignment = 4 : i64}
+// CHECK: %1 = cir.const #cir.int<42> : !cir.int<u, 32>
+// CHECK: cir.return %1 : !cir.int<u, 32>
// CHECK: }
unsigned long long ullfunc() { return 42ull; }
// CHECK: cir.func @ullfunc() -> !cir.int<u, 64>
-// CHECK: %0 = cir.const #cir.int<42> : !cir.int<u, 64>
-// CHECK: cir.return %0 : !cir.int<u, 64>
+// CHECK: %0 = cir.alloca !cir.int<u, 64>, !cir.ptr<!cir.int<u, 64>>, ["__retval"] {alignment = 8 : i64}
+// CHECK: %1 = cir.const #cir.int<42> : !cir.int<u, 64>
+// CHECK: cir.return %1 : !cir.int<u, 64>
// CHECK: }
bool boolfunc() { return true; }
// CHECK: cir.func @boolfunc() -> !cir.bool {
-// CHECK: %0 = cir.const #true
-// CHECK: cir.return %0 : !cir.bool
+// CHECK: %0 = cir.alloca !cir.bool, !cir.ptr<!cir.bool>, ["__retval"] {alignment = 1 : i64}
+// CHECK: %1 = cir.const #true
+// CHECK: cir.return %1 : !cir.bool
// CHECK: }
float floatfunc() { return 42.42f; }
// CHECK: cir.func @floatfunc() -> !cir.float {
-// CHECK: %0 = cir.const #cir.fp<4.242
-// CHECK: cir.return %0 : !cir.float
+// CHECK: %0 = cir.alloca !cir.float, !cir.ptr<!cir.float>, ["__retval"] {alignment = 4 : i64}
+// CHECK: %1 = cir.const #cir.fp<4.242
+// CHECK: cir.return %1 : !cir.float
// CHECK: }
double doublefunc() { return 42.42; }
// CHECK: cir.func @doublefunc() -> !cir.double {
-// CHECK: %0 = cir.const #cir.fp<4.242
-// CHECK: cir.return %0 : !cir.double
+// CHECK: %0 = cir.alloca !cir.double, !cir.ptr<!cir.double>, ["__retval"] {alignment = 8 : i64}
+// CHECK: %1 = cir.const #cir.fp<4.242
+// CHECK: cir.return %1 : !cir.double
// CHECK: }
More information about the cfe-commits
mailing list