diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2016-02-02 19:18:53 +0000 |
---|---|---|
committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2016-02-02 19:18:53 +0000 |
commit | ad1348459fd824e45f62bb099521249b6a523fac (patch) | |
tree | 56188b86763ecb3bf3b2374c79caf0c398c388ae /llvm | |
parent | 853a1fc6d9d433c9d68f6ecd04477bf120e0cb73 (diff) | |
download | bcm5719-llvm-ad1348459fd824e45f62bb099521249b6a523fac.tar.gz bcm5719-llvm-ad1348459fd824e45f62bb099521249b6a523fac.zip |
AMDGPU: Whitelist handled intrinsics
We shouldn't crash on unhandled intrinsics.
Also simplify failure handling in loop.
llvm-svn: 259546
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp | 44 | ||||
-rw-r--r-- | llvm/test/CodeGen/AMDGPU/promote-alloca-unhandled-intrinsic.ll | 24 |
2 files changed, 60 insertions, 8 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp b/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp index cc09ced8f6e..e4f2d5e7e43 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp @@ -399,15 +399,37 @@ static bool tryPromoteAllocaToVector(AllocaInst *Alloca) { return true; } +static bool isCallPromotable(CallInst *CI) { + // TODO: We might be able to handle some cases where the callee is a + // constantexpr bitcast of a function. + if (!CI->getCalledFunction()) + return false; + + IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI); + if (!II) + return false; + + switch (II->getIntrinsicID()) { + case Intrinsic::memcpy: + case Intrinsic::memset: + case Intrinsic::lifetime_start: + case Intrinsic::lifetime_end: + case Intrinsic::invariant_start: + case Intrinsic::invariant_end: + case Intrinsic::invariant_group_barrier: + return true; + default: + return false; + } +} + static bool collectUsesWithPtrTypes(Value *Val, std::vector<Value*> &WorkList) { - bool Success = true; for (User *User : Val->users()) { - if(std::find(WorkList.begin(), WorkList.end(), User) != WorkList.end()) + if (std::find(WorkList.begin(), WorkList.end(), User) != WorkList.end()) continue; + if (CallInst *CI = dyn_cast<CallInst>(User)) { - // TODO: We might be able to handle some cases where the callee is a - // constantexpr bitcast of a function. - if (!CI->getCalledFunction()) + if (!isCallPromotable(CI)) return false; WorkList.push_back(User); @@ -429,10 +451,11 @@ static bool collectUsesWithPtrTypes(Value *Val, std::vector<Value*> &WorkList) { continue; WorkList.push_back(User); - - Success &= collectUsesWithPtrTypes(User, WorkList); + if (!collectUsesWithPtrTypes(User, WorkList)) + return false; } - return Success; + + return true; } void AMDGPUPromoteAlloca::visitAlloca(AllocaInst &I) { @@ -521,6 +544,11 @@ void AMDGPUPromoteAlloca::visitAlloca(AllocaInst &I) { IntrinsicInst *Intr = dyn_cast<IntrinsicInst>(Call); if (!Intr) { + // FIXME: What is this for? It doesn't make sense to promote arbitrary + // function calls. If the call is to a defined function that can also be + // promoted, we should be able to do this once that function is also + // rewritten. + std::vector<Type*> ArgTypes; for (unsigned ArgIdx = 0, ArgEnd = Call->getNumArgOperands(); ArgIdx != ArgEnd; ++ArgIdx) { diff --git a/llvm/test/CodeGen/AMDGPU/promote-alloca-unhandled-intrinsic.ll b/llvm/test/CodeGen/AMDGPU/promote-alloca-unhandled-intrinsic.ll new file mode 100644 index 00000000000..7543f2f82dd --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/promote-alloca-unhandled-intrinsic.ll @@ -0,0 +1,24 @@ +; RUN: opt -S -mtriple=amdgcn-unknown-amdhsa < %s | FileCheck %s + +; This is just an arbitrary intrinisic that shouldn't ever need to be +; handled to ensure it doesn't crash. + +declare void @eh.sjlj.functioncontext(i8*) #2 + +; CHECK-LABEL: @try_promote_unhandled_intrinsic( +; CHECK: alloca +; CHECK: call void @eh.sjlj.functioncontext(i8* %tmp1) +define void @try_promote_unhandled_intrinsic(i32 addrspace(1)* %arg) #2 { +bb: + %tmp = alloca i32, align 4 + %tmp1 = bitcast i32* %tmp to i8* + %tmp2 = getelementptr inbounds i32, i32 addrspace(1)* %arg, i64 1 + %tmp3 = load i32, i32 addrspace(1)* %tmp2 + store i32 %tmp3, i32* %tmp + call void @eh.sjlj.functioncontext(i8* %tmp1) + ret void +} + +attributes #0 = { argmemonly nounwind } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind } |