From cc70e12ebdacd09d5e4e124df81af6e9626be7d7 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 21 Nov 2024 14:58:40 +0100 Subject: [PATCH] [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. --- llvm/lib/IR/Operator.cpp | 12 +++++++++--- llvm/test/Transforms/InstCombine/gep-custom-dl.ll | 8 ++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/llvm/lib/IR/Operator.cpp b/llvm/lib/IR/Operator.cpp index 199eb4d90f55..e1580cf76096 100644 --- a/llvm/lib/IR/Operator.cpp +++ b/llvm/lib/IR/Operator.cpp @@ -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()) { diff --git a/llvm/test/Transforms/InstCombine/gep-custom-dl.ll b/llvm/test/Transforms/InstCombine/gep-custom-dl.ll index c1c11c1acc7b..ed9a5e649763 100644 --- a/llvm/test/Transforms/InstCombine/gep-custom-dl.ll +++ b/llvm/test/Transforms/InstCombine/gep-custom-dl.ll @@ -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 +}