MemoryBuiltins:
authorNuno Lopes <nunoplopes@sapo.pt>
Thu, 28 Jun 2012 16:34:03 +0000 (16:34 +0000)
committerNuno Lopes <nunoplopes@sapo.pt>
Thu, 28 Jun 2012 16:34:03 +0000 (16:34 +0000)
 - recognize C++ new(std::nothrow) friends
 - ignore ExtractElement and ExtractValue instructions in size/offset analysis (all easy cases are probably folded away before we get here)
 - also recognize realloc as noalias

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

include/llvm/Analysis/MemoryBuiltins.h
lib/Analysis/MemoryBuiltins.cpp

index 4072878f39b5aa14e7fa554a3a7ab93c2f850411..f8184ff43ec6ced866a39b3458425891fe7bfece 100644 (file)
@@ -37,7 +37,7 @@ class Value;
 bool isAllocationFn(const Value *V, bool LookThroughBitCast = false);
 
 /// \brief Tests if a value is a call or invoke to a function that returns a
-/// NoAlias pointer (including malloc/calloc/strdup-like functions).
+/// NoAlias pointer (including malloc/calloc/realloc/strdup-like functions).
 bool isNoAliasFn(const Value *V, bool LookThroughBitCast = false);
 
 /// \brief Tests if a value is a call or invoke to a library function that
@@ -174,6 +174,7 @@ public:
   SizeOffsetType visitArgument(Argument &A);
   SizeOffsetType visitCallSite(CallSite CS);
   SizeOffsetType visitConstantPointerNull(ConstantPointerNull&);
+  SizeOffsetType visitExtractElementInst(ExtractElementInst &I);
   SizeOffsetType visitExtractValueInst(ExtractValueInst &I);
   SizeOffsetType visitGEPOperator(GEPOperator &GEP);
   SizeOffsetType visitGlobalVariable(GlobalVariable &GV);
@@ -233,6 +234,8 @@ public:
 
   SizeOffsetEvalType visitAllocaInst(AllocaInst &I);
   SizeOffsetEvalType visitCallSite(CallSite CS);
+  SizeOffsetEvalType visitExtractElementInst(ExtractElementInst &I);
+  SizeOffsetEvalType visitExtractValueInst(ExtractValueInst &I);
   SizeOffsetEvalType visitGEPOperator(GEPOperator &GEP);
   SizeOffsetEvalType visitIntToPtrInst(IntToPtrInst&);
   SizeOffsetEvalType visitLoadInst(LoadInst &I);
index 6b21b73f22f831dd27aa3aa5349dcc72d15ec0e3..b60b728b91571042eb9519a2cf8aefb66bfa35f7 100644 (file)
@@ -46,19 +46,25 @@ struct AllocFnsTy {
   signed char FstParam, SndParam;
 };
 
+// FIXME: certain users need more information. E.g., SimplifyLibCalls needs to
+// know which functions are nounwind, noalias, nocapture parameters, etc.
 static const AllocFnsTy AllocationFnData[] = {
-  {"malloc",         MallocLike,  1, 0,  -1},
-  {"valloc",         MallocLike,  1, 0,  -1},
-  {"_Znwj",          MallocLike,  1, 0,  -1}, // operator new(unsigned int)
-  {"_Znwm",          MallocLike,  1, 0,  -1}, // operator new(unsigned long)
-  {"_Znaj",          MallocLike,  1, 0,  -1}, // operator new[](unsigned int)
-  {"_Znam",          MallocLike,  1, 0,  -1}, // operator new[](unsigned long)
-  {"posix_memalign", MallocLike,  3, 2,  -1},
-  {"calloc",         CallocLike,  2, 0,  1},
-  {"realloc",        ReallocLike, 2, 1,  -1},
-  {"reallocf",       ReallocLike, 2, 1,  -1},
-  {"strdup",         StrDupLike,  1, -1, -1},
-  {"strndup",        StrDupLike,  2, -1, -1}
+  {"malloc",              MallocLike,  1, 0,  -1},
+  {"valloc",              MallocLike,  1, 0,  -1},
+  {"_Znwj",               MallocLike,  1, 0,  -1}, // new(unsigned int)
+  {"_ZnwjRKSt9nothrow_t", MallocLike,  2, 0,  -1}, // new(unsigned int, nothrow)
+  {"_Znwm",               MallocLike,  1, 0,  -1}, // new(unsigned long)
+  {"_ZnwmRKSt9nothrow_t", MallocLike,  2, 0,  -1}, // new(unsigned long, nothrow)
+  {"_Znaj",               MallocLike,  1, 0,  -1}, // new[](unsigned int)
+  {"_ZnajRKSt9nothrow_t", MallocLike,  2, 0,  -1}, // new[](unsigned int, nothrow)
+  {"_Znam",               MallocLike,  1, 0,  -1}, // new[](unsigned long)
+  {"_ZnamRKSt9nothrow_t", MallocLike,  2, 0,  -1}, // new[](unsigned long, nothrow)
+  {"posix_memalign",      MallocLike,  3, 2,  -1},
+  {"calloc",              CallocLike,  2, 0,  1},
+  {"realloc",             ReallocLike, 2, 1,  -1},
+  {"reallocf",            ReallocLike, 2, 1,  -1},
+  {"strdup",              StrDupLike,  1, -1, -1},
+  {"strndup",             StrDupLike,  2, -1, -1}
 };
 
 
@@ -131,9 +137,11 @@ bool llvm::isAllocationFn(const Value *V, bool LookThroughBitCast) {
 }
 
 /// \brief Tests if a value is a call or invoke to a function that returns a
-/// NoAlias pointer (including malloc/calloc/strdup-like functions).
+/// NoAlias pointer (including malloc/calloc/realloc/strdup-like functions).
 bool llvm::isNoAliasFn(const Value *V, bool LookThroughBitCast) {
-  return isAllocLikeFn(V, LookThroughBitCast) ||
+  // it's safe to consider realloc as noalias since accessing the original
+  // pointer is undefined behavior
+  return isAllocationFn(V, LookThroughBitCast) ||
          hasNoAliasAttr(V, LookThroughBitCast);
 }
 
@@ -440,6 +448,11 @@ ObjectSizeOffsetVisitor::visitConstantPointerNull(ConstantPointerNull&) {
   return std::make_pair(Zero, Zero);
 }
 
+SizeOffsetType
+ObjectSizeOffsetVisitor::visitExtractElementInst(ExtractElementInst&) {
+  return unknown();
+}
+
 SizeOffsetType
 ObjectSizeOffsetVisitor::visitExtractValueInst(ExtractValueInst&) {
   // Easy cases were already folded by previous passes.
@@ -616,6 +629,16 @@ SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitCallSite(CallSite CS) {
   // - memset
 }
 
+SizeOffsetEvalType
+ObjectSizeOffsetEvaluator::visitExtractElementInst(ExtractElementInst&) {
+  return unknown();
+}
+
+SizeOffsetEvalType
+ObjectSizeOffsetEvaluator::visitExtractValueInst(ExtractValueInst&) {
+  return unknown();
+}
+
 SizeOffsetEvalType
 ObjectSizeOffsetEvaluator::visitGEPOperator(GEPOperator &GEP) {
   SizeOffsetEvalType PtrData = compute_(GEP.getPointerOperand());