https://github.com/RiverDave updated https://github.com/llvm/llvm-project/pull/196868
>From f62f8d8c6c84331b3e89e3c948811f0cd7df4cf5 Mon Sep 17 00:00:00 2001 From: David Rivera <[email protected]> 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 e9197e877560010d362d33033c0d30d12ed41b2c Mon Sep 17 00:00:00 2001 From: David Rivera <[email protected]> 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 54a4861d114a859835fa9a5971951c74f0e6e2b9 Mon Sep 17 00:00:00 2001 From: David Rivera <[email protected]> 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; } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
