[llvm] r191310 - Teach MemoryBuiltins and InstructionSimplify that operator new never returns NULL.

Benjamin Kramer benny.kra at gmail.com
Tue Sep 24 11:43:45 PDT 2013


On 24.09.2013, at 20:10, Bill Wendling <wendling at apple.com> wrote:

> On Sep 24, 2013, at 9:37 AM, Benjamin Kramer <benny.kra at googlemail.com> wrote:
> 
>> Author: d0k
>> Date: Tue Sep 24 11:37:51 2013
>> New Revision: 191310
>> 
>> URL: http://llvm.org/viewvc/llvm-project?rev=191310&view=rev
>> Log:
>> Teach MemoryBuiltins and InstructionSimplify that operator new never returns NULL.
>> 
>> This is safe per C++11 18.6.1.1p3: [operator new returns] a non-null pointer to
>> suitably aligned storage (3.7.4), or else throw a bad_alloc exception. This
>> requirement is binding on a replacement version of this function.
>> 
> Just checking, but I assume that you mean the operator new that can throw never returns null. (The no-throw operator new may return null.) Could you modify the test case to ensure that the no-throw operator new isn't affected by this change? :-)

r191325 adds a test for operator new with nothrow_t.

- Ben


> -bw
> 
>> Brings us a tiny bit closer to eliminating more vector push_backs.
>> 
>> Modified:
>>   llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h
>>   llvm/trunk/include/llvm/Analysis/ValueTracking.h
>>   llvm/trunk/lib/Analysis/InstructionSimplify.cpp
>>   llvm/trunk/lib/Analysis/MemoryBuiltins.cpp
>>   llvm/trunk/lib/Analysis/ValueTracking.cpp
>>   llvm/trunk/test/Transforms/InstSimplify/call.ll
>> 
>> Modified: llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h?rev=191310&r1=191309&r2=191310&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h (original)
>> +++ llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h Tue Sep 24 11:37:51 2013
>> @@ -64,6 +64,10 @@ bool isAllocLikeFn(const Value *V, const
>> bool isReallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
>>                     bool LookThroughBitCast = false);
>> 
>> +/// \brief Tests if a value is a call or invoke to a library function that
>> +/// allocates memory and never returns null (such as operator new).
>> +bool isOperatorNewLikeFn(const Value *V, const TargetLibraryInfo *TLI,
>> +                         bool LookThroughBitCast = false);
>> 
>> //===----------------------------------------------------------------------===//
>> //  malloc Call Utility Functions.
>> 
>> Modified: llvm/trunk/include/llvm/Analysis/ValueTracking.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ValueTracking.h?rev=191310&r1=191309&r2=191310&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/Analysis/ValueTracking.h (original)
>> +++ llvm/trunk/include/llvm/Analysis/ValueTracking.h Tue Sep 24 11:37:51 2013
>> @@ -25,6 +25,7 @@ namespace llvm {
>>  class DataLayout;
>>  class StringRef;
>>  class MDNode;
>> +  class TargetLibraryInfo;
>> 
>>  /// ComputeMaskedBits - Determine which of the bits specified in Mask are
>>  /// known to be either zero or one and return them in the KnownZero/KnownOne
>> @@ -186,7 +187,7 @@ namespace llvm {
>>  /// isKnownNonNull - Return true if this pointer couldn't possibly be null by
>>  /// its definition.  This returns true for allocas, non-extern-weak globals
>>  /// and byval arguments.
>> -  bool isKnownNonNull(const Value *V);
>> +  bool isKnownNonNull(const Value *V, const TargetLibraryInfo *TLI = 0);
>> 
>> } // end namespace llvm
>> 
>> 
>> Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=191310&r1=191309&r2=191310&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
>> +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Tue Sep 24 11:37:51 2013
>> @@ -1739,7 +1739,7 @@ static Constant *computePointerICmp(cons
>>  RHS = RHS->stripPointerCasts();
>> 
>>  // A non-null pointer is not equal to a null pointer.
>> -  if (llvm::isKnownNonNull(LHS) && isa<ConstantPointerNull>(RHS) &&
>> +  if (llvm::isKnownNonNull(LHS, TLI) && isa<ConstantPointerNull>(RHS) &&
>>      (Pred == CmpInst::ICMP_EQ || Pred == CmpInst::ICMP_NE))
>>    return ConstantInt::get(GetCompareTy(LHS),
>>                            !CmpInst::isTrueWhenEqual(Pred));
>> 
>> Modified: llvm/trunk/lib/Analysis/MemoryBuiltins.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryBuiltins.cpp?rev=191310&r1=191309&r2=191310&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Analysis/MemoryBuiltins.cpp (original)
>> +++ llvm/trunk/lib/Analysis/MemoryBuiltins.cpp Tue Sep 24 11:37:51 2013
>> @@ -35,6 +35,7 @@ enum AllocType {
>>  CallocLike         = 1<<1, // allocates + bzero
>>  ReallocLike        = 1<<2, // reallocates
>>  StrDupLike         = 1<<3,
>> +  OpNewLike          = MallocLike | (1<<4), // allocates; never returns null
>>  AllocLike          = MallocLike | CallocLike | StrDupLike,
>>  AnyAlloc           = MallocLike | CallocLike | ReallocLike | StrDupLike
>> };
>> @@ -52,13 +53,13 @@ struct AllocFnsTy {
>> static const AllocFnsTy AllocationFnData[] = {
>>  {LibFunc::malloc,              MallocLike,  1, 0,  -1},
>>  {LibFunc::valloc,              MallocLike,  1, 0,  -1},
>> -  {LibFunc::Znwj,                MallocLike,  1, 0,  -1}, // new(unsigned int)
>> +  {LibFunc::Znwj,                OpNewLike,   1, 0,  -1}, // new(unsigned int)
>>  {LibFunc::ZnwjRKSt9nothrow_t,  MallocLike,  2, 0,  -1}, // new(unsigned int, nothrow)
>> -  {LibFunc::Znwm,                MallocLike,  1, 0,  -1}, // new(unsigned long)
>> +  {LibFunc::Znwm,                OpNewLike,   1, 0,  -1}, // new(unsigned long)
>>  {LibFunc::ZnwmRKSt9nothrow_t,  MallocLike,  2, 0,  -1}, // new(unsigned long, nothrow)
>> -  {LibFunc::Znaj,                MallocLike,  1, 0,  -1}, // new[](unsigned int)
>> +  {LibFunc::Znaj,                OpNewLike,   1, 0,  -1}, // new[](unsigned int)
>>  {LibFunc::ZnajRKSt9nothrow_t,  MallocLike,  2, 0,  -1}, // new[](unsigned int, nothrow)
>> -  {LibFunc::Znam,                MallocLike,  1, 0,  -1}, // new[](unsigned long)
>> +  {LibFunc::Znam,                OpNewLike,   1, 0,  -1}, // new[](unsigned long)
>>  {LibFunc::ZnamRKSt9nothrow_t,  MallocLike,  2, 0,  -1}, // new[](unsigned long, nothrow)
>>  {LibFunc::posix_memalign,      MallocLike,  3, 2,  -1},
>>  {LibFunc::calloc,              CallocLike,  2, 0,   1},
>> @@ -189,6 +190,13 @@ bool llvm::isReallocLikeFn(const Value *
>>  return getAllocationData(V, ReallocLike, TLI, LookThroughBitCast);
>> }
>> 
>> +/// \brief Tests if a value is a call or invoke to a library function that
>> +/// allocates memory and never returns null (such as operator new).
>> +bool llvm::isOperatorNewLikeFn(const Value *V, const TargetLibraryInfo *TLI,
>> +                               bool LookThroughBitCast) {
>> +  return getAllocationData(V, OpNewLike, TLI, LookThroughBitCast);
>> +}
>> +
>> /// extractMallocCall - Returns the corresponding CallInst if the instruction
>> /// is a malloc call.  Since CallInst::CreateMalloc() only creates calls, we
>> /// ignore InvokeInst here.
>> 
>> Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=191310&r1=191309&r2=191310&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
>> +++ llvm/trunk/lib/Analysis/ValueTracking.cpp Tue Sep 24 11:37:51 2013
>> @@ -15,6 +15,7 @@
>> #include "llvm/Analysis/ValueTracking.h"
>> #include "llvm/ADT/SmallPtrSet.h"
>> #include "llvm/Analysis/InstructionSimplify.h"
>> +#include "llvm/Analysis/MemoryBuiltins.h"
>> #include "llvm/IR/Constants.h"
>> #include "llvm/IR/DataLayout.h"
>> #include "llvm/IR/GlobalAlias.h"
>> @@ -2064,7 +2065,7 @@ bool llvm::isSafeToSpeculativelyExecute(
>> 
>> /// isKnownNonNull - Return true if we know that the specified value is never
>> /// null.
>> -bool llvm::isKnownNonNull(const Value *V) {
>> +bool llvm::isKnownNonNull(const Value *V, const TargetLibraryInfo *TLI) {
>>  // Alloca never returns null, malloc might.
>>  if (isa<AllocaInst>(V)) return true;
>> 
>> @@ -2075,5 +2076,10 @@ bool llvm::isKnownNonNull(const Value *V
>>  // Global values are not null unless extern weak.
>>  if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
>>    return !GV->hasExternalWeakLinkage();
>> +
>> +  // operator new never returns null.
>> +  if (isOperatorNewLikeFn(V, TLI, /*LookThroughBitCast=*/true))
>> +    return true;
>> +
>>  return false;
>> }
>> 
>> Modified: llvm/trunk/test/Transforms/InstSimplify/call.ll
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/call.ll?rev=191310&r1=191309&r2=191310&view=diff
>> ==============================================================================
>> --- llvm/trunk/test/Transforms/InstSimplify/call.ll (original)
>> +++ llvm/trunk/test/Transforms/InstSimplify/call.ll Tue Sep 24 11:37:51 2013
>> @@ -101,3 +101,23 @@ define float @test_idempotence(float %a)
>> 
>>  ret float %r4
>> }
>> +
>> +define i8* @operator_new() {
>> +entry:
>> +  %call = tail call noalias i8* @_Znwm(i64 8)
>> +  %cmp = icmp eq i8* %call, null
>> +  br i1 %cmp, label %cast.end, label %cast.notnull
>> +
>> +cast.notnull:                                     ; preds = %entry
>> +  %add.ptr = getelementptr inbounds i8* %call, i64 4
>> +  br label %cast.end
>> +
>> +cast.end:                                         ; preds = %cast.notnull, %entry
>> +  %cast.result = phi i8* [ %add.ptr, %cast.notnull ], [ null, %entry ]
>> +  ret i8* %cast.result
>> +
>> +; CHECK-LABEL: @operator_new
>> +; CHECK: br i1 false, label %cast.end, label %cast.notnull
>> +}
>> +
>> +declare noalias i8* @_Znwm(i64)
>> 
>> 
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> 





More information about the llvm-commits mailing list