[Operator] Truncate large type sizes in GEP calculations

If the size is larger than the index width, truncate it instead
of asserting.

Longer-term we should consider rejecting types larger than the
index size in the verifier, though this is probably tricky in
practice (it's address space dependent, and types are owned by
the context, not the module).

Fixes https://github.com/llvm/llvm-project/issues/116960.
This commit is contained in:
Nikita Popov 2024-11-21 14:58:40 +01:00
parent df9a14d7bb
commit cc70e12ebd
2 changed files with 17 additions and 3 deletions

View File

@ -136,7 +136,9 @@ bool GEPOperator::accumulateConstantOffset(
bool UsedExternalAnalysis = false;
auto AccumulateOffset = [&](APInt Index, uint64_t Size) -> bool {
Index = Index.sextOrTrunc(Offset.getBitWidth());
APInt IndexedSize = APInt(Offset.getBitWidth(), Size);
// Truncate if type size exceeds index space.
APInt IndexedSize(Offset.getBitWidth(), Size, /*isSigned=*/false,
/*implcitTrunc=*/true);
// For array or vector indices, scale the index by the size of the type.
if (!UsedExternalAnalysis) {
Offset += Index * IndexedSize;
@ -210,7 +212,9 @@ bool GEPOperator::collectOffset(
auto CollectConstantOffset = [&](APInt Index, uint64_t Size) {
Index = Index.sextOrTrunc(BitWidth);
APInt IndexedSize = APInt(BitWidth, Size);
// Truncate if type size exceeds index space.
APInt IndexedSize(BitWidth, Size, /*isSigned=*/false,
/*implcitTrunc=*/true);
ConstantOffset += Index * IndexedSize;
};
@ -248,7 +252,9 @@ bool GEPOperator::collectOffset(
if (STy || ScalableType)
return false;
APInt IndexedSize = APInt(BitWidth, GTI.getSequentialElementStride(DL));
// Truncate if type size exceeds index space.
APInt IndexedSize(BitWidth, GTI.getSequentialElementStride(DL),
/*isSigned=*/false, /*implicitTrunc=*/true);
// Insert an initial offset of 0 for V iff none exists already, then
// increment the offset by IndexedSize.
if (!IndexedSize.isZero()) {

View File

@ -182,3 +182,11 @@ entry:
ret i16 %E
}
define ptr @gep_too_large_type(ptr %p) {
; CHECK-LABEL: @gep_too_large_type(
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i32 -4
; CHECK-NEXT: ret ptr [[GEP]]
;
%gep = getelementptr inbounds [4294967295 x i32], ptr %p, i32 1
ret ptr %gep
}