[llvm] cc70e12 - [Operator] Truncate large type sizes in GEP calculations

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 21 06:00:58 PST 2024


Author: Nikita Popov
Date: 2024-11-21T15:00:43+01:00
New Revision: cc70e12ebdacd09d5e4e124df81af6e9626be7d7

URL: https://github.com/llvm/llvm-project/commit/cc70e12ebdacd09d5e4e124df81af6e9626be7d7
DIFF: https://github.com/llvm/llvm-project/commit/cc70e12ebdacd09d5e4e124df81af6e9626be7d7.diff

LOG: [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.

Added: 
    

Modified: 
    llvm/lib/IR/Operator.cpp
    llvm/test/Transforms/InstCombine/gep-custom-dl.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/IR/Operator.cpp b/llvm/lib/IR/Operator.cpp
index 199eb4d90f5565..e1580cf7609699 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 c1c11c1acc7bbc..ed9a5e64976382 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
+}


        


More information about the llvm-commits mailing list