R600: Don't crash on unhandled instruction in promote alloca
[oota-llvm.git] / lib / Target / R600 / AMDGPUPromoteAlloca.cpp
index 053ea8a90b77ab6a793e7cbbffc1bb7f69a61f38..218750d445e621e9986203c745327e5b7de247ce 100644 (file)
@@ -129,6 +129,22 @@ static Value* GEPToVectorIndex(GetElementPtrInst *GEP) {
   return GEP->getOperand(2);
 }
 
+// Not an instruction handled below to turn into a vector.
+//
+// TODO: Check isTriviallyVectorizable for calls and handle other
+// instructions.
+static bool canVectorizeInst(Instruction *Inst) {
+  switch (Inst->getOpcode()) {
+  case Instruction::Load:
+  case Instruction::Store:
+  case Instruction::BitCast:
+  case Instruction::AddrSpaceCast:
+    return true;
+  default:
+    return false;
+  }
+}
+
 static bool tryPromoteAllocaToVector(AllocaInst *Alloca) {
   Type *AllocaTy = Alloca->getAllocatedType();
 
@@ -149,6 +165,9 @@ static bool tryPromoteAllocaToVector(AllocaInst *Alloca) {
   for (User *AllocaUser : Alloca->users()) {
     GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(AllocaUser);
     if (!GEP) {
+      if (!canVectorizeInst(cast<Instruction>(AllocaUser)))
+        return false;
+
       WorkList.push_back(AllocaUser);
       continue;
     }
@@ -164,6 +183,9 @@ static bool tryPromoteAllocaToVector(AllocaInst *Alloca) {
 
     GEPVectorIdx[GEP] = Index;
     for (User *GEPUser : AllocaUser->users()) {
+      if (!canVectorizeInst(cast<Instruction>(GEPUser)))
+        return false;
+
       WorkList.push_back(GEPUser);
     }
   }
@@ -201,12 +223,12 @@ static bool tryPromoteAllocaToVector(AllocaInst *Alloca) {
       break;
     }
     case Instruction::BitCast:
+    case Instruction::AddrSpaceCast:
       break;
 
     default:
       Inst->dump();
-      llvm_unreachable("Do not know how to replace this instruction "
-                       "with vector op");
+      llvm_unreachable("Inconsistency in instructions promotable to vector");
     }
   }
   return true;