https://github.com/bcardosolopes updated https://github.com/llvm/llvm-project/pull/227520
>From d67d4804f3b98f14732dc268bdacf94d855abd3e Mon Sep 17 00:00:00 2001 From: Bruno Cardoso Lopes <[email protected]> Date: Tue, 29 Sep 2026 16:45:07 -0700 Subject: [PATCH 1/2] [CIR] Emit inbounds and inrange for vtable address points in initializers Classic codegen emits `inbounds inrange(...)` for vtable address points in global initializers (VTT entries and the vptr of a constant-initialized object). CIR never emitted any flags for #cir.global_view. It only got inbounds and nuw when LLVM's constant folder inferred them, which stopped for a while with c68a4ca2a920 (https://github.com/llvm/llvm-project/pull/226904) until #227651 restored the folding. It never got inrange. Emit the flags in CIR instead of relying on the folder: - Add an `address_point` flag to #cir.global_view, spelled `#cir.global_view<@vtable, [vtable index, slot], address_point>`. - Set it where CIRGen builds VTT entries and constant vptrs, and keep it when CIRGen and CXXABILowering rebuild the attribute. - When lowering to LLVM, make an address point `inbounds`, with an `inrange` covering the one vtable in the group that it points into. The bounds come from the vtable global's type, so they also work when the vtable is only declared. VTT and vptr initializers now match classic codegen, except that the folder also adds `nuw` (valid for these non-negative offsets). Classic codegen does not fold these constants, so it does not add it. --- .../include/clang/CIR/Dialect/IR/CIRAttrs.td | 20 +++++++---- clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp | 6 ++-- clang/lib/CIR/CodeGen/CIRGenModule.cpp | 8 +++-- clang/lib/CIR/CodeGen/CIRGenVTables.cpp | 6 ++-- clang/lib/CIR/Dialect/IR/CIRAttrs.cpp | 18 ++++++++++ .../CIR/Dialect/Transforms/CXXABILowering.cpp | 5 +-- .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 27 ++++++++++++-- clang/test/CIR/CodeGen/global-ptr-init.cpp | 17 +++++++-- clang/test/CIR/CodeGen/vtt.cpp | 28 +++++++-------- clang/test/CIR/CodeGenCXX/base-layout.cpp | 4 +-- clang/test/CIR/CodeGenCXX/vtable-linkage.cpp | 4 +-- .../test/CIR/IR/global-view-address-point.cir | 35 +++++++++++++++++++ 12 files changed, 140 insertions(+), 38 deletions(-) create mode 100644 clang/test/CIR/IR/global-view-address-point.cir diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index 358412b75fc05..64b8016971c76 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -1033,28 +1033,35 @@ def CIR_GlobalViewAttr : CIR_ValueLikeAttr<"GlobalView", "global_view"> { int b; }; ``` + `address_point` marks a vtable address point: `symbol` is a vtable and + `indices` are the vtable within the group and the address point within + it. As in classic codegen, it lowers to an `inbounds` GEP whose `inrange` + spans that one vtable. + VTT for B in CIR: ``` cir.global linkonce_odr @_ZTT1B = #cir.const_array<[ - #cir.global_view<@_ZTV1B, [0 : i32, 3 : i32]> : !cir.ptr<!u8i>]> - : !cir.array<!cir.ptr<!u8i> x 1> + #cir.global_view<@_ZTV1B, [0 : i32, 3 : i32], address_point> + : !cir.ptr<!u8i>]> : !cir.array<!cir.ptr<!u8i> x 1> ``` VTT for B in LLVM IR: ``` @_ZTT1B = linkonce_odr global [1 x ptr] [ptr getelementptr inbounds - ({ [3 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 3)], align 8 + inrange(-24, 0) (i8, ptr @_ZTV1B, i64 24)], align 8 ``` }]; let parameters = (ins AttributeSelfTypeParameter<"">:$type, "mlir::FlatSymbolRefAttr":$symbol, - OptionalParameter<"mlir::ArrayAttr">:$indices); + OptionalParameter<"mlir::ArrayAttr">:$indices, + DefaultValuedParameter<"bool", "false">:$address_point); let builders = [ AttrBuilderWithInferredContext<(ins "mlir::Type":$type, "mlir::FlatSymbolRefAttr":$symbol, - CArg<"mlir::ArrayAttr", "{}">:$indices), [{ - return $_get(type.getContext(), type, symbol, indices); + CArg<"mlir::ArrayAttr", "{}">:$indices, + CArg<"bool", "false">:$addressPoint), [{ + return $_get(type.getContext(), type, symbol, indices, addressPoint); }]> ]; @@ -1063,6 +1070,7 @@ def CIR_GlobalViewAttr : CIR_ValueLikeAttr<"GlobalView", "global_view"> { `<` $symbol (`,` $indices^)? + `` custom<GlobalViewAddressPoint>($address_point) `>` }]; } diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp index 46aabba5b567a..ba2feb8bc6ff2 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp @@ -333,9 +333,9 @@ mlir::Attribute buildRecordHelper(ConstantEmitter &emitter, mlir::ArrayAttr indices = builder.getArrayAttr( {builder.getI32IntegerAttr(apOp.getAddressPoint().getIndex()), builder.getI32IntegerAttr(apOp.getAddressPoint().getOffset())}); - elements[0] = - cir::GlobalViewAttr::get(cir::VPtrType::get(builder.getContext()), - apOp.getNameAttr(), indices); + elements[0] = cir::GlobalViewAttr::get( + cir::VPtrType::get(builder.getContext()), apOp.getNameAttr(), indices, + /*addressPoint=*/true); } for (auto [idx, base] : llvm::enumerate(cxxrd->bases())) { diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 06914ea698d61..fe2201ac44940 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -1123,8 +1123,12 @@ static mlir::Attribute createNewGlobalView(CIRGenModule &cgm, else if (isa<cir::ArrayType>(oldTy)) newPtrTy = cast<cir::PointerType>(attr.getType()); - if (newPtrTy) - return bld.getGlobalViewAttr(newPtrTy, newGlob, newInds); + if (newPtrTy) { + cir::GlobalViewAttr view = + bld.getGlobalViewAttr(newPtrTy, newGlob, newInds); + return cir::GlobalViewAttr::get(view.getType(), view.getSymbol(), + view.getIndices(), attr.getAddressPoint()); + } // This may be unreachable in practice, but keep it as errorNYI while CIR // is still under development. diff --git a/clang/lib/CIR/CodeGen/CIRGenVTables.cpp b/clang/lib/CIR/CodeGen/CIRGenVTables.cpp index 123246f3b3d3f..4c9ee965bebec 100644 --- a/clang/lib/CIR/CodeGen/CIRGenVTables.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenVTables.cpp @@ -499,8 +499,10 @@ void CIRGenVTables::emitVTTDefinition(cir::GlobalOp vttOp, }; auto indicesAttr = mlir::ArrayAttr::get(mlirContext, indices); - cir::GlobalViewAttr init = cgm.getBuilder().getGlobalViewAttr( - cgm.getBuilder().getUInt8PtrTy(), vtable, indicesAttr); + auto init = cir::GlobalViewAttr::get( + cgm.getBuilder().getUInt8PtrTy(), + mlir::FlatSymbolRefAttr::get(vtable.getSymNameAttr()), indicesAttr, + /*addressPoint=*/true); vttComponents.push_back(init); } diff --git a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp index 2649ed1449739..388de73108bee 100644 --- a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp @@ -57,6 +57,11 @@ parseDataMemberPath(mlir::AsmParser &parser, static void printDataMemberPath(mlir::AsmPrinter &p, mlir::DenseI32ArrayAttr memberPath); +static mlir::ParseResult parseGlobalViewAddressPoint(mlir::AsmParser &parser, + bool &addressPoint); + +static void printGlobalViewAddressPoint(mlir::AsmPrinter &p, bool addressPoint); + #define GET_ATTRDEF_CLASSES #include "clang/CIR/Dialect/IR/CIROpsAttributes.cpp.inc" @@ -353,6 +358,19 @@ static void printDataMemberPath(AsmPrinter &p, p.printStrippedAttrOrType(memberPath); } +static ParseResult parseGlobalViewAddressPoint(AsmParser &parser, + bool &addressPoint) { + addressPoint = parser.parseOptionalComma().succeeded(); + if (addressPoint) + return parser.parseKeyword("address_point"); + return success(); +} + +static void printGlobalViewAddressPoint(AsmPrinter &p, bool addressPoint) { + if (addressPoint) + p << ", address_point"; +} + //===----------------------------------------------------------------------===// // IntAttr definitions //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp b/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp index 9a0e40bd4f506..750366bfa78c2 100644 --- a/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp +++ b/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp @@ -210,7 +210,8 @@ mlir::Attribute rewriteAttribute(const mlir::TypeConverter &tc, return cir::GlobalViewAttr::get( tc.convertType(gva.getType()), gva.getSymbol(), mlir::cast<mlir::ArrayAttr>( - rewriteAttribute(tc, ctx, gva.getIndices()))); + rewriteAttribute(tc, ctx, gva.getIndices())), + gva.getAddressPoint()); }) .Case<cir::GlobalOffsetAttr>([&tc](cir::GlobalOffsetAttr goa) { return cir::GlobalOffsetAttr::get(tc.convertType(goa.getType()), @@ -504,7 +505,7 @@ static mlir::TypedAttr lowerInitialValue(const LowerModule *lowerModule, if (auto gva = mlir::dyn_cast_if_present<cir::GlobalViewAttr>(initVal)) return cir::GlobalViewAttr::get(convertedTy, gva.getSymbol(), - gva.getIndices()); + gva.getIndices(), gva.getAddressPoint()); if (auto goa = mlir::dyn_cast_if_present<cir::GlobalOffsetAttr>(initVal)) return cir::GlobalOffsetAttr::get(convertedTy, goa.getSymbol(), diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 007b673419056..57e8dc534633e 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -1018,9 +1018,30 @@ mlir::Value CIRAttrToValue::visitCirAttr(cir::GlobalViewAttr globalAttr) { } mlir::Type resTy = addrOp.getType(); mlir::Type eltTy = converter->convertType(sourceType); - addrOp = mlir::LLVM::GEPOp::create(rewriter, parentOp->getLoc(), resTy, - eltTy, addrOp, indices, - mlir::LLVM::GEPNoWrapFlags::none); + auto gep = mlir::LLVM::GEPOp::create(rewriter, parentOp->getLoc(), resTy, + eltTy, addrOp, indices, + mlir::LLVM::GEPNoWrapFlags::none); + if (globalAttr.getAddressPoint()) { + // Like classic codegen, a vtable address point is inbounds, and only the + // one vtable of the group it points into can be accessed through it. + auto indices = + globalAttr.getIndices().getAsValueRange<mlir::IntegerAttr>(); + assert(llvm::range_size(indices) == 2 && + "address point takes a vtable index and a slot index"); + auto vtableTy = mlir::cast<mlir::LLVM::LLVMArrayType>( + mlir::cast<mlir::LLVM::LLVMStructType>(eltTy) + .getBody()[(*indices.begin()).getZExtValue()]); + mlir::DataLayout layout(parentOp->getParentOfType<mlir::ModuleOp>()); + int64_t slotSize = layout.getTypeSize(vtableTy.getElementType()); + int64_t offset = (*std::next(indices.begin())).getSExtValue() * slotSize; + int64_t size = vtableTy.getNumElements() * slotSize; + unsigned indexBits = *layout.getTypeIndexBitwidth( + mlir::cast<mlir::LLVM::LLVMPointerType>(addrOp.getType())); + gep.setNoWrapFlags(mlir::LLVM::GEPNoWrapFlags::inbounds); + gep.setInrangeAttr(mlir::LLVM::ConstantRangeAttr::get( + rewriter.getContext(), indexBits, -offset, size - offset)); + } + addrOp = gep; } return castGlobalAddrToType(addrOp, globalAttr.getType(), sourceType, diff --git a/clang/test/CIR/CodeGen/global-ptr-init.cpp b/clang/test/CIR/CodeGen/global-ptr-init.cpp index 9a9824881a98c..4704dde5fbec9 100644 --- a/clang/test/CIR/CodeGen/global-ptr-init.cpp +++ b/clang/test/CIR/CodeGen/global-ptr-init.cpp @@ -11,6 +11,19 @@ struct B { }; B x; -// CIR: cir.global external @x = #cir.const_record<{#cir.global_view<@_ZTV1B, [0 : i32, 2 : i32]> : !cir.vptr}> : !rec_B -// LLVM: @x = global %struct.B { ptr getelementptr inbounds nuw (i8, ptr @_ZTV1B, i64 16) }, align 8 +// CIR: cir.global external @x = #cir.const_record<{#cir.global_view<@_ZTV1B, [0 : i32, 2 : i32], address_point> : !cir.vptr}> : !rec_B +// LLVM: @x = global %struct.B { ptr getelementptr inbounds nuw inrange(-16, 24) (i8, ptr @_ZTV1B, i64 16) }, align 8 // OGCG: @x = global %struct.B { ptr getelementptr inbounds inrange(-16, 24) (i8, ptr @_ZTV1B, i64 16) }, align 8 + +// The vtable is only declared here: the inrange bound still comes from its type. +struct K { + virtual void f(); +}; +K k; + +// CIR: cir.global "private" constant external @_ZTV1K : !rec_anon_struct +// CIR: cir.global external @k = #cir.const_record<{#cir.global_view<@_ZTV1K, [0 : i32, 2 : i32], address_point> : !cir.vptr}> : !rec_K +// LLVM: @_ZTV1K = external constant { [3 x ptr] }, align 8 +// OGCG: @_ZTV1K = external constant { [3 x ptr] }, align 8 +// LLVM: @k = global %struct.K { ptr getelementptr inbounds nuw inrange(-16, 8) (i8, ptr @_ZTV1K, i64 16) }, align 8 +// OGCG: @k = global %struct.K { ptr getelementptr inbounds inrange(-16, 8) (i8, ptr @_ZTV1K, i64 16) }, align 8 diff --git a/clang/test/CIR/CodeGen/vtt.cpp b/clang/test/CIR/CodeGen/vtt.cpp index 6bd87bf75b7d8..e2100609d0601 100644 --- a/clang/test/CIR/CodeGen/vtt.cpp +++ b/clang/test/CIR/CodeGen/vtt.cpp @@ -107,23 +107,23 @@ void D::y() {} // VTT for D // CIR-COMMON: cir.global{{.*}} @_ZTT1D = #cir.const_array<[ -// CIR-COMMON-SAME: #cir.global_view<@_ZTV1D, [0 : i32, 3 : i32]> : !cir.ptr<!u8i>, -// CIR-COMMON-SAME: #cir.global_view<@_ZTC1D0_1B, [0 : i32, 3 : i32]> : !cir.ptr<!u8i>, -// CIR-COMMON-SAME: #cir.global_view<@_ZTC1D0_1B, [1 : i32, 3 : i32]> : !cir.ptr<!u8i>, -// CIR-COMMON-SAME: #cir.global_view<@_ZTC1D16_1C, [0 : i32, 3 : i32]> : !cir.ptr<!u8i>, -// CIR-COMMON-SAME: #cir.global_view<@_ZTC1D16_1C, [1 : i32, 3 : i32]> : !cir.ptr<!u8i>, -// CIR-COMMON-SAME: #cir.global_view<@_ZTV1D, [2 : i32, 3 : i32]> : !cir.ptr<!u8i>, -// CIR-COMMON-SAME: #cir.global_view<@_ZTV1D, [1 : i32, 3 : i32]> : !cir.ptr<!u8i> +// CIR-COMMON-SAME: #cir.global_view<@_ZTV1D, [0 : i32, 3 : i32], address_point> : !cir.ptr<!u8i>, +// CIR-COMMON-SAME: #cir.global_view<@_ZTC1D0_1B, [0 : i32, 3 : i32], address_point> : !cir.ptr<!u8i>, +// CIR-COMMON-SAME: #cir.global_view<@_ZTC1D0_1B, [1 : i32, 3 : i32], address_point> : !cir.ptr<!u8i>, +// CIR-COMMON-SAME: #cir.global_view<@_ZTC1D16_1C, [0 : i32, 3 : i32], address_point> : !cir.ptr<!u8i>, +// CIR-COMMON-SAME: #cir.global_view<@_ZTC1D16_1C, [1 : i32, 3 : i32], address_point> : !cir.ptr<!u8i>, +// CIR-COMMON-SAME: #cir.global_view<@_ZTV1D, [2 : i32, 3 : i32], address_point> : !cir.ptr<!u8i>, +// CIR-COMMON-SAME: #cir.global_view<@_ZTV1D, [1 : i32, 3 : i32], address_point> : !cir.ptr<!u8i> // CIR-COMMON-SAME: ]> : !cir.array<!cir.ptr<!u8i> x 7> align(8) // LLVM-COMMON: @_ZTT1D = constant [7 x ptr] [ -// LLVM-COMMON-SAME: ptr getelementptr inbounds nuw (i8, ptr @_ZTV1D, i64 24), -// LLVM-COMMON-SAME: ptr getelementptr inbounds nuw (i8, ptr @_ZTC1D0_1B, i64 24), -// LLVM-COMMON-SAME: ptr getelementptr inbounds nuw (i8, ptr @_ZTC1D0_1B, i64 56), -// LLVM-COMMON-SAME: ptr getelementptr inbounds nuw (i8, ptr @_ZTC1D16_1C, i64 24), -// LLVM-COMMON-SAME: ptr getelementptr inbounds nuw (i8, ptr @_ZTC1D16_1C, i64 56), -// LLVM-COMMON-SAME: ptr getelementptr inbounds nuw (i8, ptr @_ZTV1D, i64 96), -// LLVM-COMMON-SAME: ptr getelementptr inbounds nuw (i8, ptr @_ZTV1D, i64 64) +// LLVM-COMMON-SAME: ptr getelementptr inbounds nuw inrange(-24, 16) (i8, ptr @_ZTV1D, i64 24), +// LLVM-COMMON-SAME: ptr getelementptr inbounds nuw inrange(-24, 8) (i8, ptr @_ZTC1D0_1B, i64 24), +// LLVM-COMMON-SAME: ptr getelementptr inbounds nuw inrange(-24, 8) (i8, ptr @_ZTC1D0_1B, i64 56), +// LLVM-COMMON-SAME: ptr getelementptr inbounds nuw inrange(-24, 8) (i8, ptr @_ZTC1D16_1C, i64 24), +// LLVM-COMMON-SAME: ptr getelementptr inbounds nuw inrange(-24, 8) (i8, ptr @_ZTC1D16_1C, i64 56), +// LLVM-COMMON-SAME: ptr getelementptr inbounds nuw inrange(-24, 8) (i8, ptr @_ZTV1D, i64 96), +// LLVM-COMMON-SAME: ptr getelementptr inbounds nuw inrange(-24, 8) (i8, ptr @_ZTV1D, i64 64) // LLVM-COMMON-SAME: ], align 8 // OGCG-COMMON: @_ZTT1D = unnamed_addr constant [7 x ptr] [ diff --git a/clang/test/CIR/CodeGenCXX/base-layout.cpp b/clang/test/CIR/CodeGenCXX/base-layout.cpp index dc80ef1dbb8dd..5c814a2ef48c6 100644 --- a/clang/test/CIR/CodeGenCXX/base-layout.cpp +++ b/clang/test/CIR/CodeGenCXX/base-layout.cpp @@ -14,8 +14,8 @@ struct B : V1, V2 {}; struct D : V3, B {}; constinit D d{}; -// CIR: cir.global external @d = #cir.const_record<{#cir.const_record<{#cir.global_view<@_ZTV1D, [0 : i32, 2 : i32]> : !cir.vptr}> : !rec_V3, #cir.const_record<{#cir.const_record<{#cir.global_view<@_ZTV1D, [1 : i32, 2 : i32]> : !cir.vptr}> : !rec_V1, #cir.const_record<{#cir.global_view<@_ZTV1D, [2 : i32, 2 : i32]> : !cir.vptr}> : !rec_V2}> : !rec_B}> : !rec_D -// LLVM: @d = global %struct.D { %struct.V3 { ptr getelementptr inbounds nuw (i8, ptr @_ZTV1D, i64 16) }, %struct.B { %struct.V1 { ptr getelementptr inbounds nuw (i8, ptr @_ZTV1D, i64 40) }, %struct.V2 { ptr getelementptr inbounds nuw (i8, ptr @_ZTV1D, i64 64) } } } +// CIR: cir.global external @d = #cir.const_record<{#cir.const_record<{#cir.global_view<@_ZTV1D, [0 : i32, 2 : i32], address_point> : !cir.vptr}> : !rec_V3, #cir.const_record<{#cir.const_record<{#cir.global_view<@_ZTV1D, [1 : i32, 2 : i32], address_point> : !cir.vptr}> : !rec_V1, #cir.const_record<{#cir.global_view<@_ZTV1D, [2 : i32, 2 : i32], address_point> : !cir.vptr}> : !rec_V2}> : !rec_B}> : !rec_D +// LLVM: @d = global %struct.D { %struct.V3 { ptr getelementptr inbounds nuw inrange(-16, 8) (i8, ptr @_ZTV1D, i64 16) }, %struct.B { %struct.V1 { ptr getelementptr inbounds nuw inrange(-16, 8) (i8, ptr @_ZTV1D, i64 40) }, %struct.V2 { ptr getelementptr inbounds nuw inrange(-16, 8) (i8, ptr @_ZTV1D, i64 64) } } } // OGCG: @d = global { ptr, ptr, ptr } { ptr getelementptr inbounds inrange(-16, 8) (i8, ptr @_ZTV1D, i64 16), ptr getelementptr inbounds inrange(-16, 8) (i8, ptr @_ZTV1D, i64 40), ptr getelementptr inbounds inrange(-16, 8) (i8, ptr @_ZTV1D, i64 64) } diff --git a/clang/test/CIR/CodeGenCXX/vtable-linkage.cpp b/clang/test/CIR/CodeGenCXX/vtable-linkage.cpp index cdef1dbeb086a..45320352010ff 100644 --- a/clang/test/CIR/CodeGenCXX/vtable-linkage.cpp +++ b/clang/test/CIR/CodeGenCXX/vtable-linkage.cpp @@ -117,11 +117,11 @@ void use_F() { // CIR-DAG: cir.global "private" constant linkonce_odr comdat @_ZTV1C = #cir.vtable<{#cir.const_array<[#cir.ptr<null> : !cir.ptr<!u8i>, #cir.ptr<null> : !cir.ptr<!u8i>, #cir.ptr<null> : !cir.ptr<!u8i>, #cir.global_view<@_ZTI1C> : !cir.ptr<!u8i>, #cir.global_view<@_ZN1C1fEv> : !cir.ptr<!u8i>]> : !cir.array<!cir.ptr<!u8i> x 5>}> : !{{.*}}align(8) // CIR-DAG: cir.global constant linkonce_odr comdat @_ZTS1C = #cir.const_array<"1C" : !cir.array<!s8i x 2>, trailing_zeros> : !cir.array<!s8i x 3> align(1) // CIR-DAG: cir.global constant linkonce_odr comdat @_ZTI1C = #cir.typeinfo<{#cir.global_view<@_ZTVN10__cxxabiv121__vmi_class_type_infoE, [2 : i32]> : !cir.ptr<!u8i>, #cir.global_view<@_ZTS1C> : !cir.ptr<!u8i>, #cir.int<0> : !u32i, #cir.int<1> : !u32i, #cir.global_view<@_ZTI1B> : !cir.ptr<!u8i>, #cir.int<-8189> : !s64i}> : !{{.*}}align(8) -// CIR-DAG: cir.global constant linkonce_odr comdat @_ZTT1C = #cir.const_array<[#cir.global_view<@_ZTV1C, [0 : i32, 4 : i32]> : !cir.ptr<!u8i>, #cir.global_view<@_ZTV1C, [0 : i32, 4 : i32]> : !cir.ptr<!u8i>]> : !cir.array<!cir.ptr<!u8i> x 2> align(8) +// CIR-DAG: cir.global constant linkonce_odr comdat @_ZTT1C = #cir.const_array<[#cir.global_view<@_ZTV1C, [0 : i32, 4 : i32], address_point> : !cir.ptr<!u8i>, #cir.global_view<@_ZTV1C, [0 : i32, 4 : i32], address_point> : !cir.ptr<!u8i>]> : !cir.array<!cir.ptr<!u8i> x 2> align(8) // LLVM-DAG: @_ZTV1C = linkonce_odr constant { [5 x ptr] } { [5 x ptr] [ptr null, ptr null, ptr null, ptr @_ZTI1C, ptr @_ZN1C1fEv] }, comdat, align 8 // LLVM-DAG: @_ZTS1C = linkonce_odr constant [{{[0-9]}} x i8] c"1C\00", comdat, align 1 // LLVM-DAG: @_ZTI1C = linkonce_odr constant { ptr, ptr, i32, i32, ptr, i64 } { ptr getelementptr{{.*}}({{.*}}, ptr @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 {{.*}}), ptr @_ZTS1C, i32 0, i32 1, ptr @_ZTI1B, i64 -8189 }, comdat -// LLVM-DAG: @_ZTT1C = linkonce_odr{{.*}} constant [2 x ptr] [ptr getelementptr inbounds{{.*}}({{.*}}, ptr @_ZTV1C, {{.*}}, ptr getelementptr inbounds {{.*}}({{.*}}, ptr @_ZTV1C{{.*}})] +// LLVM-DAG: @_ZTT1C = linkonce_odr{{.*}} constant [2 x ptr] [ptr getelementptr inbounds {{(nuw )?}}inrange(-32, 8) (i8, ptr @_ZTV1C, i64 32), ptr getelementptr inbounds {{(nuw )?}}inrange(-32, 8) (i8, ptr @_ZTV1C, i64 32)] // D has a key function that is defined in this translation unit so its vtable is // defined in the translation unit. diff --git a/clang/test/CIR/IR/global-view-address-point.cir b/clang/test/CIR/IR/global-view-address-point.cir new file mode 100644 index 0000000000000..0faecab15dd1a --- /dev/null +++ b/clang/test/CIR/IR/global-view-address-point.cir @@ -0,0 +1,35 @@ +// RUN: cir-opt %s --verify-roundtrip | FileCheck %s +// RUN: cir-opt %s -cir-to-llvm | FileCheck %s -check-prefix=MLIR +// RUN: cir-translate %s -cir-to-llvmir --disable-cc-lowering | FileCheck %s -check-prefix=LLVM + +!u8i = !cir.int<u, 8> +!rec_anon_struct = !cir.struct<{data !cir.array<!cir.ptr<!u8i> x 5>, data !cir.array<!cir.ptr<!u8i> x 4>}> +!rec_B = !cir.struct<"B" {data !cir.vptr}> +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + cir.global "private" constant external @_ZTV1D : !rec_anon_struct + + // CHECK: #cir.global_view<@_ZTV1D, [0 : i32, 3 : i32], address_point> : !cir.ptr<!u8i> + // CHECK: #cir.global_view<@_ZTV1D, [1 : i32, 2 : i32], address_point> : !cir.ptr<!u8i> + // CHECK: #cir.global_view<@_ZTV1D, [1 : i32, 2 : i32]> : !cir.ptr<!u8i> + cir.global external @vtt = #cir.const_array<[ + #cir.global_view<@_ZTV1D, [0 : i32, 3 : i32], address_point> : !cir.ptr<!u8i>, + #cir.global_view<@_ZTV1D, [1 : i32, 2 : i32], address_point> : !cir.ptr<!u8i>, + #cir.global_view<@_ZTV1D, [1 : i32, 2 : i32]> : !cir.ptr<!u8i> + ]> : !cir.array<!cir.ptr<!u8i> x 3> + + // CHECK: #cir.global_view<@_ZTV1D, [0 : i32, 3 : i32], address_point> : !cir.vptr + cir.global external @b = #cir.const_record<{#cir.global_view<@_ZTV1D, [0 : i32, 3 : i32], address_point> : !cir.vptr}> : !rec_B +} + +// An address point is inbounds and can only reach the vtable it points into. + +// MLIR: llvm.getelementptr inbounds inrange <i64, -24, 16> %{{.*}}[0, 0, 3] +// MLIR: llvm.getelementptr inbounds inrange <i64, -16, 16> %{{.*}}[0, 1, 2] +// MLIR: llvm.getelementptr %{{.*}}[0, 1, 2] +// MLIR: llvm.getelementptr inbounds inrange <i64, -24, 16> %{{.*}}[0, 0, 3] + +// LLVM: @vtt = global [3 x ptr] [ +// LLVM-SAME: ptr getelementptr inbounds nuw inrange(-24, 16) (i8, ptr @_ZTV1D, i64 24), +// LLVM-SAME: ptr getelementptr inbounds nuw inrange(-16, 16) (i8, ptr @_ZTV1D, i64 56), +// LLVM-SAME: ptr getelementptr inbounds nuw (i8, ptr @_ZTV1D, i64 56)] +// LLVM: @b = global %struct.B { ptr getelementptr inbounds nuw inrange(-24, 16) (i8, ptr @_ZTV1D, i64 24) } >From 23621d812c64df3c5caf3c70e1ae54883d03e845 Mon Sep 17 00:00:00 2001 From: Bruno Cardoso Lopes <[email protected]> Date: Wed, 7 Oct 2026 18:55:47 -0700 Subject: [PATCH 2/2] [CIR] Address review on vtable address points Take the address point through getGlobalViewAttr instead of rebuilding the attribute around an intermediate, and print it with a declarative optional group rather than custom parse/print code. The spelling is now `, address_point true`, matching the trivial-bool precedent. Assisted-by: Muse Code (Muse). --- .../clang/CIR/Dialect/Builder/CIRBaseBuilder.h | 10 ++++++---- clang/include/clang/CIR/Dialect/IR/CIRAttrs.td | 2 +- clang/lib/CIR/CodeGen/CIRGenModule.cpp | 9 +++------ clang/lib/CIR/CodeGen/CIRGenVTables.cpp | 7 +++---- clang/lib/CIR/Dialect/IR/CIRAttrs.cpp | 18 ------------------ clang/test/CIR/CodeGen/global-ptr-init.cpp | 4 ++-- clang/test/CIR/CodeGen/vtt.cpp | 14 +++++++------- clang/test/CIR/CodeGenCXX/base-layout.cpp | 2 +- clang/test/CIR/CodeGenCXX/vtable-linkage.cpp | 2 +- .../test/CIR/IR/global-view-address-point.cir | 12 ++++++------ 10 files changed, 30 insertions(+), 50 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index 36d583cfe9fbe..2ee3fcb7cf209 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -472,21 +472,23 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { /// Get constant address of a global variable as an MLIR attribute. cir::GlobalViewAttr getGlobalViewAttr(cir::PointerType type, cir::GlobalOp globalOp, - mlir::ArrayAttr indices = {}) { + mlir::ArrayAttr indices = {}, + bool addressPoint = false) { auto symbol = mlir::FlatSymbolRefAttr::get(globalOp.getSymNameAttr()); - return cir::GlobalViewAttr::get(type, symbol, indices); + return cir::GlobalViewAttr::get(type, symbol, indices, addressPoint); } /// Get constant address of a global variable as an MLIR attribute. /// This overload converts raw int64_t indices to an ArrayAttr. cir::GlobalViewAttr getGlobalViewAttr(cir::PointerType type, cir::GlobalOp globalOp, - llvm::ArrayRef<int64_t> indices) { + llvm::ArrayRef<int64_t> indices, + bool addressPoint = false) { llvm::SmallVector<mlir::Attribute> attrs; for (int64_t ind : indices) attrs.push_back(getI64IntegerAttr(ind)); mlir::ArrayAttr arAttr = mlir::ArrayAttr::get(getContext(), attrs); - return getGlobalViewAttr(type, globalOp, arAttr); + return getGlobalViewAttr(type, globalOp, arAttr, addressPoint); } cir::GetGlobalOp createGetGlobal(mlir::Location loc, cir::GlobalOp global, diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index 64b8016971c76..4ccdc83f310fb 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -1070,7 +1070,7 @@ def CIR_GlobalViewAttr : CIR_ValueLikeAttr<"GlobalView", "global_view"> { `<` $symbol (`,` $indices^)? - `` custom<GlobalViewAddressPoint>($address_point) + (`,` `address_point` $address_point^)? `>` }]; } diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index fe2201ac44940..39c3ede7b1074 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -1123,12 +1123,9 @@ static mlir::Attribute createNewGlobalView(CIRGenModule &cgm, else if (isa<cir::ArrayType>(oldTy)) newPtrTy = cast<cir::PointerType>(attr.getType()); - if (newPtrTy) { - cir::GlobalViewAttr view = - bld.getGlobalViewAttr(newPtrTy, newGlob, newInds); - return cir::GlobalViewAttr::get(view.getType(), view.getSymbol(), - view.getIndices(), attr.getAddressPoint()); - } + if (newPtrTy) + return bld.getGlobalViewAttr(newPtrTy, newGlob, newInds, + attr.getAddressPoint()); // This may be unreachable in practice, but keep it as errorNYI while CIR // is still under development. diff --git a/clang/lib/CIR/CodeGen/CIRGenVTables.cpp b/clang/lib/CIR/CodeGen/CIRGenVTables.cpp index 4c9ee965bebec..921ae7b6cd144 100644 --- a/clang/lib/CIR/CodeGen/CIRGenVTables.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenVTables.cpp @@ -499,10 +499,9 @@ void CIRGenVTables::emitVTTDefinition(cir::GlobalOp vttOp, }; auto indicesAttr = mlir::ArrayAttr::get(mlirContext, indices); - auto init = cir::GlobalViewAttr::get( - cgm.getBuilder().getUInt8PtrTy(), - mlir::FlatSymbolRefAttr::get(vtable.getSymNameAttr()), indicesAttr, - /*addressPoint=*/true); + CIRGenBuilderTy &bld = cgm.getBuilder(); + auto init = bld.getGlobalViewAttr(bld.getUInt8PtrTy(), vtable, indicesAttr, + /*addressPoint=*/true); vttComponents.push_back(init); } diff --git a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp index 388de73108bee..2649ed1449739 100644 --- a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp @@ -57,11 +57,6 @@ parseDataMemberPath(mlir::AsmParser &parser, static void printDataMemberPath(mlir::AsmPrinter &p, mlir::DenseI32ArrayAttr memberPath); -static mlir::ParseResult parseGlobalViewAddressPoint(mlir::AsmParser &parser, - bool &addressPoint); - -static void printGlobalViewAddressPoint(mlir::AsmPrinter &p, bool addressPoint); - #define GET_ATTRDEF_CLASSES #include "clang/CIR/Dialect/IR/CIROpsAttributes.cpp.inc" @@ -358,19 +353,6 @@ static void printDataMemberPath(AsmPrinter &p, p.printStrippedAttrOrType(memberPath); } -static ParseResult parseGlobalViewAddressPoint(AsmParser &parser, - bool &addressPoint) { - addressPoint = parser.parseOptionalComma().succeeded(); - if (addressPoint) - return parser.parseKeyword("address_point"); - return success(); -} - -static void printGlobalViewAddressPoint(AsmPrinter &p, bool addressPoint) { - if (addressPoint) - p << ", address_point"; -} - //===----------------------------------------------------------------------===// // IntAttr definitions //===----------------------------------------------------------------------===// diff --git a/clang/test/CIR/CodeGen/global-ptr-init.cpp b/clang/test/CIR/CodeGen/global-ptr-init.cpp index 4704dde5fbec9..b2e9b3e2a5e20 100644 --- a/clang/test/CIR/CodeGen/global-ptr-init.cpp +++ b/clang/test/CIR/CodeGen/global-ptr-init.cpp @@ -11,7 +11,7 @@ struct B { }; B x; -// CIR: cir.global external @x = #cir.const_record<{#cir.global_view<@_ZTV1B, [0 : i32, 2 : i32], address_point> : !cir.vptr}> : !rec_B +// CIR: cir.global external @x = #cir.const_record<{#cir.global_view<@_ZTV1B, [0 : i32, 2 : i32], address_point true> : !cir.vptr}> : !rec_B // LLVM: @x = global %struct.B { ptr getelementptr inbounds nuw inrange(-16, 24) (i8, ptr @_ZTV1B, i64 16) }, align 8 // OGCG: @x = global %struct.B { ptr getelementptr inbounds inrange(-16, 24) (i8, ptr @_ZTV1B, i64 16) }, align 8 @@ -22,7 +22,7 @@ struct K { K k; // CIR: cir.global "private" constant external @_ZTV1K : !rec_anon_struct -// CIR: cir.global external @k = #cir.const_record<{#cir.global_view<@_ZTV1K, [0 : i32, 2 : i32], address_point> : !cir.vptr}> : !rec_K +// CIR: cir.global external @k = #cir.const_record<{#cir.global_view<@_ZTV1K, [0 : i32, 2 : i32], address_point true> : !cir.vptr}> : !rec_K // LLVM: @_ZTV1K = external constant { [3 x ptr] }, align 8 // OGCG: @_ZTV1K = external constant { [3 x ptr] }, align 8 // LLVM: @k = global %struct.K { ptr getelementptr inbounds nuw inrange(-16, 8) (i8, ptr @_ZTV1K, i64 16) }, align 8 diff --git a/clang/test/CIR/CodeGen/vtt.cpp b/clang/test/CIR/CodeGen/vtt.cpp index e2100609d0601..0a150f18b75ac 100644 --- a/clang/test/CIR/CodeGen/vtt.cpp +++ b/clang/test/CIR/CodeGen/vtt.cpp @@ -107,13 +107,13 @@ void D::y() {} // VTT for D // CIR-COMMON: cir.global{{.*}} @_ZTT1D = #cir.const_array<[ -// CIR-COMMON-SAME: #cir.global_view<@_ZTV1D, [0 : i32, 3 : i32], address_point> : !cir.ptr<!u8i>, -// CIR-COMMON-SAME: #cir.global_view<@_ZTC1D0_1B, [0 : i32, 3 : i32], address_point> : !cir.ptr<!u8i>, -// CIR-COMMON-SAME: #cir.global_view<@_ZTC1D0_1B, [1 : i32, 3 : i32], address_point> : !cir.ptr<!u8i>, -// CIR-COMMON-SAME: #cir.global_view<@_ZTC1D16_1C, [0 : i32, 3 : i32], address_point> : !cir.ptr<!u8i>, -// CIR-COMMON-SAME: #cir.global_view<@_ZTC1D16_1C, [1 : i32, 3 : i32], address_point> : !cir.ptr<!u8i>, -// CIR-COMMON-SAME: #cir.global_view<@_ZTV1D, [2 : i32, 3 : i32], address_point> : !cir.ptr<!u8i>, -// CIR-COMMON-SAME: #cir.global_view<@_ZTV1D, [1 : i32, 3 : i32], address_point> : !cir.ptr<!u8i> +// CIR-COMMON-SAME: #cir.global_view<@_ZTV1D, [0 : i32, 3 : i32], address_point true> : !cir.ptr<!u8i>, +// CIR-COMMON-SAME: #cir.global_view<@_ZTC1D0_1B, [0 : i32, 3 : i32], address_point true> : !cir.ptr<!u8i>, +// CIR-COMMON-SAME: #cir.global_view<@_ZTC1D0_1B, [1 : i32, 3 : i32], address_point true> : !cir.ptr<!u8i>, +// CIR-COMMON-SAME: #cir.global_view<@_ZTC1D16_1C, [0 : i32, 3 : i32], address_point true> : !cir.ptr<!u8i>, +// CIR-COMMON-SAME: #cir.global_view<@_ZTC1D16_1C, [1 : i32, 3 : i32], address_point true> : !cir.ptr<!u8i>, +// CIR-COMMON-SAME: #cir.global_view<@_ZTV1D, [2 : i32, 3 : i32], address_point true> : !cir.ptr<!u8i>, +// CIR-COMMON-SAME: #cir.global_view<@_ZTV1D, [1 : i32, 3 : i32], address_point true> : !cir.ptr<!u8i> // CIR-COMMON-SAME: ]> : !cir.array<!cir.ptr<!u8i> x 7> align(8) // LLVM-COMMON: @_ZTT1D = constant [7 x ptr] [ diff --git a/clang/test/CIR/CodeGenCXX/base-layout.cpp b/clang/test/CIR/CodeGenCXX/base-layout.cpp index 5c814a2ef48c6..b9e1b841a2f09 100644 --- a/clang/test/CIR/CodeGenCXX/base-layout.cpp +++ b/clang/test/CIR/CodeGenCXX/base-layout.cpp @@ -14,7 +14,7 @@ struct B : V1, V2 {}; struct D : V3, B {}; constinit D d{}; -// CIR: cir.global external @d = #cir.const_record<{#cir.const_record<{#cir.global_view<@_ZTV1D, [0 : i32, 2 : i32], address_point> : !cir.vptr}> : !rec_V3, #cir.const_record<{#cir.const_record<{#cir.global_view<@_ZTV1D, [1 : i32, 2 : i32], address_point> : !cir.vptr}> : !rec_V1, #cir.const_record<{#cir.global_view<@_ZTV1D, [2 : i32, 2 : i32], address_point> : !cir.vptr}> : !rec_V2}> : !rec_B}> : !rec_D +// CIR: cir.global external @d = #cir.const_record<{#cir.const_record<{#cir.global_view<@_ZTV1D, [0 : i32, 2 : i32], address_point true> : !cir.vptr}> : !rec_V3, #cir.const_record<{#cir.const_record<{#cir.global_view<@_ZTV1D, [1 : i32, 2 : i32], address_point true> : !cir.vptr}> : !rec_V1, #cir.const_record<{#cir.global_view<@_ZTV1D, [2 : i32, 2 : i32], address_point true> : !cir.vptr}> : !rec_V2}> : !rec_B}> : !rec_D // LLVM: @d = global %struct.D { %struct.V3 { ptr getelementptr inbounds nuw inrange(-16, 8) (i8, ptr @_ZTV1D, i64 16) }, %struct.B { %struct.V1 { ptr getelementptr inbounds nuw inrange(-16, 8) (i8, ptr @_ZTV1D, i64 40) }, %struct.V2 { ptr getelementptr inbounds nuw inrange(-16, 8) (i8, ptr @_ZTV1D, i64 64) } } } // OGCG: @d = global { ptr, ptr, ptr } { ptr getelementptr inbounds inrange(-16, 8) (i8, ptr @_ZTV1D, i64 16), ptr getelementptr inbounds inrange(-16, 8) (i8, ptr @_ZTV1D, i64 40), ptr getelementptr inbounds inrange(-16, 8) (i8, ptr @_ZTV1D, i64 64) } diff --git a/clang/test/CIR/CodeGenCXX/vtable-linkage.cpp b/clang/test/CIR/CodeGenCXX/vtable-linkage.cpp index 45320352010ff..ece1a9675761a 100644 --- a/clang/test/CIR/CodeGenCXX/vtable-linkage.cpp +++ b/clang/test/CIR/CodeGenCXX/vtable-linkage.cpp @@ -117,7 +117,7 @@ void use_F() { // CIR-DAG: cir.global "private" constant linkonce_odr comdat @_ZTV1C = #cir.vtable<{#cir.const_array<[#cir.ptr<null> : !cir.ptr<!u8i>, #cir.ptr<null> : !cir.ptr<!u8i>, #cir.ptr<null> : !cir.ptr<!u8i>, #cir.global_view<@_ZTI1C> : !cir.ptr<!u8i>, #cir.global_view<@_ZN1C1fEv> : !cir.ptr<!u8i>]> : !cir.array<!cir.ptr<!u8i> x 5>}> : !{{.*}}align(8) // CIR-DAG: cir.global constant linkonce_odr comdat @_ZTS1C = #cir.const_array<"1C" : !cir.array<!s8i x 2>, trailing_zeros> : !cir.array<!s8i x 3> align(1) // CIR-DAG: cir.global constant linkonce_odr comdat @_ZTI1C = #cir.typeinfo<{#cir.global_view<@_ZTVN10__cxxabiv121__vmi_class_type_infoE, [2 : i32]> : !cir.ptr<!u8i>, #cir.global_view<@_ZTS1C> : !cir.ptr<!u8i>, #cir.int<0> : !u32i, #cir.int<1> : !u32i, #cir.global_view<@_ZTI1B> : !cir.ptr<!u8i>, #cir.int<-8189> : !s64i}> : !{{.*}}align(8) -// CIR-DAG: cir.global constant linkonce_odr comdat @_ZTT1C = #cir.const_array<[#cir.global_view<@_ZTV1C, [0 : i32, 4 : i32], address_point> : !cir.ptr<!u8i>, #cir.global_view<@_ZTV1C, [0 : i32, 4 : i32], address_point> : !cir.ptr<!u8i>]> : !cir.array<!cir.ptr<!u8i> x 2> align(8) +// CIR-DAG: cir.global constant linkonce_odr comdat @_ZTT1C = #cir.const_array<[#cir.global_view<@_ZTV1C, [0 : i32, 4 : i32], address_point true> : !cir.ptr<!u8i>, #cir.global_view<@_ZTV1C, [0 : i32, 4 : i32], address_point true> : !cir.ptr<!u8i>]> : !cir.array<!cir.ptr<!u8i> x 2> align(8) // LLVM-DAG: @_ZTV1C = linkonce_odr constant { [5 x ptr] } { [5 x ptr] [ptr null, ptr null, ptr null, ptr @_ZTI1C, ptr @_ZN1C1fEv] }, comdat, align 8 // LLVM-DAG: @_ZTS1C = linkonce_odr constant [{{[0-9]}} x i8] c"1C\00", comdat, align 1 // LLVM-DAG: @_ZTI1C = linkonce_odr constant { ptr, ptr, i32, i32, ptr, i64 } { ptr getelementptr{{.*}}({{.*}}, ptr @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 {{.*}}), ptr @_ZTS1C, i32 0, i32 1, ptr @_ZTI1B, i64 -8189 }, comdat diff --git a/clang/test/CIR/IR/global-view-address-point.cir b/clang/test/CIR/IR/global-view-address-point.cir index 0faecab15dd1a..15cbf4cf0b688 100644 --- a/clang/test/CIR/IR/global-view-address-point.cir +++ b/clang/test/CIR/IR/global-view-address-point.cir @@ -8,17 +8,17 @@ module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { cir.global "private" constant external @_ZTV1D : !rec_anon_struct - // CHECK: #cir.global_view<@_ZTV1D, [0 : i32, 3 : i32], address_point> : !cir.ptr<!u8i> - // CHECK: #cir.global_view<@_ZTV1D, [1 : i32, 2 : i32], address_point> : !cir.ptr<!u8i> + // CHECK: #cir.global_view<@_ZTV1D, [0 : i32, 3 : i32], address_point true> : !cir.ptr<!u8i> + // CHECK: #cir.global_view<@_ZTV1D, [1 : i32, 2 : i32], address_point true> : !cir.ptr<!u8i> // CHECK: #cir.global_view<@_ZTV1D, [1 : i32, 2 : i32]> : !cir.ptr<!u8i> cir.global external @vtt = #cir.const_array<[ - #cir.global_view<@_ZTV1D, [0 : i32, 3 : i32], address_point> : !cir.ptr<!u8i>, - #cir.global_view<@_ZTV1D, [1 : i32, 2 : i32], address_point> : !cir.ptr<!u8i>, + #cir.global_view<@_ZTV1D, [0 : i32, 3 : i32], address_point true> : !cir.ptr<!u8i>, + #cir.global_view<@_ZTV1D, [1 : i32, 2 : i32], address_point true> : !cir.ptr<!u8i>, #cir.global_view<@_ZTV1D, [1 : i32, 2 : i32]> : !cir.ptr<!u8i> ]> : !cir.array<!cir.ptr<!u8i> x 3> - // CHECK: #cir.global_view<@_ZTV1D, [0 : i32, 3 : i32], address_point> : !cir.vptr - cir.global external @b = #cir.const_record<{#cir.global_view<@_ZTV1D, [0 : i32, 3 : i32], address_point> : !cir.vptr}> : !rec_B + // CHECK: #cir.global_view<@_ZTV1D, [0 : i32, 3 : i32], address_point true> : !cir.vptr + cir.global external @b = #cir.const_record<{#cir.global_view<@_ZTV1D, [0 : i32, 3 : i32], address_point true> : !cir.vptr}> : !rec_B } // An address point is inbounds and can only reach the vtable it points into. _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
