[BasicAA] Bugfix for r251016
authorJames Molloy <james.molloy@arm.com>
Fri, 23 Oct 2015 14:17:03 +0000 (14:17 +0000)
committerJames Molloy <james.molloy@arm.com>
Fri, 23 Oct 2015 14:17:03 +0000 (14:17 +0000)
If the loaded type sizes don't match the element type of the sequential type, all bets are off and the addresses may, indeed, overlap.

Surprisingly, this just got caught in one test, on one builder, out of the 30+ builders testing this change. Congratulations go to http://lab.llvm.org:8011/builders/clang-aarch64-lnt/builds/5205.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@251112 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/BasicAliasAnalysis.cpp
test/Analysis/BasicAA/sequential-gep.ll

index 7c1255578a2074dfce20d5a672466dce99f6521a..59b2953c3b918f94a0f1a68fb3b0dfcf76ee5a64 100644 (file)
@@ -815,11 +815,17 @@ static AliasResult aliasSameBasePointerGEPs(const GEPOperator *GEP1,
     // Because array indices greater than the number of elements are valid in
     // GEPs, unless we know the intermediate indices are identical between
     // GEP1 and GEP2 we cannot guarantee that the last indexed arrays don't
-    // partially overlap.
+    // partially overlap. We also need to check that the loaded size matches
+    // the element size, otherwise we could still have overlap.
+    const uint64_t ElementSize =
+        DL.getTypeStoreSize(cast<SequentialType>(Ty)->getElementType());
+    if (V1Size != ElementSize || V2Size != ElementSize)
+      return MayAlias;
+
     for (unsigned i = 0, e = GEP1->getNumIndices() - 1; i != e; ++i)
       if (GEP1->getOperand(i + 1) != GEP2->getOperand(i + 1))
         return MayAlias;
-    
+
     // Now we know that the array/pointer that GEP1 indexes into and that
     // that GEP2 indexes into must either precisely overlap or be disjoint.
     // Because they cannot partially overlap and because fields in an array
index f59843742f4b67178d38fd053634d37ad39b64d0..c17a782aa04b65c2f95041e0e3fbaaaddb924a76 100644 (file)
@@ -40,4 +40,15 @@ define void @t4([8 x i32]* %p, i32 %addend, i32* %q) {
   ret void
 }
 
+; CHECK: Function: t5
+; CHECK: PartialAlias: i32* %gep2, i64* %bc
+define void @t5([8 x i32]* %p, i32 %addend, i32* %q) {
+  %knownnonzero = load i32, i32* %q, !range !0
+  %add = add nsw nuw i32 %addend, %knownnonzero
+  %gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 2, i32 %addend
+  %gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 2, i32 %add
+  %bc = bitcast i32* %gep1 to i64*
+  ret void
+}
+
 !0 = !{ i32 1, i32 5 }