Skip to content

Commit 0f46e31

Browse files
authoredMar 20, 2024
[IR] Change representation of getelementptr inrange (#84341)
As part of the migration to ptradd (https://discourse.llvm.org/t/rfc-replacing-getelementptr-with-ptradd/68699), we need to change the representation of the `inrange` attribute, which is used for vtable splitting. Currently, inrange is specified as follows: ``` getelementptr inbounds ({ [4 x ptr], [4 x ptr] }, ptr @vt, i64 0, inrange i32 1, i64 2) ``` The `inrange` is placed on a GEP index, and all accesses must be "in range" of that index. The new representation is as follows: ``` getelementptr inbounds inrange(-16, 16) ({ [4 x ptr], [4 x ptr] }, ptr @vt, i64 0, i32 1, i64 2) ``` This specifies which offsets are "in range" of the GEP result. The new representation will continue working when canonicalizing to ptradd representation: ``` getelementptr inbounds inrange(-16, 16) (i8, ptr @vt, i64 48) ``` The inrange offsets are relative to the return value of the GEP. An alternative design could make them relative to the source pointer instead. The result-relative format was chosen on the off-chance that we want to extend support to non-constant GEPs in the future, in which case this variant is more expressive. This implementation "upgrades" the old inrange representation in bitcode by simply dropping it. This is a very niche feature, and I don't think trying to upgrade it is worthwhile. Let me know if you disagree.
1 parent 1f63a56 commit 0f46e31

File tree

70 files changed

+511
-341
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+511
-341
lines changed
 

‎clang/lib/CodeGen/CGVTT.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,18 @@ CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT,
7777
llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.AddressPointIndex),
7878
};
7979

80+
// Add inrange attribute to indicate that only the VTableIndex can be
81+
// accessed.
82+
unsigned ComponentSize =
83+
CGM.getDataLayout().getTypeAllocSize(getVTableComponentType());
84+
unsigned VTableSize = CGM.getDataLayout().getTypeAllocSize(
85+
cast<llvm::StructType>(VTable->getValueType())
86+
->getElementType(AddressPoint.VTableIndex));
87+
unsigned Offset = ComponentSize * AddressPoint.AddressPointIndex;
88+
llvm::ConstantRange InRange(llvm::APInt(32, -Offset, true),
89+
llvm::APInt(32, VTableSize - Offset, true));
8090
llvm::Constant *Init = llvm::ConstantExpr::getGetElementPtr(
81-
VTable->getValueType(), VTable, Idxs, /*InBounds=*/true,
82-
/*InRangeIndex=*/1);
91+
VTable->getValueType(), VTable, Idxs, /*InBounds=*/true, InRange);
8392

8493
VTTComponents.push_back(Init);
8594
}

‎clang/lib/CodeGen/ItaniumCXXABI.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1885,19 +1885,27 @@ ItaniumCXXABI::getVTableAddressPoint(BaseSubobject Base,
18851885

18861886
// Find the appropriate vtable within the vtable group, and the address point
18871887
// within that vtable.
1888+
const VTableLayout &Layout =
1889+
CGM.getItaniumVTableContext().getVTableLayout(VTableClass);
18881890
VTableLayout::AddressPointLocation AddressPoint =
1889-
CGM.getItaniumVTableContext()
1890-
.getVTableLayout(VTableClass)
1891-
.getAddressPoint(Base);
1891+
Layout.getAddressPoint(Base);
18921892
llvm::Value *Indices[] = {
18931893
llvm::ConstantInt::get(CGM.Int32Ty, 0),
18941894
llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.VTableIndex),
18951895
llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.AddressPointIndex),
18961896
};
18971897

1898-
return llvm::ConstantExpr::getGetElementPtr(VTable->getValueType(), VTable,
1899-
Indices, /*InBounds=*/true,
1900-
/*InRangeIndex=*/1);
1898+
// Add inrange attribute to indicate that only the VTableIndex can be
1899+
// accessed.
1900+
unsigned ComponentSize =
1901+
CGM.getDataLayout().getTypeAllocSize(CGM.getVTableComponentType());
1902+
unsigned VTableSize =
1903+
ComponentSize * Layout.getVTableSize(AddressPoint.VTableIndex);
1904+
unsigned Offset = ComponentSize * AddressPoint.AddressPointIndex;
1905+
llvm::ConstantRange InRange(llvm::APInt(32, -Offset, true),
1906+
llvm::APInt(32, VTableSize - Offset, true));
1907+
return llvm::ConstantExpr::getGetElementPtr(
1908+
VTable->getValueType(), VTable, Indices, /*InBounds=*/true, InRange);
19011909
}
19021910

19031911
// Check whether all the non-inline virtual methods for the class have the

0 commit comments

Comments
 (0)
Please sign in to comment.