Fix a problem in alias analysis. It is about the misinterpretation of "Object".
authorShuxin Yang <shuxin.llvm@gmail.com>
Thu, 28 Feb 2013 00:24:45 +0000 (00:24 +0000)
committerShuxin Yang <shuxin.llvm@gmail.com>
Thu, 28 Feb 2013 00:24:45 +0000 (00:24 +0000)
This problem is exposed by r171325 which is already reverted. It is rather
hard to fabricate a testing case without it.

r171325 should *NOT* be resurrected as it has a potential problem although
this problem dosen't directly contribute to PR14988.

The bug is tracked by:
  - rdar://13063553, and
  - http://llvm.org/bugs/show_bug.cgi?id=14988

Thank Arnold for coming up a better solution to this problem. After
comparing this solution and my original proposal, I decided to ditch mine.

llvm-svn: 176225

llvm/lib/Analysis/BasicAliasAnalysis.cpp

index ca668b2..ad36cbb 100644 (file)
@@ -98,6 +98,35 @@ static uint64_t getObjectSize(const Value *V, const DataLayout &TD,
 static bool isObjectSmallerThan(const Value *V, uint64_t Size,
                                 const DataLayout &TD,
                                 const TargetLibraryInfo &TLI) {
+  // Note that the meanings of the "object" are slightly different in the
+  // following contexts:
+  //    c1: llvm::getObjectSize()
+  //    c2: llvm.objectsize() intrinsic
+  //    c3: isObjectSmallerThan()
+  // c1 and c2 share the same meaning; however, the meaning of "object" in c3
+  // refers to the "entire object".
+  //
+  //  Consider this example:
+  //     char *p = (char*)malloc(100)
+  //     char *q = p+80;
+  //
+  //  In the context of c1 and c2, the "object" pointed by q refers to the
+  // stretch of memory of q[0:19]. So, getObjectSize(q) should return 20.
+  //
+  //  However, in the context of c3, the "object" refers to the chunk of memory
+  // being allocated. So, the "object" has 100 bytes, and q points to the middle
+  // the "object". In case q is passed to isObjectSmallerThan() as the 1st
+  // parameter, before the llvm::getObjectSize() is called to get the size of
+  // entire object, we should:
+  //    - either rewind the pointer q to the base-address of the object in
+  //      question (in this case rewind to p), or
+  //    - just give up. It is up to caller to make sure the pointer is pointing
+  //      to the base address the object.
+  // 
+  // We go for 2nd option for simplicity.
+  if (!isIdentifiedObject(V))
+    return false;
+
   // This function needs to use the aligned object size because we allow
   // reads a bit past the end given sufficient alignment.
   uint64_t ObjectSize = getObjectSize(V, TD, TLI, /*RoundToAlign*/true);