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

Bill Wendling wendling at apple.com
Tue Sep 24 11:10:58 PDT 2013


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? :-)

-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