ART: Fix vectorizer HalvingAdd idiom.

IsAddConst2 function tried to extract addition chains
for the halving add idiom: (A + B) >> 1. The problem
was that regular shift right (x >> 1) was accepted for the
idiom (with {A: x, B: 0}) and not processed as a shift - which
broke the assumptions on shifts right and operand signedness.
This CL fixes that.

Test: 646-checker-simd-hadd.
Test: test-art-target.

Change-Id: Icf71e1a8e8c54e68114d7d5d6c4aa8a47ea5234d
diff --git a/compiler/optimizing/load_store_analysis.cc b/compiler/optimizing/load_store_analysis.cc
index 7d7bb94..7a67fc5 100644
--- a/compiler/optimizing/load_store_analysis.cc
+++ b/compiler/optimizing/load_store_analysis.cc
@@ -30,10 +30,6 @@
   return std::max(l1, l2) <= std::min(h1, h2);
 }
 
-static bool IsAddOrSub(const HInstruction* instruction) {
-  return instruction->IsAdd() || instruction->IsSub();
-}
-
 static bool CanBinaryOpAndIndexAlias(const HBinaryOperation* idx1,
                                      const size_t vector_length1,
                                      const HInstruction* idx2,
diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc
index 770a011..b72fbb0 100644
--- a/compiler/optimizing/loop_optimization.cc
+++ b/compiler/optimizing/loop_optimization.cc
@@ -305,7 +305,8 @@
                         /*out*/ HInstruction** a,
                         /*out*/ HInstruction** b,
                         /*out*/ int64_t* c) {
-  if (IsAddConst(instruction, a, b, c) && *a != nullptr) {
+  // We want an actual add/sub and not the trivial case where {b: 0, c: 0}.
+  if (IsAddOrSub(instruction) && IsAddConst(instruction, a, b, c) && *a != nullptr) {
     if (*b == nullptr) {
       // Constant is usually already present, unless accumulated.
       *b = graph->GetConstant(instruction->GetType(), (*c));
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 7ed5bca..611e0e7 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -8121,6 +8121,10 @@
   return instruction;
 }
 
+inline bool IsAddOrSub(const HInstruction* instruction) {
+  return instruction->IsAdd() || instruction->IsSub();
+}
+
 void RemoveEnvironmentUses(HInstruction* instruction);
 bool HasEnvironmentUsedByOthers(HInstruction* instruction);
 void ResetEnvironmentInputRecords(HInstruction* instruction);