From b5c86504a06576e1fd542ee873042fbd307840ea Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Fri, 31 Oct 2014 20:52:04 +0000 Subject: [PATCH] R600: Don't promote allocas when one of the users is a ptrtoint instruction We need to figure out how to track ptrtoint values all the way until result is converted back to a pointer in order to correctly rewrite the pointer type. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220997 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/R600/AMDGPUPromoteAlloca.cpp | 25 +++++++++++++++++++------ test/CodeGen/R600/private-memory.ll | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/lib/Target/R600/AMDGPUPromoteAlloca.cpp b/lib/Target/R600/AMDGPUPromoteAlloca.cpp index 8e85b03d4eb..b81fef47d55 100644 --- a/lib/Target/R600/AMDGPUPromoteAlloca.cpp +++ b/lib/Target/R600/AMDGPUPromoteAlloca.cpp @@ -234,7 +234,8 @@ static bool tryPromoteAllocaToVector(AllocaInst *Alloca) { return true; } -static void collectUsesWithPtrTypes(Value *Val, std::vector &WorkList) { +static bool collectUsesWithPtrTypes(Value *Val, std::vector &WorkList) { + bool Success = true; for (User *User : Val->users()) { if(std::find(WorkList.begin(), WorkList.end(), User) != WorkList.end()) continue; @@ -242,11 +243,20 @@ static void collectUsesWithPtrTypes(Value *Val, std::vector &WorkList) { WorkList.push_back(User); continue; } + + // FIXME: Correctly handle ptrtoint instructions. + Instruction *UseInst = dyn_cast(User); + if (UseInst && UseInst->getOpcode() == Instruction::PtrToInt) + return false; + if (!User->getType()->isPointerTy()) continue; + WorkList.push_back(User); - collectUsesWithPtrTypes(User, WorkList); + + Success &= collectUsesWithPtrTypes(User, WorkList); } + return Success; } void AMDGPUPromoteAlloca::visitAlloca(AllocaInst &I) { @@ -274,6 +284,13 @@ void AMDGPUPromoteAlloca::visitAlloca(AllocaInst &I) { return; } + std::vector WorkList; + + if (!collectUsesWithPtrTypes(&I, WorkList)) { + DEBUG(dbgs() << " Do not know how to convert all uses\n"); + return; + } + DEBUG(dbgs() << "Promoting alloca to local memory\n"); LocalMemAvailable -= AllocaSize; @@ -320,10 +337,6 @@ void AMDGPUPromoteAlloca::visitAlloca(AllocaInst &I) { I.replaceAllUsesWith(Offset); I.eraseFromParent(); - std::vector WorkList; - - collectUsesWithPtrTypes(Offset, WorkList); - for (std::vector::iterator i = WorkList.begin(), e = WorkList.end(); i != e; ++i) { Value *V = *i; diff --git a/test/CodeGen/R600/private-memory.ll b/test/CodeGen/R600/private-memory.ll index 820fe699022..b865e91d3f9 100644 --- a/test/CodeGen/R600/private-memory.ll +++ b/test/CodeGen/R600/private-memory.ll @@ -290,3 +290,22 @@ entry: ret void } +; AMDGPUPromoteAlloca does not know how to handle ptrtoint. When it +; finds one, it should stop trying to promote. + +; FUNC-LABEL: ptrtoint: +; SI-NOT: DS_WRITE +; SI: BUFFER_STORE_DWORD v{{[0-9]+}}, v{{[0-9]+}}, s[{{[0-9]+:[0-9]+}}], s{{[0-9]+}} offen +; SI: BUFFER_LOAD_DWORD v{{[0-9]+}}, v{{[0-9]+}}, s[{{[0-9]+:[0-9]+}}], s{{[0-9]+}} offen offset:0x5 +define void @ptrtoint(i32 addrspace(1)* %out, i32 %a, i32 %b) { + %alloca = alloca [16 x i32] + %tmp0 = getelementptr [16 x i32]* %alloca, i32 0, i32 %a + store i32 5, i32* %tmp0 + %tmp1 = ptrtoint [16 x i32]* %alloca to i32 + %tmp2 = add i32 %tmp1, 5 + %tmp3 = inttoptr i32 %tmp2 to i32* + %tmp4 = getelementptr i32* %tmp3, i32 %b + %tmp5 = load i32* %tmp4 + store i32 %tmp5, i32 addrspace(1)* %out + ret void +} -- 2.34.1