Loop vectorizer should not remove instructions that can throw

Instructions that are not used outside of the inner loop were
inadvertently being removed. Make sure this does not happen.

Original author: Georgia Kouveli <georgia.kouveli@linaro.org>
Committed by: David Horstmann <david.horstmann@linaro.org>

Test: 1961-checker-loop-vectorizer
Test: test-art-target

Change-Id: I3af9e861e75669457e5925dd1d655db784a55287
diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc
index 3e1c42c..9c4e9d2 100644
--- a/compiler/optimizing/loop_optimization.cc
+++ b/compiler/optimizing/loop_optimization.cc
@@ -1283,6 +1283,10 @@
   // (3) unit stride index,
   // (4) vectorizable right-hand-side value.
   uint64_t restrictions = kNone;
+  // Don't accept expressions that can throw.
+  if (instruction->CanThrow()) {
+    return false;
+  }
   if (instruction->IsArraySet()) {
     DataType::Type type = instruction->AsArraySet()->GetComponentType();
     HInstruction* base = instruction->InputAt(0);
@@ -1334,7 +1338,8 @@
   }
   // Otherwise accept only expressions with no effects outside the immediate loop-body.
   // Note that actual uses are inspected during right-hand-side tree traversal.
-  return !IsUsedOutsideLoop(node->loop_info, instruction) && !instruction->DoesAnyWrite();
+  return !IsUsedOutsideLoop(node->loop_info, instruction)
+         && !instruction->DoesAnyWrite();
 }
 
 bool HLoopOptimization::VectorizeUse(LoopNode* node,