summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2016-02-02 19:18:53 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2016-02-02 19:18:53 +0000
commitad1348459fd824e45f62bb099521249b6a523fac (patch)
tree56188b86763ecb3bf3b2374c79caf0c398c388ae /llvm
parent853a1fc6d9d433c9d68f6ecd04477bf120e0cb73 (diff)
downloadbcm5719-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.cpp44
-rw-r--r--llvm/test/CodeGen/AMDGPU/promote-alloca-unhandled-intrinsic.ll24
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 }
OpenPOWER on IntegriCloud