Skip to content

Commit 5969e57

Browse files
committed
[IR] Handle large element size when calculating GEP indices
This is a fix for the issue reported at https://reviews.llvm.org/D110043#3019942: The ElementSize is a uint64_t and as such may be larger than the index space, or be negative in the index space. This is UB, but shouldn't cause assertion failures. We address this by detecting whether the size is too large and use a zero index in that case (which is always conservatively correct). Differential Revision: https://reviews.llvm.org/D110437
1 parent 5312063 commit 5969e57

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

llvm/lib/IR/DataLayout.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -903,9 +903,13 @@ int64_t DataLayout::getIndexedOffsetInType(Type *ElemTy,
903903

904904
static void addElementIndex(SmallVectorImpl<APInt> &Indices, TypeSize ElemSize,
905905
APInt &Offset) {
906-
// Skip over scalable or zero size elements.
907-
if (ElemSize.isScalable() || ElemSize == 0) {
908-
Indices.push_back(APInt::getZero(Offset.getBitWidth()));
906+
// Skip over scalable or zero size elements. Also skip element sizes larger
907+
// than the positive index space, because the arithmetic below may not be
908+
// correct in that case.
909+
unsigned BitWidth = Offset.getBitWidth();
910+
if (ElemSize.isScalable() || ElemSize == 0 ||
911+
!isUIntN(BitWidth - 1, ElemSize)) {
912+
Indices.push_back(APInt::getZero(BitWidth));
909913
return;
910914
}
911915

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
; RUN: opt -S -passes=globalopt < %s | FileCheck %s
2+
3+
target datalayout = "p:32:32"
4+
5+
%struct.s.2 = type { %struct.t.1, %struct.t.1, %struct.t.1, %struct.u.0, %struct.u.0 }
6+
%struct.t.1 = type { %struct.u.0, %struct.u.0, %struct.u.0, %struct.u.0, i32, i32, i32, i32 }
7+
%struct.u.0 = type { i32, i32, i32, i8 }
8+
9+
@s = external global [700 x [24000 x %struct.s.2]], align 1
10+
@p = global %struct.s.2* bitcast (i8* getelementptr (i8, i8* bitcast ([700 x [24000 x %struct.s.2]]* @s to i8*), i64 2247483647) to %struct.s.2*), align 1
11+
12+
; CHECK: @p = local_unnamed_addr global %struct.s.2* bitcast (i8* getelementptr (i8, i8* bitcast ([700 x [24000 x %struct.s.2]]* @s to i8*), i32 -2047483649) to %struct.s.2*), align 1

0 commit comments

Comments
 (0)