From d07e73b3821cb9ec34b691707458a5a7a8d2ac49 Mon Sep 17 00:00:00 2001 From: Andy Kaylor Date: Wed, 19 Feb 2025 17:04:31 -0800 Subject: [PATCH 1/2] [CIR] Fix Address element type problems There were problems with the pointer type and element type of the Address class getting out of sync. In the traditional codegen the pointer has no type, so it was sufficient for the Address class to simply track the type it was supposed to be pointing to. Since ClangIR pointer values are typed, the Address::withType function wasn't really doing what it was supposed to. It returned an object with the same pointer that the original object had, but with a mismatched element type. This change removes the Address::withType function and replaces calls to it with CIRGenBuilder::createElementBitCast. It also adds assertions in the Address class to verify that pointer type and element type are consistent and updates many places that were causing those assertions to fire. These code changes cause extra bitcasts to be emitted in a few places. Regression tests have been updated as needed to reflect the CIR that is now generated. --- clang/lib/CIR/CodeGen/Address.h | 19 +++++++++---------- clang/lib/CIR/CodeGen/CIRAsm.cpp | 13 ++++++++----- clang/lib/CIR/CodeGen/CIRGenAtomic.cpp | 13 ++++++++----- clang/lib/CIR/CodeGen/CIRGenBuilder.h | 4 ++-- .../lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp | 3 ++- clang/lib/CIR/CodeGen/CIRGenCXX.cpp | 3 +-- clang/lib/CIR/CodeGen/CIRGenClass.cpp | 4 ++-- clang/lib/CIR/CodeGen/CIRGenDecl.cpp | 6 ++---- clang/lib/CIR/CodeGen/CIRGenException.cpp | 3 ++- clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 3 ++- clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp | 4 +++- clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp | 14 ++++++++++---- clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 4 ++-- clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp | 16 +++++++++++----- clang/test/CIR/CodeGen/atomic-thread-fence.c | 10 ++++++---- clang/test/CIR/CodeGen/atomic-xchg-field.c | 5 +++-- clang/test/CIR/CodeGen/atomic.cpp | 6 +++--- clang/test/CIR/CodeGen/union-init.c | 6 +++--- 18 files changed, 79 insertions(+), 57 deletions(-) diff --git a/clang/lib/CIR/CodeGen/Address.h b/clang/lib/CIR/CodeGen/Address.h index b88bd4378647..990d9b64a286 100644 --- a/clang/lib/CIR/CodeGen/Address.h +++ b/clang/lib/CIR/CodeGen/Address.h @@ -64,6 +64,9 @@ class Address { assert(pointer && "Pointer cannot be null"); assert(elementType && "Element type cannot be null"); assert(!alignment.isZero() && "Alignment cannot be zero"); + + assert(mlir::cast(pointer.getType()).getPointee() == + ElementType); } Address(mlir::Value basePtr, mlir::Type elementType, @@ -104,16 +107,6 @@ class Address { bool hasOffset() const { return bool(offset); } - /// Return address with different element type, but same pointer and - /// alignment. - Address withElementType(mlir::Type ElemTy) const { - if (!hasOffset()) - return Address(getBasePointer(), ElemTy, getAlignment(), - getPointerAuthInfo(), /*Offset=*/nullptr, - isKnownNonNull()); - return Address(getPointer(), ElemTy, getAlignment(), isKnownNonNull()); - } - mlir::Value getPointer() const { assert(isValid()); return PointerAndKnownNonNull.getPointer(); @@ -142,11 +135,17 @@ class Address { /// Return the type of the pointer value. cir::PointerType getType() const { + assert(mlir::cast( + PointerAndKnownNonNull.getPointer().getType()) + .getPointee() == ElementType); return mlir::cast(getPointer().getType()); } mlir::Type getElementType() const { assert(isValid()); + assert(mlir::cast( + PointerAndKnownNonNull.getPointer().getType()) + .getPointee() == ElementType); return ElementType; } diff --git a/clang/lib/CIR/CodeGen/CIRAsm.cpp b/clang/lib/CIR/CodeGen/CIRAsm.cpp index 498311280e20..d3de289d6f5a 100644 --- a/clang/lib/CIR/CodeGen/CIRAsm.cpp +++ b/clang/lib/CIR/CodeGen/CIRAsm.cpp @@ -214,9 +214,9 @@ std::pair CIRGenFunction::emitAsmInputLValue( getTargetHooks().isScalarizableAsmOperand(*this, Ty)) { Ty = cir::IntType::get(&getMLIRContext(), Size, false); - return {builder.createLoad(getLoc(Loc), - InputValue.getAddress().withElementType(Ty)), - mlir::Type()}; + auto InputAddr = builder.createElementBitCast( + getLoc(Loc), InputValue.getAddress(), Ty); + return {builder.createLoad(getLoc(Loc), InputAddr), mlir::Type()}; } } @@ -320,7 +320,8 @@ static void emitAsmStores(CIRGenFunction &CGF, const AsmStmt &S, // ResultTypeRequiresCast.size() elements of RegResults. if ((i < ResultTypeRequiresCast.size()) && ResultTypeRequiresCast[i]) { unsigned Size = CGF.getContext().getTypeSize(ResultRegQualTys[i]); - Address A = Dest.getAddress().withElementType(ResultRegTypes[i]); + Address A = Builder.createElementBitCast( + Dest.getPointer().getLoc(), Dest.getAddress(), ResultRegTypes[i]); if (CGF.getTargetHooks().isScalarizableAsmOperand(CGF, TruncTy)) { Builder.createStore(CGF.getLoc(S.getAsmLoc()), Tmp, A); continue; @@ -478,7 +479,9 @@ mlir::LogicalResult CIRGenFunction::emitAsmStmt(const AsmStmt &S) { // Otherwise there will be a mis-match if the matrix is also an // input-argument which is represented as vector. if (isa(OutExpr->getType().getCanonicalType())) - DestAddr = DestAddr.withElementType(convertType(OutExpr->getType())); + DestAddr = builder.createElementBitCast( + DestAddr.getPointer().getLoc(), DestAddr, + convertType(OutExpr->getType())); ArgTypes.push_back(DestAddr.getType()); ArgElemTypes.push_back(DestAddr.getElementType()); diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp index ddd6c78d20b3..12db9389f47a 100644 --- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp @@ -305,7 +305,8 @@ Address AtomicInfo::castToAtomicIntPointer(Address addr) const { if (intTy && intTy.getWidth() == AtomicSizeInBits) return addr; auto ty = CGF.getBuilder().getUIntNTy(AtomicSizeInBits); - return addr.withElementType(ty); + return CGF.getBuilder().createElementBitCast(addr.getPointer().getLoc(), addr, + ty); } Address AtomicInfo::convertToAtomicIntPointer(Address Addr) const { @@ -1243,8 +1244,9 @@ RValue CIRGenFunction::emitAtomicExpr(AtomicExpr *E) { if (RValTy->isVoidType()) return RValue::get(nullptr); - return convertTempToRValue(Dest.withElementType(convertTypeForMem(RValTy)), - RValTy, E->getExprLoc()); + Address A = builder.createElementBitCast(Dest.getPointer().getLoc(), Dest, + convertTypeForMem(RValTy)); + return convertTempToRValue(A, RValTy, E->getExprLoc()); } // The memory order is not known at compile-time. The atomic operations @@ -1321,8 +1323,9 @@ RValue CIRGenFunction::emitAtomicExpr(AtomicExpr *E) { if (RValTy->isVoidType()) return RValue::get(nullptr); - return convertTempToRValue(Dest.withElementType(convertTypeForMem(RValTy)), - RValTy, E->getExprLoc()); + Address A = builder.createElementBitCast(Dest.getPointer().getLoc(), Dest, + convertTypeForMem(RValTy)); + return convertTempToRValue(A, RValTy, E->getExprLoc()); } void CIRGenFunction::emitAtomicStore(RValue rvalue, LValue lvalue, diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h index 5a06ddbd0b27..e315630a9e3e 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h +++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h @@ -733,7 +733,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy { auto ptrTy = getPointerTo(destType); auto baseAddr = create( loc, ptrTy, addr.getPointer(), mlir::APInt(64, offset), assumeNotNull); - return Address(baseAddr, ptrTy, addr.getAlignment()); + return Address(baseAddr, destType, addr.getAlignment()); } Address createDerivedClassAddr(mlir::Location loc, Address addr, @@ -745,7 +745,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy { auto ptrTy = getPointerTo(destType); auto derivedAddr = create( loc, ptrTy, addr.getPointer(), mlir::APInt(64, offset), assumeNotNull); - return Address(derivedAddr, ptrTy, addr.getAlignment()); + return Address(derivedAddr, destType, addr.getAlignment()); } mlir::Value createVTTAddrPoint(mlir::Location loc, mlir::Type retTy, diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp index 4db27337ced6..d9c825606d2a 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp @@ -4488,7 +4488,8 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E, } case NEON::BI__builtin_neon_vld1_dup_v: case NEON::BI__builtin_neon_vld1q_dup_v: { - Address ptrAddr = PtrOp0.withElementType(vTy.getEltType()); + Address ptrAddr = builder.createElementBitCast(getLoc(E->getExprLoc()), + PtrOp0, vTy.getEltType()); mlir::Value val = builder.createLoad(getLoc(E->getExprLoc()), ptrAddr); cir::VecSplatOp vecSplat = builder.create(getLoc(E->getExprLoc()), vTy, val); diff --git a/clang/lib/CIR/CodeGen/CIRGenCXX.cpp b/clang/lib/CIR/CodeGen/CIRGenCXX.cpp index 5d401d008dd7..79157921bfe2 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCXX.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCXX.cpp @@ -408,8 +408,7 @@ void CIRGenModule::emitCXXGlobalVarDeclInit(const VarDecl *varDecl, builder.setInsertionPointToStart(block); auto getGlobal = builder.createGetGlobal(addr); - Address declAddr(getGlobal, getGlobal.getType(), - getASTContext().getDeclAlign(varDecl)); + Address declAddr(getGlobal, getASTContext().getDeclAlign(varDecl)); assert(performInit && "cannot have constant initializer which needs " "destruction for reference"); RValue rv = cgf.emitReferenceBindingToExpr(init); diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp b/clang/lib/CIR/CodeGen/CIRGenClass.cpp index a1437ec19174..fb6c6e49b2f4 100644 --- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp @@ -1672,7 +1672,7 @@ CIRGenFunction::getAddressOfBaseClass(Address Value, VBase, BaseValueTy, not NullCheckValue); // Cast to the destination type. - Value = Value.withElementType(BaseValueTy); + Value = builder.createElementBitCast(getLoc(Loc), Value, BaseValueTy); return Value; } @@ -1894,7 +1894,7 @@ void CIRGenFunction::emitCXXAggrConstructorCall( builder.create( *currSrcLoc, arrayOp, [&](mlir::OpBuilder &b, mlir::Location loc) { auto arg = b.getInsertionBlock()->addArgument(ptrToElmType, loc); - Address curAddr = Address(arg, ptrToElmType, eltAlignment); + Address curAddr = Address(arg, elementType, eltAlignment); auto currAVS = AggValueSlot::forAddr( curAddr, type.getQualifiers(), AggValueSlot::IsDestructed, AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased, diff --git a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp index 333bbf0e4c95..27735787ccff 100644 --- a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp @@ -245,9 +245,7 @@ static void emitStoresForConstant(CIRGenModule &CGM, const VarDecl &D, // copy from a global, we just create a cir.const out of it. if (addr.getElementType() != Ty) { - auto ptr = addr.getPointer(); - ptr = builder.createBitcast(ptr.getLoc(), ptr, builder.getPointerTo(Ty)); - addr = addr.withPointer(ptr, addr.isKnownNonNull()); + addr = builder.createElementBitCast(addr.getPointer().getLoc(), addr, Ty); } auto loc = CGM.getLoc(D.getSourceRange()); @@ -1108,7 +1106,7 @@ void CIRGenFunction::emitArrayDestroy(mlir::Value begin, mlir::Value end, builder.create( *currSrcLoc, begin, [&](mlir::OpBuilder &b, mlir::Location loc) { auto arg = b.getInsertionBlock()->addArgument(ptrToElmType, loc); - Address curAddr = Address(arg, ptrToElmType, elementAlign); + Address curAddr = Address(arg, cirElementType, elementAlign); if (useEHCleanup) { pushRegularPartialArrayCleanup(arg, arg, elementType, elementAlign, destroyer); diff --git a/clang/lib/CIR/CodeGen/CIRGenException.cpp b/clang/lib/CIR/CodeGen/CIRGenException.cpp index b7a10fb4ef96..b2af1084a391 100644 --- a/clang/lib/CIR/CodeGen/CIRGenException.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenException.cpp @@ -237,7 +237,8 @@ void CIRGenFunction::emitAnyExprToExn(const Expr *e, Address addr) { // __cxa_allocate_exception returns a void*; we need to cast this // to the appropriate type for the object. auto ty = convertTypeForMem(e->getType()); - Address typedAddr = addr.withElementType(ty); + Address typedAddr = + builder.createElementBitCast(getLoc(e->getExprLoc()), addr, ty); // From LLVM's codegen: // FIXME: this isn't quite right! If there's a final unelided call diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp index a6121122fe34..43f991a4c0f5 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -2938,7 +2938,8 @@ mlir::Value CIRGenFunction::emitLoadOfScalar(Address addr, bool isVolatile, CGM.getABIInfo().getOptimalVectorMemoryType(vTy, getLangOpts()); if (vTy != newVecTy) { - const Address cast = addr.withElementType(newVecTy); + const Address cast = builder.createElementBitCast( + addr.getPointer().getLoc(), addr, newVecTy); mlir::Value v = builder.createLoad(loc, cast, isVolatile); const uint64_t oldNumElements = vTy.getSize(); SmallVector mask(oldNumElements); diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp index 8c37cdea13f8..8be693e7569f 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp @@ -999,7 +999,9 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) { // GCC union extension QualType Ty = E->getSubExpr()->getType(); - Address CastPtr = Dest.getAddress().withElementType(CGF.convertType(Ty)); + Address CastPtr = CGF.getBuilder().createElementBitCast( + CGF.getLoc(E->getExprLoc()), Dest.getAddress(), CGF.convertType(Ty)); + emitInitializationToLValue(E->getSubExpr(), CGF.makeAddrLValue(CastPtr, Ty)); break; diff --git a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp index 4e3774e0b3b9..5b746481b056 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp @@ -379,7 +379,8 @@ static void emitNullBaseClassInitialization(CIRGenFunction &CGF, if (Base->isEmpty()) return; - DestPtr = DestPtr.withElementType(CGF.UInt8Ty); + DestPtr = CGF.getBuilder().createElementBitCast(DestPtr.getPointer().getLoc(), + DestPtr, CGF.UInt8Ty); const ASTRecordLayout &Layout = CGF.getContext().getASTRecordLayout(Base); CharUnits NVSize = Layout.getNonVirtualSize(); @@ -1095,7 +1096,8 @@ void CIRGenFunction::emitNewArrayInitializer( } // Switch back to initializing one base element at a time. - CurPtr = CurPtr.withElementType(BeginPtr.getElementType()); + CurPtr = builder.createElementBitCast(getLoc(E->getExprLoc()), CurPtr, + BeginPtr.getElementType()); } // If all elements have already been initialized, skip any further @@ -1134,7 +1136,8 @@ void CIRGenFunction::emitNewArrayInitializer( if (InitListElements) llvm_unreachable("NYI"); auto arrayType = convertType(CCE->getType()); - CurPtr = CurPtr.withElementType(arrayType); + CurPtr = builder.createElementBitCast(getLoc(CCE->getLocation()), CurPtr, + arrayType); emitCXXAggrConstructorCall(Ctor, NumElements, CurPtr, CCE, /*NewPointerIsChecked*/ true, CCE->requiresZeroInitialization()); @@ -1412,7 +1415,10 @@ mlir::Value CIRGenFunction::emitCXXNewExpr(const CXXNewExpr *E) { allocationAlign, getContext().toCharUnitsFromBits(AllocatorAlign)); } - allocation = Address(RV.getScalarVal(), UInt8Ty, allocationAlign); + auto allocPtr = RV.getScalarVal(); + allocation = Address( + allocPtr, mlir::cast(allocPtr.getType()).getPointee(), + allocationAlign); } // Emit a null check on the allocation result if the allocation diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 836e78c32176..3f6c81408ae5 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -1606,8 +1606,8 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { mlir::Value DestPtr = CGF.getBuilder().createBitcast( CGF.getLoc(E->getExprLoc()), SourceAddr.getPointer(), DestPtrTy); - Address DestAddr = - SourceAddr.withPointer(DestPtr).withElementType(DestElemTy); + Address DestAddr = Address(DestPtr, DestElemTy, SourceAddr.getAlignment(), + SourceAddr.isKnownNonNull()); LValue DestLVal = CGF.makeAddrLValue(DestAddr, DestTy); DestLVal.setTBAAInfo(TBAAAccessInfo::getMayAliasInfo()); return emitLoadOfLValue(DestLVal, CE->getExprLoc()); diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp index 4de62d46e5a5..eccd1e0e609f 100644 --- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp @@ -2357,8 +2357,10 @@ mlir::Value CIRGenItaniumCXXABI::getVirtualBaseClassOffset( loc, Address(VBaseOffsetPtr, CGM.SInt32Ty, CharUnits::fromQuantity(4))); // vbase.offset } else { + auto OffsetPtr = CGF.getBuilder().createBitcast( + VBaseOffsetPtr, CGF.getBuilder().getPointerTo(CGM.PtrDiffTy)); VBaseOffset = CGF.getBuilder().createLoad( - loc, Address(VBaseOffsetPtr, CGM.PtrDiffTy, + loc, Address(OffsetPtr, CGM.PtrDiffTy, CGF.getPointerAlign())); // vbase.offset } return VBaseOffset; @@ -2715,11 +2717,13 @@ Address CIRGenItaniumCXXABI::initializeArrayCookie(CIRGenFunction &CGF, auto OffsetOp = CGF.getBuilder().getSignedInt( Loc, CookieOffset.getQuantity(), /*width=*/32); auto DataPtr = CGF.getBuilder().createPtrStride(Loc, CastOp, OffsetOp); - CookiePtr = Address(DataPtr, NewPtr.getType(), NewPtr.getAlignment()); + CookiePtr = + Address(DataPtr, CGF.getBuilder().getUIntNTy(8), NewPtr.getAlignment()); } // Write the number of elements into the appropriate slot. - Address NumElementsPtr = CookiePtr.withElementType(CGF.SizeTy); + Address NumElementsPtr = + CGF.getBuilder().createElementBitCast(Loc, CookiePtr, CGF.SizeTy); CGF.getBuilder().createStore(Loc, NumElements, NumElementsPtr); if (CGF.SanOpts.has(SanitizerKind::Address)) @@ -2732,7 +2736,8 @@ Address CIRGenItaniumCXXABI::initializeArrayCookie(CIRGenFunction &CGF, NewPtr.getPointer(), CGF.getBuilder().getUIntNTy(8)); auto OffsetOp = CGF.getBuilder().getSignedInt(Loc, Offset, /*width=*/32); auto DataPtr = CGF.getBuilder().createPtrStride(Loc, CastOp, OffsetOp); - return Address(DataPtr, NewPtr.getType(), NewPtr.getAlignment()); + return Address(DataPtr, CGF.getBuilder().getUIntNTy(8), + NewPtr.getAlignment()); } CharUnits CIRGenARMCXXABI::getArrayCookieSizeImpl(QualType elementType) { @@ -2783,5 +2788,6 @@ Address CIRGenARMCXXABI::initializeArrayCookie(CIRGenFunction &cgf, auto castOp = cgf.getBuilder().createPtrBitcast( newPtr.getPointer(), cgf.getBuilder().getUIntNTy(8)); dataPtr = cgf.getBuilder().createPtrStride(loc, castOp, offsetOp); - return Address(dataPtr, newPtr.getType(), newPtr.getAlignment()); + return Address(dataPtr, cgf.getBuilder().getUIntNTy(8), + newPtr.getAlignment()); } diff --git a/clang/test/CIR/CodeGen/atomic-thread-fence.c b/clang/test/CIR/CodeGen/atomic-thread-fence.c index 4c71c3c83966..1b3199f56165 100644 --- a/clang/test/CIR/CodeGen/atomic-thread-fence.c +++ b/clang/test/CIR/CodeGen/atomic-thread-fence.c @@ -87,10 +87,11 @@ void loadWithThreadFence(DataPtr d) { // CIR: %[[LOAD_DATA:.*]] = cir.load %[[DATA]] : !cir.ptr>, !cir.ptr // CIR: %[[DATA_VALUE:.*]] = cir.get_member %[[LOAD_DATA]][1] {name = "ptr"} : !cir.ptr -> !cir.ptr> // CIR: %[[CASTED_DATA_VALUE:.*]] = cir.cast(bitcast, %[[DATA_VALUE]] : !cir.ptr>), !cir.ptr -// CIR: %[[ATOMIC_LOAD:.*]] = cir.load atomic(seq_cst) %[[CASTED_DATA_VALUE]] : !cir.ptr, !u64i // CIR: %[[CASTED_ATOMIC_TEMP:.*]] = cir.cast(bitcast, %[[ATOMIC_TEMP]] : !cir.ptr>), !cir.ptr +// CIR: %[[ATOMIC_LOAD:.*]] = cir.load atomic(seq_cst) %[[CASTED_DATA_VALUE]] : !cir.ptr, !u64i // CIR: cir.store %[[ATOMIC_LOAD]], %[[CASTED_ATOMIC_TEMP]] : !u64i, !cir.ptr -// CIR: %[[ATOMIC_LOAD_PTR:.*]] = cir.load %[[ATOMIC_TEMP]] : !cir.ptr>, !cir.ptr +// CIR: %[[DOUBLE_CASTED_ATOMIC_TEMP:.*]] = cir.cast(bitcast, %[[CASTED_ATOMIC_TEMP]] : !cir.ptr), !cir.ptr> +// CIR: %[[ATOMIC_LOAD_PTR:.*]] = cir.load %[[DOUBLE_CASTED_ATOMIC_TEMP]] : !cir.ptr>, !cir.ptr // CIR: cir.return // LLVM-LABEL: @loadWithThreadFence @@ -115,10 +116,11 @@ void loadWithSignalFence(DataPtr d) { // CIR: %[[LOAD_DATA:.*]] = cir.load %[[DATA]] : !cir.ptr>, !cir.ptr // CIR: %[[DATA_PTR:.*]] = cir.get_member %[[LOAD_DATA]][1] {name = "ptr"} : !cir.ptr -> !cir.ptr> // CIR: %[[CASTED_DATA_PTR:.*]] = cir.cast(bitcast, %[[DATA_PTR]] : !cir.ptr>), !cir.ptr -// CIR: %[[ATOMIC_LOAD:.*]] = cir.load atomic(seq_cst) %[[CASTED_DATA_PTR]] : !cir.ptr, !u64i // CIR: %[[CASTED_ATOMIC_TEMP:.*]] = cir.cast(bitcast, %[[ATOMIC_TEMP]] : !cir.ptr>), !cir.ptr +// CIR: %[[ATOMIC_LOAD:.*]] = cir.load atomic(seq_cst) %[[CASTED_DATA_PTR]] : !cir.ptr, !u64i // CIR: cir.store %[[ATOMIC_LOAD]], %[[CASTED_ATOMIC_TEMP]] : !u64i, !cir.ptr -// CIR: %[[LOAD_ATOMIC_TEMP:.*]] = cir.load %[[ATOMIC_TEMP]] : !cir.ptr>, !cir.ptr +// CIR: %[[DOUBLE_CASTED_ATOMIC_TEMP:.*]] = cir.cast(bitcast, %[[CASTED_ATOMIC_TEMP]] : !cir.ptr), !cir.ptr> +// CIR: %[[LOAD_ATOMIC_TEMP:.*]] = cir.load %[[DOUBLE_CASTED_ATOMIC_TEMP]] : !cir.ptr>, !cir.ptr // CIR: cir.return // LLVM-LABEL: @loadWithSignalFence diff --git a/clang/test/CIR/CodeGen/atomic-xchg-field.c b/clang/test/CIR/CodeGen/atomic-xchg-field.c index 59b36ba183bb..d2d0a6be7410 100644 --- a/clang/test/CIR/CodeGen/atomic-xchg-field.c +++ b/clang/test/CIR/CodeGen/atomic-xchg-field.c @@ -27,7 +27,8 @@ void field_access(wPtr item) { // CHECK-NEXT: %[[WADDR:.*]] = cir.alloca !cir.ptr, {{.*}} {alignment = 8 : i64} // CHECK: %[[FIELD:.*]] = cir.load %[[WADDR]] // CHECK: %[[MEMBER:.*]] = cir.get_member %[[FIELD]][1] {name = "ref"} -// CHECK: cir.atomic.xchg(%[[MEMBER]] : !cir.ptr>, {{.*}} : !u64i, seq_cst) +// CHECK: %[[CASTED_MEMBER:.*]] = cir.cast(bitcast, %[[MEMBER]] : !cir.ptr>), !cir.ptr +// CHECK: cir.atomic.xchg(%[[CASTED_MEMBER]] : !cir.ptr, {{.*}} : !u64i, seq_cst) // LLVM-LABEL: @field_access // LLVM: = alloca ptr, i64 1, align 8 @@ -77,8 +78,8 @@ void structLoad(unsigned referenceCount, wPtr item) { // CHECK-LABEL: @structLoad // CHECK: %[[ATOMIC_TEMP:.*]] = cir.alloca !cir.ptr, !cir.ptr>, ["atomic-temp"] -// CHECK: %[[ATOMIC_LOAD:.*]] = cir.load atomic(seq_cst) %6 : !cir.ptr, !u64i // CHECK: %[[RES:.*]] = cir.cast(bitcast, %[[ATOMIC_TEMP]] : !cir.ptr>), !cir.ptr +// CHECK: %[[ATOMIC_LOAD:.*]] = cir.load atomic(seq_cst) %6 : !cir.ptr, !u64i // CHECK: cir.store %[[ATOMIC_LOAD]], %[[RES]] : !u64i, !cir.ptr // No LLVM tests needed for this one, already covered elsewhere. diff --git a/clang/test/CIR/CodeGen/atomic.cpp b/clang/test/CIR/CodeGen/atomic.cpp index 54244c6d4f74..d04c767591a4 100644 --- a/clang/test/CIR/CodeGen/atomic.cpp +++ b/clang/test/CIR/CodeGen/atomic.cpp @@ -239,7 +239,7 @@ void fd3(struct S *a, struct S *b, struct S *c) { } // CHECK-LABEL: @_Z3fd3P1SS0_S0_ -// CHECK: cir.atomic.xchg({{.*}} : !cir.ptr, {{.*}} : !u64i, seq_cst) : !u64i +// CHECK: cir.atomic.xchg({{.*}} : !cir.ptr, {{.*}} : !u64i, seq_cst) : !u64i // FIXME: CIR is producing an over alignment of 8, only 4 needed. // LLVM-LABEL: @_Z3fd3P1SS0_S0_ @@ -261,7 +261,7 @@ bool fd4(struct S *a, struct S *b, struct S *c) { } // CHECK-LABEL: @_Z3fd4P1SS0_S0_ -// CHECK: %old, %cmp = cir.atomic.cmp_xchg({{.*}} : !cir.ptr, {{.*}} : !u64i, {{.*}} : !u64i, success = seq_cst, failure = seq_cst) align(8) weak : (!u64i, !cir.bool) +// CHECK: %old, %cmp = cir.atomic.cmp_xchg({{.*}} : !cir.ptr, {{.*}} : !u64i, {{.*}} : !u64i, success = seq_cst, failure = seq_cst) align(8) weak : (!u64i, !cir.bool) // LLVM-LABEL: @_Z3fd4P1SS0_S0_ // LLVM: cmpxchg weak ptr {{.*}}, i64 {{.*}}, i64 {{.*}} seq_cst seq_cst, align 8 @@ -328,7 +328,7 @@ bool fsb(bool *c) { } // CHECK-LABEL: @_Z3fsbPb -// CHECK: cir.atomic.xchg({{.*}} : !cir.ptr, {{.*}} : !u8i, seq_cst) : !u8i +// CHECK: cir.atomic.xchg({{.*}} : !cir.ptr, {{.*}} : !u8i, seq_cst) : !u8i // LLVM-LABEL: @_Z3fsbPb // LLVM: atomicrmw xchg ptr {{.*}}, i8 {{.*}} seq_cst, align 1 diff --git a/clang/test/CIR/CodeGen/union-init.c b/clang/test/CIR/CodeGen/union-init.c index 122999de23c2..a8d3321142f3 100644 --- a/clang/test/CIR/CodeGen/union-init.c +++ b/clang/test/CIR/CodeGen/union-init.c @@ -54,9 +54,9 @@ typedef union { // CHECK: %[[VAL_0:.*]] = cir.alloca !s32i, !cir.ptr, ["x", init] {alignment = 4 : i64} // CHECK: %[[VAL_1:.*]] = cir.alloca !ty_U, !cir.ptr, ["u", init] {alignment = 4 : i64} // CHECK: cir.store %arg0, %[[VAL_0]] : !s32i, !cir.ptr -// CHECK: %[[VAL_2:.*]] = cir.load %[[VAL_0]] : !cir.ptr, !s32i -// CHECK: %[[VAL_3:.*]] = cir.cast(bitcast, %[[VAL_1]] : !cir.ptr), !cir.ptr -// CHECK: cir.store %[[VAL_2]], %[[VAL_3]] : !s32i, !cir.ptr +// CHECK: %[[VAL_2:.*]] = cir.cast(bitcast, %[[VAL_1]] : !cir.ptr), !cir.ptr +// CHECK: %[[VAL_3:.*]] = cir.load %[[VAL_0]] : !cir.ptr, !s32i +// CHECK: cir.store %[[VAL_3]], %[[VAL_2]] : !s32i, !cir.ptr void union_cast(int x) { U u = (U) x; From 6294988d61f31ecad4573a370becb52132a03026 Mon Sep 17 00:00:00 2001 From: Andy Kaylor Date: Thu, 20 Feb 2025 12:46:00 -0800 Subject: [PATCH 2/2] Switch back to Address::withElementType, but insert a bitcast there --- clang/lib/CIR/CodeGen/Address.h | 7 +++++++ clang/lib/CIR/CodeGen/CIRAsm.cpp | 15 +++++++-------- clang/lib/CIR/CodeGen/CIRGenAtomic.cpp | 16 ++++++++-------- clang/lib/CIR/CodeGen/CIRGenBuilder.cpp | 14 +++++++++++++- clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp | 3 +-- clang/lib/CIR/CodeGen/CIRGenClass.cpp | 2 +- clang/lib/CIR/CodeGen/CIRGenDecl.cpp | 5 ++--- clang/lib/CIR/CodeGen/CIRGenException.cpp | 3 +-- clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 3 +-- clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp | 5 ++--- clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp | 12 ++++-------- clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp | 2 +- 12 files changed, 48 insertions(+), 39 deletions(-) diff --git a/clang/lib/CIR/CodeGen/Address.h b/clang/lib/CIR/CodeGen/Address.h index 990d9b64a286..5f82dd6b7eff 100644 --- a/clang/lib/CIR/CodeGen/Address.h +++ b/clang/lib/CIR/CodeGen/Address.h @@ -25,6 +25,9 @@ namespace clang::CIRGen { +// Forward declaration to avoid a circular dependency +class CIRGenBuilderTy; + // Indicates whether a pointer is known not to be null. enum KnownNonNull_t { NotKnownNonNull, KnownNonNull }; @@ -107,6 +110,10 @@ class Address { bool hasOffset() const { return bool(offset); } + /// Return address with different element type, a bitcast pointer, and + /// the same alignment. + Address withElementType(CIRGenBuilderTy &builder, mlir::Type ElemTy) const; + mlir::Value getPointer() const { assert(isValid()); return PointerAndKnownNonNull.getPointer(); diff --git a/clang/lib/CIR/CodeGen/CIRAsm.cpp b/clang/lib/CIR/CodeGen/CIRAsm.cpp index d3de289d6f5a..f7cbe073f4da 100644 --- a/clang/lib/CIR/CodeGen/CIRAsm.cpp +++ b/clang/lib/CIR/CodeGen/CIRAsm.cpp @@ -214,9 +214,10 @@ std::pair CIRGenFunction::emitAsmInputLValue( getTargetHooks().isScalarizableAsmOperand(*this, Ty)) { Ty = cir::IntType::get(&getMLIRContext(), Size, false); - auto InputAddr = builder.createElementBitCast( - getLoc(Loc), InputValue.getAddress(), Ty); - return {builder.createLoad(getLoc(Loc), InputAddr), mlir::Type()}; + return {builder.createLoad( + getLoc(Loc), + InputValue.getAddress().withElementType(builder, Ty)), + mlir::Type()}; } } @@ -320,8 +321,7 @@ static void emitAsmStores(CIRGenFunction &CGF, const AsmStmt &S, // ResultTypeRequiresCast.size() elements of RegResults. if ((i < ResultTypeRequiresCast.size()) && ResultTypeRequiresCast[i]) { unsigned Size = CGF.getContext().getTypeSize(ResultRegQualTys[i]); - Address A = Builder.createElementBitCast( - Dest.getPointer().getLoc(), Dest.getAddress(), ResultRegTypes[i]); + Address A = Dest.getAddress().withElementType(Builder, ResultRegTypes[i]); if (CGF.getTargetHooks().isScalarizableAsmOperand(CGF, TruncTy)) { Builder.createStore(CGF.getLoc(S.getAsmLoc()), Tmp, A); continue; @@ -479,9 +479,8 @@ mlir::LogicalResult CIRGenFunction::emitAsmStmt(const AsmStmt &S) { // Otherwise there will be a mis-match if the matrix is also an // input-argument which is represented as vector. if (isa(OutExpr->getType().getCanonicalType())) - DestAddr = builder.createElementBitCast( - DestAddr.getPointer().getLoc(), DestAddr, - convertType(OutExpr->getType())); + DestAddr = + DestAddr.withElementType(builder, convertType(OutExpr->getType())); ArgTypes.push_back(DestAddr.getType()); ArgElemTypes.push_back(DestAddr.getElementType()); diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp index 12db9389f47a..fc9c7c19afb4 100644 --- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp @@ -305,8 +305,7 @@ Address AtomicInfo::castToAtomicIntPointer(Address addr) const { if (intTy && intTy.getWidth() == AtomicSizeInBits) return addr; auto ty = CGF.getBuilder().getUIntNTy(AtomicSizeInBits); - return CGF.getBuilder().createElementBitCast(addr.getPointer().getLoc(), addr, - ty); + return addr.withElementType(CGF.getBuilder(), ty); } Address AtomicInfo::convertToAtomicIntPointer(Address Addr) const { @@ -1244,9 +1243,9 @@ RValue CIRGenFunction::emitAtomicExpr(AtomicExpr *E) { if (RValTy->isVoidType()) return RValue::get(nullptr); - Address A = builder.createElementBitCast(Dest.getPointer().getLoc(), Dest, - convertTypeForMem(RValTy)); - return convertTempToRValue(A, RValTy, E->getExprLoc()); + return convertTempToRValue( + Dest.withElementType(builder, convertTypeForMem(RValTy)), RValTy, + E->getExprLoc()); } // The memory order is not known at compile-time. The atomic operations @@ -1323,9 +1322,10 @@ RValue CIRGenFunction::emitAtomicExpr(AtomicExpr *E) { if (RValTy->isVoidType()) return RValue::get(nullptr); - Address A = builder.createElementBitCast(Dest.getPointer().getLoc(), Dest, - convertTypeForMem(RValTy)); - return convertTempToRValue(A, RValTy, E->getExprLoc()); + + return convertTempToRValue( + Dest.withElementType(builder, convertTypeForMem(RValTy)), RValTy, + E->getExprLoc()); } void CIRGenFunction::emitAtomicStore(RValue rvalue, LValue lvalue, diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.cpp b/clang/lib/CIR/CodeGen/CIRGenBuilder.cpp index f4c9506d02d9..f5555ef3bf74 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuilder.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.cpp @@ -133,4 +133,16 @@ uint64_t CIRGenBuilderTy::computeOffsetFromGlobalViewIndices( } return offset; -} \ No newline at end of file +} + +// This can't be defined in Address.h because that file is included by +// CIRGenBuilder.h +Address Address::withElementType(CIRGenBuilderTy &builder, + mlir::Type ElemTy) const { + if (!hasOffset()) + return Address(builder.createPtrBitcast(getBasePointer(), ElemTy), ElemTy, + getAlignment(), getPointerAuthInfo(), /*Offset=*/nullptr, + isKnownNonNull()); + return Address(builder.createPtrBitcast(getPointer(), ElemTy), ElemTy, + getAlignment(), isKnownNonNull()); +} diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp index d9c825606d2a..f9edf18eb5d5 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp @@ -4488,8 +4488,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E, } case NEON::BI__builtin_neon_vld1_dup_v: case NEON::BI__builtin_neon_vld1q_dup_v: { - Address ptrAddr = builder.createElementBitCast(getLoc(E->getExprLoc()), - PtrOp0, vTy.getEltType()); + Address ptrAddr = PtrOp0.withElementType(builder, vTy.getEltType()); mlir::Value val = builder.createLoad(getLoc(E->getExprLoc()), ptrAddr); cir::VecSplatOp vecSplat = builder.create(getLoc(E->getExprLoc()), vTy, val); diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp b/clang/lib/CIR/CodeGen/CIRGenClass.cpp index fb6c6e49b2f4..1db346682531 100644 --- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp @@ -1672,7 +1672,7 @@ CIRGenFunction::getAddressOfBaseClass(Address Value, VBase, BaseValueTy, not NullCheckValue); // Cast to the destination type. - Value = builder.createElementBitCast(getLoc(Loc), Value, BaseValueTy); + Value = Value.withElementType(builder, BaseValueTy); return Value; } diff --git a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp index 27735787ccff..64e48a42cc25 100644 --- a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp @@ -244,9 +244,8 @@ static void emitStoresForConstant(CIRGenModule &CGM, const VarDecl &D, // FIXME(cir): This is closer to memcpy behavior but less optimal, instead of // copy from a global, we just create a cir.const out of it. - if (addr.getElementType() != Ty) { - addr = builder.createElementBitCast(addr.getPointer().getLoc(), addr, Ty); - } + if (addr.getElementType() != Ty) + addr = addr.withElementType(builder, Ty); auto loc = CGM.getLoc(D.getSourceRange()); builder.createStore(loc, builder.getConstant(loc, constant), addr); diff --git a/clang/lib/CIR/CodeGen/CIRGenException.cpp b/clang/lib/CIR/CodeGen/CIRGenException.cpp index b2af1084a391..4ee25d0d38eb 100644 --- a/clang/lib/CIR/CodeGen/CIRGenException.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenException.cpp @@ -237,8 +237,7 @@ void CIRGenFunction::emitAnyExprToExn(const Expr *e, Address addr) { // __cxa_allocate_exception returns a void*; we need to cast this // to the appropriate type for the object. auto ty = convertTypeForMem(e->getType()); - Address typedAddr = - builder.createElementBitCast(getLoc(e->getExprLoc()), addr, ty); + Address typedAddr = addr.withElementType(builder, ty); // From LLVM's codegen: // FIXME: this isn't quite right! If there's a final unelided call diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp index 43f991a4c0f5..3a289c080ad9 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -2938,8 +2938,7 @@ mlir::Value CIRGenFunction::emitLoadOfScalar(Address addr, bool isVolatile, CGM.getABIInfo().getOptimalVectorMemoryType(vTy, getLangOpts()); if (vTy != newVecTy) { - const Address cast = builder.createElementBitCast( - addr.getPointer().getLoc(), addr, newVecTy); + const Address cast = addr.withElementType(builder, newVecTy); mlir::Value v = builder.createLoad(loc, cast, isVolatile); const uint64_t oldNumElements = vTy.getSize(); SmallVector mask(oldNumElements); diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp index 8be693e7569f..6485c996349e 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp @@ -999,9 +999,8 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) { // GCC union extension QualType Ty = E->getSubExpr()->getType(); - Address CastPtr = CGF.getBuilder().createElementBitCast( - CGF.getLoc(E->getExprLoc()), Dest.getAddress(), CGF.convertType(Ty)); - + Address CastPtr = Dest.getAddress().withElementType(CGF.getBuilder(), + CGF.convertType(Ty)); emitInitializationToLValue(E->getSubExpr(), CGF.makeAddrLValue(CastPtr, Ty)); break; diff --git a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp index 5b746481b056..1367478df2f1 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp @@ -379,8 +379,7 @@ static void emitNullBaseClassInitialization(CIRGenFunction &CGF, if (Base->isEmpty()) return; - DestPtr = CGF.getBuilder().createElementBitCast(DestPtr.getPointer().getLoc(), - DestPtr, CGF.UInt8Ty); + DestPtr = DestPtr.withElementType(CGF.getBuilder(), CGF.UInt8Ty); const ASTRecordLayout &Layout = CGF.getContext().getASTRecordLayout(Base); CharUnits NVSize = Layout.getNonVirtualSize(); @@ -1050,8 +1049,7 @@ void CIRGenFunction::emitNewArrayInitializer( if (const ConstantArrayType *CAT = dyn_cast_or_null( AllocType->getAsArrayTypeUnsafe())) { ElementTy = convertTypeForMem(AllocType); - auto CastOp = builder.createPtrBitcast(CurPtr.getPointer(), ElementTy); - CurPtr = Address(CastOp, ElementTy, CurPtr.getAlignment()); + CurPtr = CurPtr.withElementType(builder, ElementTy); InitListElements *= getContext().getConstantArrayElementCount(CAT); } @@ -1096,8 +1094,7 @@ void CIRGenFunction::emitNewArrayInitializer( } // Switch back to initializing one base element at a time. - CurPtr = builder.createElementBitCast(getLoc(E->getExprLoc()), CurPtr, - BeginPtr.getElementType()); + CurPtr = CurPtr.withElementType(builder, BeginPtr.getElementType()); } // If all elements have already been initialized, skip any further @@ -1136,8 +1133,7 @@ void CIRGenFunction::emitNewArrayInitializer( if (InitListElements) llvm_unreachable("NYI"); auto arrayType = convertType(CCE->getType()); - CurPtr = builder.createElementBitCast(getLoc(CCE->getLocation()), CurPtr, - arrayType); + CurPtr = CurPtr.withElementType(builder, arrayType); emitCXXAggrConstructorCall(Ctor, NumElements, CurPtr, CCE, /*NewPointerIsChecked*/ true, CCE->requiresZeroInitialization()); diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp index eccd1e0e609f..1f98292f28fd 100644 --- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp @@ -2723,7 +2723,7 @@ Address CIRGenItaniumCXXABI::initializeArrayCookie(CIRGenFunction &CGF, // Write the number of elements into the appropriate slot. Address NumElementsPtr = - CGF.getBuilder().createElementBitCast(Loc, CookiePtr, CGF.SizeTy); + CookiePtr.withElementType(CGF.getBuilder(), CGF.SizeTy); CGF.getBuilder().createStore(Loc, NumElements, NumElementsPtr); if (CGF.SanOpts.has(SanitizerKind::Address))