[clang] [CIR][CIRGen] Cast stack allocas to the language-visible address space (PR #196868)
David Rivera via cfe-commits
cfe-commits at lists.llvm.org
Sun May 10 21:55:32 PDT 2026
https://github.com/RiverDave updated https://github.com/llvm/llvm-project/pull/196868
>From 11c8eed5b1c19bedf2b65a0c1d6fbd8a4a072acc Mon Sep 17 00:00:00 2001
From: David Rivera <davidriverg at gmail.com>
Date: Sun, 10 May 2026 23:42:04 -0400
Subject: [PATCH 1/3] [CIR][CIRGen] Cast stack allocas to the language-visible
address space
---
.../CIR/Dialect/Builder/CIRBaseBuilder.h | 4 +-
clang/lib/CIR/CodeGen/Address.h | 14 ++++
clang/lib/CIR/CodeGen/CIRGenDecl.cpp | 9 +--
clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 65 +++++++++++++------
clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp | 5 +-
clang/lib/CIR/CodeGen/CIRGenFunction.cpp | 13 ++--
clang/lib/CIR/CodeGen/CIRGenFunction.h | 12 ++++
.../CodeGen/amdgpu-call-addrspace-cast.cpp | 4 +-
.../amdgpu-stack-alloca-array-decay.cpp | 42 ++++++++++++
9 files changed, 134 insertions(+), 34 deletions(-)
create mode 100644 clang/test/CIR/CodeGen/amdgpu-stack-alloca-array-decay.cpp
diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index 646fc7eb3c226..573880ec1d69d 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -544,7 +544,9 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
mlir::Value createPtrBitcast(mlir::Value src, mlir::Type newPointeeTy) {
assert(mlir::isa<cir::PointerType>(src.getType()) && "expected ptr src");
- return createBitcast(src, getPointerTo(newPointeeTy));
+ auto srcPtrTy = mlir::cast<cir::PointerType>(src.getType());
+ return createBitcast(src,
+ getPointerTo(newPointeeTy, srcPtrTy.getAddrSpace()));
}
mlir::Value createPtrIsNull(mlir::Value ptr) {
diff --git a/clang/lib/CIR/CodeGen/Address.h b/clang/lib/CIR/CodeGen/Address.h
index b459ec948c2c4..2ebb3050951ec 100644
--- a/clang/lib/CIR/CodeGen/Address.h
+++ b/clang/lib/CIR/CodeGen/Address.h
@@ -18,6 +18,7 @@
#include "mlir/IR/Value.h"
#include "clang/AST/CharUnits.h"
#include "clang/CIR/Dialect/IR/CIRAttrs.h"
+#include "clang/CIR/Dialect/IR/CIRDialect.h"
#include "clang/CIR/Dialect/IR/CIRTypes.h"
#include "clang/CIR/MissingFeatures.h"
#include "llvm/ADT/PointerIntPair.h"
@@ -146,6 +147,19 @@ class Address {
return mlir::dyn_cast_or_null<OpTy>(getDefiningOp());
}
+ /// Return the underlying alloca for this address, if any.
+ ///
+ /// Addresses may refer to an alloca through a cast, for example when a target
+ /// stack address space is cast to the language-visible address space. Peel
+ /// those cast ops so callers that need to annotate the original alloca can still
+ /// find it.
+ cir::AllocaOp getUnderlyingAllocaOp() const {
+ mlir::Value ptr = getPointer();
+ while (auto castOp = ptr.getDefiningOp<cir::CastOp>())
+ ptr = castOp.getSrc();
+ return ptr.getDefiningOp<cir::AllocaOp>();
+ }
+
/// Whether the pointer is known not to be null.
bool isKnownNonNull() const {
assert(isValid() && "Invalid address");
diff --git a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
index 2bf90e99eb7d3..200939e82327c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
@@ -22,6 +22,7 @@
#include "clang/AST/ExprCXX.h"
#include "clang/Basic/Cuda.h"
#include "clang/CIR/Dialect/IR/CIRAttrs.h"
+#include "clang/CIR/Dialect/IR/CIRDialect.h"
#include "clang/CIR/MissingFeatures.h"
using namespace clang;
@@ -203,7 +204,7 @@ static void emitStoresForConstant(CIRGenModule &cgm, const VarDecl &d,
// The address is usually and alloca, but there is at least one case where
// emitAutoVarInit is called from the OpenACC codegen with an address that
// is not an alloca.
- auto allocaOp = addr.getDefiningOp<cir::AllocaOp>();
+ cir::AllocaOp allocaOp = addr.getUnderlyingAllocaOp();
if (allocaOp)
allocaOp.setInitAttr(mlir::UnitAttr::get(&cgm.getMLIRContext()));
@@ -303,9 +304,9 @@ void CIRGenFunction::emitAutoVarInit(
if (!emission.wasEmittedAsOffloadClause()) {
// In case lv has uses it means we indeed initialized something
// out of it while trying to build the expression, mark it as such.
- mlir::Value val = lv.getAddress().getPointer();
- assert(val && "Should have an address");
- auto allocaOp = val.getDefiningOp<cir::AllocaOp>();
+ Address addr = lv.getAddress();
+ assert(addr.isValid() && "Should have an address");
+ auto allocaOp = addr.getUnderlyingAllocaOp();
assert(allocaOp && "Address should come straight out of the alloca");
if (!allocaOp.use_empty())
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index cb53430438219..e1e460a32dd3d 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -491,7 +491,7 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr,
// Update the alloca with more info on initialization.
assert(addr.getPointer() && "expected pointer to exist");
- auto srcAlloca = addr.getDefiningOp<cir::AllocaOp>();
+ auto srcAlloca = addr.getUnderlyingAllocaOp();
if (currVarDecl && srcAlloca) {
const VarDecl *vd = currVarDecl;
assert(vd && "VarDecl expected");
@@ -1878,7 +1878,7 @@ static Address createReferenceTemporary(CIRGenFunction &cgf,
if (const ValueDecl *extDecl = m->getExtendingDecl()) {
auto extDeclAddrIter = cgf.localDeclMap.find(extDecl);
if (extDeclAddrIter != cgf.localDeclMap.end())
- extDeclAlloca = extDeclAddrIter->second.getDefiningOp<cir::AllocaOp>();
+ extDeclAlloca = extDeclAddrIter->second.getUnderlyingAllocaOp();
}
mlir::OpBuilder::InsertPoint ip;
if (extDeclAlloca) {
@@ -2720,8 +2720,9 @@ Address CIRGenFunction::createMemTemp(QualType ty, CharUnits align,
mlir::Location loc, const Twine &name,
Address *alloca,
mlir::OpBuilder::InsertPoint ip) {
- Address result = createTempAlloca(convertTypeForMem(ty), align, loc, name,
- /*ArraySize=*/nullptr, alloca, ip);
+ Address result =
+ createTempAlloca(convertTypeForMem(ty), /*destAddrSpace=*/{}, align, loc,
+ name, /*arraySize=*/nullptr, alloca, ip);
if (ty->isConstantMatrixType()) {
assert(!cir::MissingFeatures::matrixType());
cgm.errorNYI(loc, "temporary matrix value");
@@ -2741,33 +2742,57 @@ Address CIRGenFunction::createTempAllocaWithoutCast(
return Address(alloca, ty, align);
}
-/// This creates a alloca and inserts it into the entry block. The alloca is
-/// casted to default address space if necessary.
-// TODO(cir): Implement address space casting to match classic codegen's
-// CreateTempAlloca behavior with DestLangAS parameter
Address CIRGenFunction::createTempAlloca(mlir::Type ty, CharUnits align,
mlir::Location loc, const Twine &name,
mlir::Value arraySize,
Address *allocaAddr,
mlir::OpBuilder::InsertPoint ip) {
- Address alloca =
- createTempAllocaWithoutCast(ty, align, loc, name, arraySize, ip);
- if (allocaAddr)
- *allocaAddr = alloca;
- mlir::Value v = alloca.getPointer();
+ return createTempAlloca(ty, /*destAddrSpace=*/{}, align, loc, name, arraySize,
+ allocaAddr, ip);
+}
+
+Address CIRGenFunction::maybeCastStackAddressSpace(
+ Address alloca, mlir::ptr::MemorySpaceAttrInterface destAddrSpace,
+ mlir::Value arraySize) {
+ if (!destAddrSpace)
+ destAddrSpace = cir::toCIRAddressSpaceAttr(
+ getMLIRContext(), cgm.getLangTempAllocaAddressSpace());
+
+ mlir::ptr::MemorySpaceAttrInterface srcAddrSpace = getCIRAllocaAddressSpace();
// Alloca always returns a pointer in alloca address space, which may
// be different from the type defined by the language. For example,
// in C++ the auto variables are in the default address space. Therefore
// cast alloca to the default address space when necessary.
+ if (srcAddrSpace == destAddrSpace)
+ return alloca;
- cir::PointerType dstTy;
- if (getCIRAllocaAddressSpace())
- dstTy = builder.getPointerTo(ty, getCIRAllocaAddressSpace());
- else
- dstTy = builder.getPointerTo(ty, clang::LangAS::Default);
- v = performAddrSpaceCast(v, dstTy);
+ mlir::OpBuilder::InsertionGuard guard(builder);
+ if (!arraySize) {
+ mlir::Block *entryBlock = getCurFunctionEntryBlock();
+ builder.restoreInsertionPoint(builder.getBestAllocaInsertPoint(entryBlock));
+ } else if (cir::AllocaOp allocaOp = alloca.getUnderlyingAllocaOp()) {
+ builder.setInsertionPointAfter(allocaOp);
+ }
+
+ mlir::Type destPtrTy =
+ builder.getPointerTo(alloca.getElementType(), destAddrSpace);
+ mlir::Value casted = performAddrSpaceCast(alloca.getPointer(), destPtrTy);
+ return Address(casted, alloca.getElementType(), alloca.getAlignment(),
+ /*isKnownNonNull=*/true);
+}
- return Address(v, ty, align);
+/// This creates a alloca and inserts it into the entry block. The alloca is
+/// casted to the requested language address space if necessary.
+Address CIRGenFunction::createTempAlloca(
+ mlir::Type ty, mlir::ptr::MemorySpaceAttrInterface destAddrSpace,
+ CharUnits align, mlir::Location loc, const Twine &name,
+ mlir::Value arraySize, Address *allocaAddr,
+ mlir::OpBuilder::InsertPoint ip) {
+ Address alloca =
+ createTempAllocaWithoutCast(ty, align, loc, name, arraySize, ip);
+ if (allocaAddr)
+ *allocaAddr = alloca;
+ return maybeCastStackAddressSpace(alloca, destAddrSpace, arraySize);
}
/// This creates an alloca and inserts it into the entry block if \p ArraySize
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
index c7b11aa3f0009..5d2a9f57cdc00 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
@@ -19,6 +19,7 @@
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/Basic/OperatorKinds.h"
+#include "clang/CIR/Dialect/IR/CIRDialect.h"
#include "clang/CIR/MissingFeatures.h"
#include "llvm/ADT/Sequence.h"
#include "llvm/Support/TrailingObjects.h"
@@ -963,7 +964,9 @@ static void enterNewDeleteCleanup(CIRGenFunction &cgf, const CXXNewExpr *e,
typedef mlir::Value ValueTy;
typedef mlir::Value RValueTy;
static RValue get(CIRGenFunction &cgf, ValueTy v) {
- auto alloca = v.getDefiningOp<cir::AllocaOp>();
+ while (auto castOp = v.getDefiningOp<cir::CastOp>())
+ v = castOp.getSrc();
+ cir::AllocaOp alloca = v.getDefiningOp<cir::AllocaOp>();
return RValue::get(cgf.getBuilder().createAlignedLoad(
alloca.getLoc(), alloca.getAllocaType(), alloca,
llvm::MaybeAlign(alloca.getAlignment())));
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index 3e38f678a7474..e81649d805d04 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -19,6 +19,7 @@
#include "clang/AST/Attr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/GlobalDecl.h"
+#include "clang/CIR/Dialect/IR/CIRDialect.h"
#include "clang/CIR/MissingFeatures.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/IR/FPEnv.h"
@@ -218,10 +219,9 @@ bool CIRGenFunction::constantFoldsToSimpleInteger(const Expr *cond,
void CIRGenFunction::emitAndUpdateRetAlloca(QualType type, mlir::Location loc,
CharUnits alignment) {
if (!type->isVoidType()) {
- mlir::Value addr = emitAlloca("__retval", convertType(type), loc, alignment,
- /*insertIntoFnEntryBlock=*/false);
- fnRetAlloca = addr;
- returnValue = Address(addr, alignment);
+ Address allocaAddr = Address::invalid();
+ returnValue = createMemTemp(type, alignment, loc, "__retval", &allocaAddr);
+ fnRetAlloca = allocaAddr.getPointer();
}
}
@@ -231,7 +231,8 @@ void CIRGenFunction::declare(mlir::Value addrVal, const Decl *var, QualType ty,
assert(isa<NamedDecl>(var) && "Needs a named decl");
assert(!symbolTable.count(var) && "not supposed to be available just yet");
- auto allocaOp = addrVal.getDefiningOp<cir::AllocaOp>();
+ Address addr(addrVal, convertTypeForMem(ty), alignment);
+ cir::AllocaOp allocaOp = addr.getUnderlyingAllocaOp();
assert(allocaOp && "expected cir::AllocaOp");
if (isParam)
@@ -239,7 +240,7 @@ void CIRGenFunction::declare(mlir::Value addrVal, const Decl *var, QualType ty,
if (ty->isReferenceType() || ty.isConstQualified())
allocaOp.setConstantAttr(mlir::UnitAttr::get(&getMLIRContext()));
- symbolTable.insert(var, allocaOp);
+ symbolTable.insert(var, addrVal);
}
void CIRGenFunction::LexicalScope::cleanup() {
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index de91b2f903018..8ab5f4d21b1f1 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -2283,11 +2283,23 @@ class CIRGenFunction : public CIRGenTypeCache {
mlir::Value arraySize = nullptr,
Address *alloca = nullptr,
mlir::OpBuilder::InsertPoint ip = {});
+ Address
+ createTempAlloca(mlir::Type ty,
+ mlir::ptr::MemorySpaceAttrInterface destAddrSpace,
+ CharUnits align, mlir::Location loc,
+ const Twine &name = "tmp",
+ mlir::Value arraySize = nullptr,
+ Address *alloca = nullptr,
+ mlir::OpBuilder::InsertPoint ip = {});
Address createTempAllocaWithoutCast(mlir::Type ty, CharUnits align,
mlir::Location loc,
const Twine &name = "tmp",
mlir::Value arraySize = nullptr,
mlir::OpBuilder::InsertPoint ip = {});
+ Address
+ maybeCastStackAddressSpace(Address alloca,
+ mlir::ptr::MemorySpaceAttrInterface destAddrSpace,
+ mlir::Value arraySize);
Address createDefaultAlignTempAlloca(mlir::Type ty, mlir::Location loc,
const Twine &name);
diff --git a/clang/test/CIR/CodeGen/amdgpu-call-addrspace-cast.cpp b/clang/test/CIR/CodeGen/amdgpu-call-addrspace-cast.cpp
index 6b98ea10fceac..3217addeca800 100644
--- a/clang/test/CIR/CodeGen/amdgpu-call-addrspace-cast.cpp
+++ b/clang/test/CIR/CodeGen/amdgpu-call-addrspace-cast.cpp
@@ -30,12 +30,12 @@ void call_with_global_ptr() {
// CIR-LABEL: cir.func{{.*}} @_Z19call_with_local_ptrv()
// CIR: %[[ALLOCA:.*]] = cir.alloca !s32i, !cir.ptr<!s32i, target_address_space(5)>
// CIR: %[[CAST:.*]] = cir.cast address_space %[[ALLOCA]] : !cir.ptr<!s32i, target_address_space(5)> -> !cir.ptr<!s32i>
-// CIR-NEXT: cir.call @_Z9takes_ptrPi(%[[CAST]])
+// CIR: cir.call @_Z9takes_ptrPi(%[[CAST]])
// LLVM-LABEL: define{{.*}} void @_Z19call_with_local_ptrv()
// LLVM: %[[ALLOCA:.*]] = alloca i32, i64 1, align 4, addrspace(5)
// LLVM: %[[CAST:.*]] = addrspacecast ptr addrspace(5) %[[ALLOCA]] to ptr
-// LLVM-NEXT: call void @_Z9takes_ptrPi(ptr noundef %[[CAST]])
+// LLVM: call void @_Z9takes_ptrPi(ptr noundef %[[CAST]])
// OGCG-LABEL: define{{.*}} void @_Z19call_with_local_ptrv()
// OGCG: %[[ALLOCA:.*]] = alloca i32, align 4, addrspace(5)
diff --git a/clang/test/CIR/CodeGen/amdgpu-stack-alloca-array-decay.cpp b/clang/test/CIR/CodeGen/amdgpu-stack-alloca-array-decay.cpp
new file mode 100644
index 0000000000000..725a78016e50e
--- /dev/null
+++ b/clang/test/CIR/CodeGen/amdgpu-stack-alloca-array-decay.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa \
+// RUN: -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR
+
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa \
+// RUN: -fclangir -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s --check-prefix=LLVM
+
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa \
+// RUN: -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s --check-prefix=OGCG
+
+void foo() {
+ const char fmt[] = "hello";
+ const char *tmp = fmt;
+ while (*tmp++)
+ ;
+}
+
+// CIR-LABEL: cir.func{{.*}} @_Z3foov()
+// CIR: %[[FMT_RAW:.*]] = cir.alloca !cir.array<!s8i x 6>, !cir.ptr<!cir.array<!s8i x 6>, target_address_space(5)>, ["fmt"
+// CIR-NEXT: %[[TMP_RAW:.*]] = cir.alloca !cir.ptr<!s8i>, !cir.ptr<!cir.ptr<!s8i>, target_address_space(5)>, ["tmp"
+// CIR-DAG: %[[FMT:.*]] = cir.cast address_space %[[FMT_RAW]] : !cir.ptr<!cir.array<!s8i x 6>, target_address_space(5)> -> !cir.ptr<!cir.array<!s8i x 6>>
+// CIR-DAG: %[[TMP:.*]] = cir.cast address_space %[[TMP_RAW]] : !cir.ptr<!cir.ptr<!s8i>, target_address_space(5)> -> !cir.ptr<!cir.ptr<!s8i>>
+// CIR: %[[DECAY:.*]] = cir.cast array_to_ptrdecay %[[FMT]] : !cir.ptr<!cir.array<!s8i x 6>> -> !cir.ptr<!s8i>
+// CIR: cir.store{{.*}} %[[DECAY]], %[[TMP]] : !cir.ptr<!s8i>, !cir.ptr<!cir.ptr<!s8i>>
+
+// LLVM-LABEL: define{{.*}} void @_Z3foov()
+// LLVM: %[[FMT:.*]] = alloca [6 x i8], i64 1, align 1, addrspace(5)
+// LLVM-NEXT: %[[TMP:.*]] = alloca ptr, i64 1, align 8, addrspace(5)
+// LLVM-DAG: %[[FMT_CAST:.*]] = addrspacecast ptr addrspace(5) %[[FMT]] to ptr
+// LLVM-DAG: %[[TMP_CAST:.*]] = addrspacecast ptr addrspace(5) %[[TMP]] to ptr
+// LLVM: %[[DECAY:.*]] = getelementptr {{.*}} ptr %[[FMT_CAST]],
+// LLVM: store ptr %[[DECAY]], ptr %[[TMP_CAST]], align 8
+
+// OGCG-LABEL: define{{.*}} void @_Z3foov()
+// OGCG: %[[FMT:.*]] = alloca [6 x i8], align 1, addrspace(5)
+// OGCG-NEXT: %[[TMP:.*]] = alloca ptr, align 8, addrspace(5)
+// OGCG-NEXT: %[[FMT_CAST:.*]] = addrspacecast ptr addrspace(5) %[[FMT]] to ptr
+// OGCG-NEXT: %[[TMP_CAST:.*]] = addrspacecast ptr addrspace(5) %[[TMP]] to ptr
+// OGCG: %[[DECAY:.*]] = getelementptr inbounds [6 x i8], ptr %[[FMT_CAST]], i64 0, i64 0
+// OGCG: store ptr %[[DECAY]], ptr %[[TMP_CAST]], align 8
>From 07aad88097a3586e13da48fbbec1f0376e9183a5 Mon Sep 17 00:00:00 2001
From: David Rivera <davidriverg at gmail.com>
Date: Mon, 11 May 2026 00:07:30 -0400
Subject: [PATCH 2/3] fix fmt and some coding conventions
---
.../clang/CIR/Dialect/Builder/CIRBaseBuilder.h | 2 +-
clang/lib/CIR/CodeGen/Address.h | 4 ++--
clang/lib/CIR/CodeGen/CIRGenDecl.cpp | 2 +-
clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 2 +-
clang/lib/CIR/CodeGen/CIRGenFunction.h | 15 +++++++--------
5 files changed, 12 insertions(+), 13 deletions(-)
diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index 573880ec1d69d..82a81ab4db596 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -544,7 +544,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
mlir::Value createPtrBitcast(mlir::Value src, mlir::Type newPointeeTy) {
assert(mlir::isa<cir::PointerType>(src.getType()) && "expected ptr src");
- auto srcPtrTy = mlir::cast<cir::PointerType>(src.getType());
+ cir::PointerType srcPtrTy = mlir::cast<cir::PointerType>(src.getType());
return createBitcast(src,
getPointerTo(newPointeeTy, srcPtrTy.getAddrSpace()));
}
diff --git a/clang/lib/CIR/CodeGen/Address.h b/clang/lib/CIR/CodeGen/Address.h
index 2ebb3050951ec..22fe1d83f7869 100644
--- a/clang/lib/CIR/CodeGen/Address.h
+++ b/clang/lib/CIR/CodeGen/Address.h
@@ -151,8 +151,8 @@ class Address {
///
/// Addresses may refer to an alloca through a cast, for example when a target
/// stack address space is cast to the language-visible address space. Peel
- /// those cast ops so callers that need to annotate the original alloca can still
- /// find it.
+ /// those cast ops so callers that need to annotate the original alloca can
+ /// still find it.
cir::AllocaOp getUnderlyingAllocaOp() const {
mlir::Value ptr = getPointer();
while (auto castOp = ptr.getDefiningOp<cir::CastOp>())
diff --git a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
index 200939e82327c..94e2bec69b6c4 100644
--- a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
@@ -306,7 +306,7 @@ void CIRGenFunction::emitAutoVarInit(
// out of it while trying to build the expression, mark it as such.
Address addr = lv.getAddress();
assert(addr.isValid() && "Should have an address");
- auto allocaOp = addr.getUnderlyingAllocaOp();
+ cir::AllocaOp allocaOp = addr.getUnderlyingAllocaOp();
assert(allocaOp && "Address should come straight out of the alloca");
if (!allocaOp.use_empty())
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index e1e460a32dd3d..f6e1245d8c298 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -491,7 +491,7 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr,
// Update the alloca with more info on initialization.
assert(addr.getPointer() && "expected pointer to exist");
- auto srcAlloca = addr.getUnderlyingAllocaOp();
+ cir::AllocaOp srcAlloca = addr.getUnderlyingAllocaOp();
if (currVarDecl && srcAlloca) {
const VarDecl *vd = currVarDecl;
assert(vd && "VarDecl expected");
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 8ab5f4d21b1f1..cb5516da97f9a 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -2283,14 +2283,13 @@ class CIRGenFunction : public CIRGenTypeCache {
mlir::Value arraySize = nullptr,
Address *alloca = nullptr,
mlir::OpBuilder::InsertPoint ip = {});
- Address
- createTempAlloca(mlir::Type ty,
- mlir::ptr::MemorySpaceAttrInterface destAddrSpace,
- CharUnits align, mlir::Location loc,
- const Twine &name = "tmp",
- mlir::Value arraySize = nullptr,
- Address *alloca = nullptr,
- mlir::OpBuilder::InsertPoint ip = {});
+ Address createTempAlloca(mlir::Type ty,
+ mlir::ptr::MemorySpaceAttrInterface destAddrSpace,
+ CharUnits align, mlir::Location loc,
+ const Twine &name = "tmp",
+ mlir::Value arraySize = nullptr,
+ Address *alloca = nullptr,
+ mlir::OpBuilder::InsertPoint ip = {});
Address createTempAllocaWithoutCast(mlir::Type ty, CharUnits align,
mlir::Location loc,
const Twine &name = "tmp",
>From 805e38cc2d4f9ce55b128fdb25185e92603276af Mon Sep 17 00:00:00 2001
From: David Rivera <davidriverg at gmail.com>
Date: Mon, 11 May 2026 00:55:19 -0400
Subject: [PATCH 3/3] Fix tests
---
clang/include/clang/CIR/MissingFeatures.h | 1 +
clang/lib/CIR/CodeGen/Address.h | 13 ++++++++-----
clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp | 5 ++++-
clang/lib/CIR/CodeGen/CIRGenModule.cpp | 8 +++++---
4 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index ba5c2bf786a99..61361cc31c0a2 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -308,6 +308,7 @@ struct MissingFeatures {
static bool msvcBuiltins() { return false; }
static bool openCL() { return false; }
static bool openMP() { return false; }
+ static bool sycl() { return false; }
static bool opTBAA() { return false; }
static bool peepholeProtection() { return false; }
static bool pgoUse() { return false; }
diff --git a/clang/lib/CIR/CodeGen/Address.h b/clang/lib/CIR/CodeGen/Address.h
index 22fe1d83f7869..233fb74d2103d 100644
--- a/clang/lib/CIR/CodeGen/Address.h
+++ b/clang/lib/CIR/CodeGen/Address.h
@@ -149,14 +149,17 @@ class Address {
/// Return the underlying alloca for this address, if any.
///
- /// Addresses may refer to an alloca through a cast, for example when a target
- /// stack address space is cast to the language-visible address space. Peel
- /// those cast ops so callers that need to annotate the original alloca can
- /// still find it.
+ /// Addresses may refer to an alloca through an address space cast, for
+ /// example when a target stack address space is cast to the language-visible
+ /// address space. Peel those casts so callers that need to annotate the
+ /// original alloca can still find it.
cir::AllocaOp getUnderlyingAllocaOp() const {
mlir::Value ptr = getPointer();
- while (auto castOp = ptr.getDefiningOp<cir::CastOp>())
+ while (cir::CastOp castOp = ptr.getDefiningOp<cir::CastOp>()) {
+ if (castOp.getKind() != cir::CastKind::address_space)
+ break;
ptr = castOp.getSrc();
+ }
return ptr.getDefiningOp<cir::AllocaOp>();
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
index 5d2a9f57cdc00..c4e21d1edc2ac 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
@@ -964,8 +964,11 @@ static void enterNewDeleteCleanup(CIRGenFunction &cgf, const CXXNewExpr *e,
typedef mlir::Value ValueTy;
typedef mlir::Value RValueTy;
static RValue get(CIRGenFunction &cgf, ValueTy v) {
- while (auto castOp = v.getDefiningOp<cir::CastOp>())
+ while (cir::CastOp castOp = v.getDefiningOp<cir::CastOp>()) {
+ if (castOp.getKind() != cir::CastKind::address_space)
+ break;
v = castOp.getSrc();
+ }
cir::AllocaOp alloca = v.getDefiningOp<cir::AllocaOp>();
return RValue::get(cgf.getBuilder().createAlignedLoad(
alloca.getLoc(), alloca.getAllocaType(), alloca,
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 04e413aa916ec..35f506144d40a 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -2109,9 +2109,11 @@ LangAS CIRGenModule::getLangTempAllocaAddressSpace() const {
if (getLangOpts().CUDAIsDevice)
return LangAS::Default;
- if (getLangOpts().SYCLIsDevice ||
- (getLangOpts().OpenMP && getLangOpts().OpenMPIsTargetDevice))
- errorNYI("SYCL or OpenMP temp address space");
+ if (getLangOpts().OpenMP && getLangOpts().OpenMPIsTargetDevice)
+ assert(!cir::MissingFeatures::openMP());
+ if (getLangOpts().SYCLIsDevice)
+ assert(!cir::MissingFeatures::sycl());
+
return LangAS::Default;
}
More information about the cfe-commits
mailing list