[PATCH] D110437: [IR] Handle large element size when calculating GEP indices

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 24 11:48:12 PDT 2021


nikic created this revision.
nikic added reviewers: aeubanks, uabelho.
Herald added subscribers: dexonsmith, hiraditya.
nikic requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

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.


https://reviews.llvm.org/D110437

Files:
  llvm/lib/IR/DataLayout.cpp
  llvm/test/Transforms/GlobalOpt/large-element-size.ll


Index: llvm/test/Transforms/GlobalOpt/large-element-size.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/GlobalOpt/large-element-size.ll
@@ -0,0 +1,12 @@
+; RUN: opt -S -passes=globalopt < %s | FileCheck %s
+
+target datalayout = "p:32:32"
+
+%struct.s.2 = type { %struct.t.1, %struct.t.1, %struct.t.1, %struct.u.0, %struct.u.0 }
+%struct.t.1 = type { %struct.u.0, %struct.u.0, %struct.u.0, %struct.u.0, i32, i32, i32, i32 }
+%struct.u.0 = type { i32, i32, i32, i8 }
+
+ at s = external global [700 x [24000 x %struct.s.2]], align 1
+ at 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
+
+; 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
Index: llvm/lib/IR/DataLayout.cpp
===================================================================
--- llvm/lib/IR/DataLayout.cpp
+++ llvm/lib/IR/DataLayout.cpp
@@ -898,9 +898,13 @@
 
 static void addElementIndex(SmallVectorImpl<APInt> &Indices, TypeSize ElemSize,
                             APInt &Offset) {
-  // Skip over scalable or zero size elements.
-  if (ElemSize.isScalable() || ElemSize == 0) {
-    Indices.push_back(APInt::getZero(Offset.getBitWidth()));
+  // Skip over scalable or zero size elements. Also skip element sizes larger
+  // than the positive index space, because the arithmetic below may not be
+  // correct in that case.
+  unsigned BitWidth = Offset.getBitWidth();
+  if (ElemSize.isScalable() || ElemSize == 0 ||
+      !isUIntN(BitWidth - 1, ElemSize)) {
+    Indices.push_back(APInt::getZero(BitWidth));
     return;
   }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D110437.374915.patch
Type: text/x-patch
Size: 1799 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210924/8f8755c9/attachment.bin>


More information about the llvm-commits mailing list