From: Nick Lewycky Date: Fri, 30 May 2014 02:31:27 +0000 (+0000) Subject: When analyzing params/args for readnone/readonly, don't forget to consider that a... X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=59633cb4786309931255ced99e98ab77a03acc4b;p=platform%2Fupstream%2Fllvm.git When analyzing params/args for readnone/readonly, don't forget to consider that a pointer argument may be passed through a callsite to the return, and that we may need to analyze it. Fixes a bug reported on llvm-dev: lists.cs.uiuc.edu/pipermail/llvmdev/2014-May/073098.html llvm-svn: 209870 --- diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp index fed8839..8174df9 100644 --- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp @@ -449,14 +449,29 @@ determinePointerReadAttrs(Argument *A, case Instruction::Call: case Instruction::Invoke: { + bool Captures = true; + + if (I->getType()->isVoidTy()) + Captures = false; + + auto AddUsersToWorklistIfCapturing = [&] { + if (Captures) + for (Use &UU : I->uses()) + if (Visited.insert(&UU)) + Worklist.push_back(&UU); + }; + CallSite CS(I); - if (CS.doesNotAccessMemory()) + if (CS.doesNotAccessMemory()) { + AddUsersToWorklistIfCapturing(); continue; + } Function *F = CS.getCalledFunction(); if (!F) { if (CS.onlyReadsMemory()) { IsRead = true; + AddUsersToWorklistIfCapturing(); continue; } return Attribute::None; @@ -471,6 +486,7 @@ determinePointerReadAttrs(Argument *A, "More params than args in non-varargs call."); return Attribute::None; } + Captures &= !CS.doesNotCapture(A - B); if (SCCNodes.count(AI)) continue; if (!CS.onlyReadsMemory() && !CS.onlyReadsMemory(A - B)) @@ -479,6 +495,7 @@ determinePointerReadAttrs(Argument *A, IsRead = true; } } + AddUsersToWorklistIfCapturing(); break; } diff --git a/llvm/test/Transforms/FunctionAttrs/nocapture.ll b/llvm/test/Transforms/FunctionAttrs/nocapture.ll index d2460c0..d3842c8 100644 --- a/llvm/test/Transforms/FunctionAttrs/nocapture.ll +++ b/llvm/test/Transforms/FunctionAttrs/nocapture.ll @@ -68,7 +68,7 @@ define i1* @lookup_bit(i32* %q, i32 %bitno) readnone nounwind { ret i1* %lookup } -; CHECK: define i1 @c7(i32* readnone %q, i32 %bitno) +; CHECK: define i1 @c7(i32* readonly %q, i32 %bitno) define i1 @c7(i32* %q, i32 %bitno) { %ptr = call i1* @lookup_bit(i32* %q, i32 %bitno) %val = load i1* %ptr diff --git a/llvm/test/Transforms/FunctionAttrs/readattrs.ll b/llvm/test/Transforms/FunctionAttrs/readattrs.ll index 7ae38bb..b4e904c 100644 --- a/llvm/test/Transforms/FunctionAttrs/readattrs.ll +++ b/llvm/test/Transforms/FunctionAttrs/readattrs.ll @@ -51,3 +51,17 @@ define void @test6_2(i8** %p, i8* %q) { define void @test7_1(i32* inalloca %a) { ret void } + +; CHECK: define i32* @test8_1(i32* readnone %p) +define i32* @test8_1(i32* %p) { +entry: + ret i32* %p +} + +; CHECK: define void @test8_2(i32* %p) +define void @test8_2(i32* %p) { +entry: + %call = call i32* @test8_1(i32* %p) + store i32 10, i32* %call, align 4 + ret void +}