[PATCH] D55538: [InterleavedAccessAnalysis] Fix integer overflow in insertMember.

Florian Hahn via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 10 18:11:36 PST 2018


fhahn created this revision.
fhahn added reviewers: Ayal, anna, hsaito.

Without checking for integer overflow, invalid members can be added, if
the calculated key overflows, becomes positive and the largest key.

This fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=7560

While looking at the code, the check below also could potentially be
problematic, in case we have only negative indices, with the difference
between smallest and largest bigger than Factor.

  // The largest index is always less than the interleave factor.
  if (Index >= static_cast<int>(Factor))
    return false;


Repository:
  rL LLVM

https://reviews.llvm.org/D55538

Files:
  include/llvm/Analysis/VectorUtils.h
  test/Transforms/LoopVectorize/X86/interleaved-accesses-large-gap.ll


Index: test/Transforms/LoopVectorize/X86/interleaved-accesses-large-gap.ll
===================================================================
--- /dev/null
+++ test/Transforms/LoopVectorize/X86/interleaved-accesses-large-gap.ll
@@ -0,0 +1,38 @@
+; RUN: opt < %s  -loop-vectorize -mtriple x86_64 -S | FileCheck %s
+
+%struct.ST4 = type { i32, i32, i32, i32 }
+
+; The gaps between the memory access in this function are too large for
+; interleaving.
+; CHECK-LABEL: @test
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label %for.body
+
+; CHECK-LABEL: for.body:
+; CHECK: store i32
+; CHECK: store i32
+; CHECK: store i32
+; CHECK: store i32
+; CHECK-NOT: store
+define void @test(%struct.ST4* noalias %B) {
+entry:
+  br label %for.body
+
+for.body:                                         ; preds = %for.body, %entry
+  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+  %p1 = getelementptr inbounds %struct.ST4, %struct.ST4* %B, i64 %indvars.iv, i32 0
+  store i32 65536, i32* %p1, align 4
+  %p2 = getelementptr i32, i32* %p1, i32 -2147483648
+  store i32 65536, i32* %p2, align 4
+  %p3 = getelementptr inbounds %struct.ST4, %struct.ST4* %B, i64 %indvars.iv, i32 2
+  store i32 10, i32* %p3, align 4
+  %p4 = getelementptr inbounds %struct.ST4, %struct.ST4* %B, i64 %indvars.iv, i32 3
+  store i32 12, i32* %p4, align 4
+  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+  %exitcond = icmp eq i64 %indvars.iv.next, 1024
+  br i1 %exitcond, label %for.cond.cleanup, label %for.body
+
+for.cond.cleanup:                                 ; preds = %for.body
+  ret void
+
+}
Index: include/llvm/Analysis/VectorUtils.h
===================================================================
--- include/llvm/Analysis/VectorUtils.h
+++ include/llvm/Analysis/VectorUtils.h
@@ -262,7 +262,13 @@
   bool insertMember(InstTy *Instr, int Index, unsigned NewAlign) {
     assert(NewAlign && "The new member's alignment should be non-zero");
 
-    int Key = Index + SmallestKey;
+    // Make sure the key fits in an int.
+    long long KeyLong =
+        static_cast<long long>(Index) + static_cast<long long>(SmallestKey);
+    if (KeyLong > std::numeric_limits<int>::max() ||
+        KeyLong < std::numeric_limits<int>::min())
+      return false;
+    int Key = KeyLong;
 
     // Skip if there is already a member with the same index.
     if (Members.find(Key) != Members.end())


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D55538.177640.patch
Type: text/x-patch
Size: 2397 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181211/bfb92a20/attachment.bin>


More information about the llvm-commits mailing list