diff --git a/llvm/lib/Analysis/GlobalsModRef.cpp b/llvm/lib/Analysis/GlobalsModRef.cpp index 53262d88ba51af..6869530148c5bd 100644 --- a/llvm/lib/Analysis/GlobalsModRef.cpp +++ b/llvm/lib/Analysis/GlobalsModRef.cpp @@ -401,14 +401,14 @@ bool GlobalsAAResult::AnalyzeUsesOfPointer(Value *V, /// AnalyzeIndirectGlobalMemory - We found an non-address-taken global variable /// which holds a pointer type. See if the global always points to non-aliased -/// heap memory: that is, all initializers of the globals are allocations, and -/// those allocations have no use other than initialization of the global. +/// heap memory: that is, all initializers of the globals store a value known +/// to be obtained via a noalias return function call which have no other use. /// Further, all loads out of GV must directly use the memory, not store the /// pointer somewhere. If this is true, we consider the memory pointed to by /// GV to be owned by GV and can disambiguate other pointers from it. bool GlobalsAAResult::AnalyzeIndirectGlobalMemory(GlobalVariable *GV) { // Keep track of values related to the allocation of the memory, f.e. the - // value produced by the malloc call and any casts. + // value produced by the noalias call and any casts. std::vector AllocRelatedValues; // If the initializer is a valid pointer, bail. @@ -438,7 +438,7 @@ bool GlobalsAAResult::AnalyzeIndirectGlobalMemory(GlobalVariable *GV) { // Check the value being stored. Value *Ptr = getUnderlyingObject(SI->getOperand(0)); - if (!isAllocLikeFn(Ptr, &GetTLI(*SI->getFunction()))) + if (!isNoAliasCall(Ptr)) return false; // Too hard to analyze. // Analyze all uses of the allocation. If any of them are used in a diff --git a/llvm/test/Analysis/GlobalsModRef/indirect-global.ll b/llvm/test/Analysis/GlobalsModRef/indirect-global.ll index 661eae091b2472..c8f6d36d0cd9c0 100644 --- a/llvm/test/Analysis/GlobalsModRef/indirect-global.ll +++ b/llvm/test/Analysis/GlobalsModRef/indirect-global.ll @@ -7,7 +7,7 @@ @G = internal global i32* null ; [#uses=3] -declare i8* @malloc(i32) +declare noalias i8* @malloc(i32) define void @malloc_init() { ; CHECK-LABEL: @malloc_init( ; CHECK-NEXT: [[A:%.*]] = call dereferenceable_or_null(4) i8* @malloc(i32 4) @@ -36,7 +36,7 @@ define i32 @malloc_test(i32* %P) { @G2 = internal global i32* null ; [#uses=3] -declare i8* @calloc(i32, i32) +declare noalias i8* @calloc(i32, i32) define void @calloc_init() { ; CHECK-LABEL: @calloc_init( ; CHECK-NEXT: [[A:%.*]] = call dereferenceable_or_null(4) i8* @calloc(i32 4, i32 1) @@ -80,12 +80,8 @@ define void @my_alloc_init() { define i32 @my_alloc_test(i32* %P) { ; CHECK-LABEL: @my_alloc_test( -; CHECK-NEXT: [[G1:%.*]] = load i32*, i32** @G3, align 8 -; CHECK-NEXT: [[H1:%.*]] = load i32, i32* [[G1]], align 4 ; CHECK-NEXT: store i32 123, i32* [[P:%.*]], align 4 -; CHECK-NEXT: [[H2:%.*]] = load i32, i32* [[G1]], align 4 -; CHECK-NEXT: [[X:%.*]] = sub i32 [[H1]], [[H2]] -; CHECK-NEXT: ret i32 [[X]] +; CHECK-NEXT: ret i32 0 ; %g1 = load i32*, i32** @G3 ; [#uses=2] %h1 = load i32, i32* %g1 ; [#uses=1]