Skip to content

Commit cc70e12

Browse files
committed
[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 #116960.
1 parent df9a14d commit cc70e12

File tree

2 files changed

+17
-3
lines changed

2 files changed

+17
-3
lines changed

llvm/lib/IR/Operator.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,9 @@ bool GEPOperator::accumulateConstantOffset(
136136
bool UsedExternalAnalysis = false;
137137
auto AccumulateOffset = [&](APInt Index, uint64_t Size) -> bool {
138138
Index = Index.sextOrTrunc(Offset.getBitWidth());
139-
APInt IndexedSize = APInt(Offset.getBitWidth(), Size);
139+
// Truncate if type size exceeds index space.
140+
APInt IndexedSize(Offset.getBitWidth(), Size, /*isSigned=*/false,
141+
/*implcitTrunc=*/true);
140142
// For array or vector indices, scale the index by the size of the type.
141143
if (!UsedExternalAnalysis) {
142144
Offset += Index * IndexedSize;
@@ -210,7 +212,9 @@ bool GEPOperator::collectOffset(
210212

211213
auto CollectConstantOffset = [&](APInt Index, uint64_t Size) {
212214
Index = Index.sextOrTrunc(BitWidth);
213-
APInt IndexedSize = APInt(BitWidth, Size);
215+
// Truncate if type size exceeds index space.
216+
APInt IndexedSize(BitWidth, Size, /*isSigned=*/false,
217+
/*implcitTrunc=*/true);
214218
ConstantOffset += Index * IndexedSize;
215219
};
216220

@@ -248,7 +252,9 @@ bool GEPOperator::collectOffset(
248252

249253
if (STy || ScalableType)
250254
return false;
251-
APInt IndexedSize = APInt(BitWidth, GTI.getSequentialElementStride(DL));
255+
// Truncate if type size exceeds index space.
256+
APInt IndexedSize(BitWidth, GTI.getSequentialElementStride(DL),
257+
/*isSigned=*/false, /*implicitTrunc=*/true);
252258
// Insert an initial offset of 0 for V iff none exists already, then
253259
// increment the offset by IndexedSize.
254260
if (!IndexedSize.isZero()) {

llvm/test/Transforms/InstCombine/gep-custom-dl.ll

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,3 +182,11 @@ entry:
182182
ret i16 %E
183183
}
184184

185+
define ptr @gep_too_large_type(ptr %p) {
186+
; CHECK-LABEL: @gep_too_large_type(
187+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i32 -4
188+
; CHECK-NEXT: ret ptr [[GEP]]
189+
;
190+
%gep = getelementptr inbounds [4294967295 x i32], ptr %p, i32 1
191+
ret ptr %gep
192+
}

0 commit comments

Comments
 (0)