]> granicus.if.org Git - llvm/commitdiff
Merging r259546:
authorTom Stellard <thomas.stellard@amd.com>
Thu, 2 Jun 2016 21:01:44 +0000 (21:01 +0000)
committerTom Stellard <thomas.stellard@amd.com>
Thu, 2 Jun 2016 21:01:44 +0000 (21:01 +0000)
------------------------------------------------------------------------
r259546 | Matthew.Arsenault | 2016-02-02 11:18:53 -0800 (Tue, 02 Feb 2016) | 5 lines

AMDGPU: Whitelist handled intrinsics

We shouldn't crash on unhandled intrinsics.
Also simplify failure handling in loop.

------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_38@271592 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp
test/CodeGen/AMDGPU/promote-alloca-unhandled-intrinsic.ll [new file with mode: 0644]

index 852934231a48a3bc138725920ff7389e0013b99d..257f92abfeb7f9a2859a7b3416e82db92656a84e 100644 (file)
@@ -256,15 +256,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);
@@ -286,10 +308,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) {
@@ -392,6 +415,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/test/CodeGen/AMDGPU/promote-alloca-unhandled-intrinsic.ll b/test/CodeGen/AMDGPU/promote-alloca-unhandled-intrinsic.ll
new file mode 100644 (file)
index 0000000..7543f2f
--- /dev/null
@@ -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 }