[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