Skip to content

[CIR] Fix Address element type problems #1373

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions clang/lib/CIR/CodeGen/Address.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 };

Expand Down Expand Up @@ -64,6 +67,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<cir::PointerType>(pointer.getType()).getPointee() ==
ElementType);
}

Address(mlir::Value basePtr, mlir::Type elementType,
Expand Down Expand Up @@ -104,15 +110,9 @@ 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());
}
/// 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());
Expand Down Expand Up @@ -142,11 +142,17 @@ class Address {

/// Return the type of the pointer value.
cir::PointerType getType() const {
assert(mlir::cast<cir::PointerType>(
PointerAndKnownNonNull.getPointer().getType())
.getPointee() == ElementType);
return mlir::cast<cir::PointerType>(getPointer().getType());
}

mlir::Type getElementType() const {
assert(isValid());
assert(mlir::cast<cir::PointerType>(
PointerAndKnownNonNull.getPointer().getType())
.getPointee() == ElementType);
return ElementType;
}

Expand Down
10 changes: 6 additions & 4 deletions clang/lib/CIR/CodeGen/CIRAsm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,9 @@ std::pair<mlir::Value, mlir::Type> CIRGenFunction::emitAsmInputLValue(
getTargetHooks().isScalarizableAsmOperand(*this, Ty)) {
Ty = cir::IntType::get(&getMLIRContext(), Size, false);

return {builder.createLoad(getLoc(Loc),
InputValue.getAddress().withElementType(Ty)),
return {builder.createLoad(
getLoc(Loc),
InputValue.getAddress().withElementType(builder, Ty)),
mlir::Type()};
}
}
Expand Down Expand Up @@ -320,7 +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 = Dest.getAddress().withElementType(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;
Expand Down Expand Up @@ -478,7 +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<MatrixType>(OutExpr->getType().getCanonicalType()))
DestAddr = DestAddr.withElementType(convertType(OutExpr->getType()));
DestAddr =
DestAddr.withElementType(builder, convertType(OutExpr->getType()));

ArgTypes.push_back(DestAddr.getType());
ArgElemTypes.push_back(DestAddr.getElementType());
Expand Down
13 changes: 8 additions & 5 deletions clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ Address AtomicInfo::castToAtomicIntPointer(Address addr) const {
if (intTy && intTy.getWidth() == AtomicSizeInBits)
return addr;
auto ty = CGF.getBuilder().getUIntNTy(AtomicSizeInBits);
return addr.withElementType(ty);
return addr.withElementType(CGF.getBuilder(), ty);
}

Address AtomicInfo::convertToAtomicIntPointer(Address Addr) const {
Expand Down Expand Up @@ -1243,8 +1243,9 @@ RValue CIRGenFunction::emitAtomicExpr(AtomicExpr *E) {
if (RValTy->isVoidType())
return RValue::get(nullptr);

return convertTempToRValue(Dest.withElementType(convertTypeForMem(RValTy)),
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
Expand Down Expand Up @@ -1321,8 +1322,10 @@ RValue CIRGenFunction::emitAtomicExpr(AtomicExpr *E) {

if (RValTy->isVoidType())
return RValue::get(nullptr);
return convertTempToRValue(Dest.withElementType(convertTypeForMem(RValTy)),
RValTy, E->getExprLoc());

return convertTempToRValue(
Dest.withElementType(builder, convertTypeForMem(RValTy)), RValTy,
E->getExprLoc());
}

void CIRGenFunction::emitAtomicStore(RValue rvalue, LValue lvalue,
Expand Down
14 changes: 13 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,16 @@ uint64_t CIRGenBuilderTy::computeOffsetFromGlobalViewIndices(
}

return offset;
}
}

// 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());
}
4 changes: 2 additions & 2 deletions clang/lib/CIR/CodeGen/CIRGenBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
auto ptrTy = getPointerTo(destType);
auto baseAddr = create<cir::BaseClassAddrOp>(
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,
Expand All @@ -745,7 +745,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
auto ptrTy = getPointerTo(destType);
auto derivedAddr = create<cir::DerivedClassAddrOp>(
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,
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4488,7 +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 = PtrOp0.withElementType(vTy.getEltType());
Address ptrAddr = PtrOp0.withElementType(builder, vTy.getEltType());
mlir::Value val = builder.createLoad(getLoc(E->getExprLoc()), ptrAddr);
cir::VecSplatOp vecSplat =
builder.create<cir::VecSplatOp>(getLoc(E->getExprLoc()), vTy, val);
Expand Down
3 changes: 1 addition & 2 deletions clang/lib/CIR/CodeGen/CIRGenCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CIR/CodeGen/CIRGenClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1672,7 +1672,7 @@ CIRGenFunction::getAddressOfBaseClass(Address Value,
VBase, BaseValueTy, not NullCheckValue);

// Cast to the destination type.
Value = Value.withElementType(BaseValueTy);
Value = Value.withElementType(builder, BaseValueTy);

return Value;
}
Expand Down Expand Up @@ -1894,7 +1894,7 @@ void CIRGenFunction::emitCXXAggrConstructorCall(
builder.create<cir::ArrayCtor>(
*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,
Expand Down
9 changes: 3 additions & 6 deletions clang/lib/CIR/CodeGen/CIRGenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,11 +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) {
auto ptr = addr.getPointer();
ptr = builder.createBitcast(ptr.getLoc(), ptr, builder.getPointerTo(Ty));
addr = addr.withPointer(ptr, addr.isKnownNonNull());
}
if (addr.getElementType() != Ty)
addr = addr.withElementType(builder, Ty);

auto loc = CGM.getLoc(D.getSourceRange());
builder.createStore(loc, builder.getConstant(loc, constant), addr);
Expand Down Expand Up @@ -1108,7 +1105,7 @@ void CIRGenFunction::emitArrayDestroy(mlir::Value begin, mlir::Value end,
builder.create<cir::ArrayDtor>(
*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);
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CIR/CodeGen/CIRGenException.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +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 = addr.withElementType(ty);
Address typedAddr = addr.withElementType(builder, ty);

// From LLVM's codegen:
// FIXME: this isn't quite right! If there's a final unelided call
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CIR/CodeGen/CIRGenExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2938,7 +2938,7 @@ 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 = addr.withElementType(builder, newVecTy);
mlir::Value v = builder.createLoad(loc, cast, isVolatile);
const uint64_t oldNumElements = vTy.getSize();
SmallVector<int64_t, 16> mask(oldNumElements);
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -999,7 +999,8 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {

// GCC union extension
QualType Ty = E->getSubExpr()->getType();
Address CastPtr = Dest.getAddress().withElementType(CGF.convertType(Ty));
Address CastPtr = Dest.getAddress().withElementType(CGF.getBuilder(),
CGF.convertType(Ty));
emitInitializationToLValue(E->getSubExpr(),
CGF.makeAddrLValue(CastPtr, Ty));
break;
Expand Down
14 changes: 8 additions & 6 deletions clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ static void emitNullBaseClassInitialization(CIRGenFunction &CGF,
if (Base->isEmpty())
return;

DestPtr = DestPtr.withElementType(CGF.UInt8Ty);
DestPtr = DestPtr.withElementType(CGF.getBuilder(), CGF.UInt8Ty);

const ASTRecordLayout &Layout = CGF.getContext().getASTRecordLayout(Base);
CharUnits NVSize = Layout.getNonVirtualSize();
Expand Down Expand Up @@ -1049,8 +1049,7 @@ void CIRGenFunction::emitNewArrayInitializer(
if (const ConstantArrayType *CAT = dyn_cast_or_null<ConstantArrayType>(
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);
}

Expand Down Expand Up @@ -1095,7 +1094,7 @@ void CIRGenFunction::emitNewArrayInitializer(
}

// Switch back to initializing one base element at a time.
CurPtr = CurPtr.withElementType(BeginPtr.getElementType());
CurPtr = CurPtr.withElementType(builder, BeginPtr.getElementType());
}

// If all elements have already been initialized, skip any further
Expand Down Expand Up @@ -1134,7 +1133,7 @@ void CIRGenFunction::emitNewArrayInitializer(
if (InitListElements)
llvm_unreachable("NYI");
auto arrayType = convertType(CCE->getType());
CurPtr = CurPtr.withElementType(arrayType);
CurPtr = CurPtr.withElementType(builder, arrayType);
emitCXXAggrConstructorCall(Ctor, NumElements, CurPtr, CCE,
/*NewPointerIsChecked*/ true,
CCE->requiresZeroInitialization());
Expand Down Expand Up @@ -1412,7 +1411,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<cir::PointerType>(allocPtr.getType()).getPointee(),
allocationAlign);
}

// Emit a null check on the allocation result if the allocation
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
16 changes: 11 additions & 5 deletions clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 =
CookiePtr.withElementType(CGF.getBuilder(), CGF.SizeTy);
CGF.getBuilder().createStore(Loc, NumElements, NumElementsPtr);

if (CGF.SanOpts.has(SanitizerKind::Address))
Expand All @@ -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) {
Expand Down Expand Up @@ -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());
}
10 changes: 6 additions & 4 deletions clang/test/CIR/CodeGen/atomic-thread-fence.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,11 @@ void loadWithThreadFence(DataPtr d) {
// CIR: %[[LOAD_DATA:.*]] = cir.load %[[DATA]] : !cir.ptr<!cir.ptr<!ty_Data>>, !cir.ptr<!ty_Data>
// CIR: %[[DATA_VALUE:.*]] = cir.get_member %[[LOAD_DATA]][1] {name = "ptr"} : !cir.ptr<!ty_Data> -> !cir.ptr<!cir.ptr<!void>>
// CIR: %[[CASTED_DATA_VALUE:.*]] = cir.cast(bitcast, %[[DATA_VALUE]] : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!u64i>
// CIR: %[[ATOMIC_LOAD:.*]] = cir.load atomic(seq_cst) %[[CASTED_DATA_VALUE]] : !cir.ptr<!u64i>, !u64i
// CIR: %[[CASTED_ATOMIC_TEMP:.*]] = cir.cast(bitcast, %[[ATOMIC_TEMP]] : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!u64i>
// CIR: %[[ATOMIC_LOAD:.*]] = cir.load atomic(seq_cst) %[[CASTED_DATA_VALUE]] : !cir.ptr<!u64i>, !u64i
// CIR: cir.store %[[ATOMIC_LOAD]], %[[CASTED_ATOMIC_TEMP]] : !u64i, !cir.ptr<!u64i>
// CIR: %[[ATOMIC_LOAD_PTR:.*]] = cir.load %[[ATOMIC_TEMP]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
// CIR: %[[DOUBLE_CASTED_ATOMIC_TEMP:.*]] = cir.cast(bitcast, %[[CASTED_ATOMIC_TEMP]] : !cir.ptr<!u64i>), !cir.ptr<!cir.ptr<!void>>
// CIR: %[[ATOMIC_LOAD_PTR:.*]] = cir.load %[[DOUBLE_CASTED_ATOMIC_TEMP]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
// CIR: cir.return

// LLVM-LABEL: @loadWithThreadFence
Expand All @@ -115,10 +116,11 @@ void loadWithSignalFence(DataPtr d) {
// CIR: %[[LOAD_DATA:.*]] = cir.load %[[DATA]] : !cir.ptr<!cir.ptr<!ty_Data>>, !cir.ptr<!ty_Data>
// CIR: %[[DATA_PTR:.*]] = cir.get_member %[[LOAD_DATA]][1] {name = "ptr"} : !cir.ptr<!ty_Data> -> !cir.ptr<!cir.ptr<!void>>
// CIR: %[[CASTED_DATA_PTR:.*]] = cir.cast(bitcast, %[[DATA_PTR]] : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!u64i>
// CIR: %[[ATOMIC_LOAD:.*]] = cir.load atomic(seq_cst) %[[CASTED_DATA_PTR]] : !cir.ptr<!u64i>, !u64i
// CIR: %[[CASTED_ATOMIC_TEMP:.*]] = cir.cast(bitcast, %[[ATOMIC_TEMP]] : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!u64i>
// CIR: %[[ATOMIC_LOAD:.*]] = cir.load atomic(seq_cst) %[[CASTED_DATA_PTR]] : !cir.ptr<!u64i>, !u64i
// CIR: cir.store %[[ATOMIC_LOAD]], %[[CASTED_ATOMIC_TEMP]] : !u64i, !cir.ptr<!u64i>
// CIR: %[[LOAD_ATOMIC_TEMP:.*]] = cir.load %[[ATOMIC_TEMP]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
// CIR: %[[DOUBLE_CASTED_ATOMIC_TEMP:.*]] = cir.cast(bitcast, %[[CASTED_ATOMIC_TEMP]] : !cir.ptr<!u64i>), !cir.ptr<!cir.ptr<!void>>
// CIR: %[[LOAD_ATOMIC_TEMP:.*]] = cir.load %[[DOUBLE_CASTED_ATOMIC_TEMP]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
// CIR: cir.return

// LLVM-LABEL: @loadWithSignalFence
Expand Down
Loading