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 <am...@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: } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits