[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