Basic SIMD reduction support.

Rationale:
Enables vectorization of x += .... for very basic (simple, same-type)
constructs. Paves the way for more complex (narrower and/or mixed-type)
constructs, which will be handled by the next CL.

This is  a revert   of Icb5d6c805516db0a1d911c3ede9a246ccef89a22
and thus a revert^2 of I2454778dd0ef1da915c178c7274e1cf33e271d0f
and thus a revert^3 of I1c1c87b6323e01442e8fbd94869ddc9e760ea1fc
and thus a revert^4 of I7880c135aee3ed0a39da9ae5b468cbf80e613766

PS1-2 shows what needed to change

Test: test-art-host test-art-target

Bug: 64091002
Change-Id: I647889e0da0959ca405b70081b79c7d3c9bcb2e9
diff --git a/compiler/optimizing/nodes_vector_test.cc b/compiler/optimizing/nodes_vector_test.cc
index 0238ea4..5a56a2c 100644
--- a/compiler/optimizing/nodes_vector_test.cc
+++ b/compiler/optimizing/nodes_vector_test.cc
@@ -332,4 +332,32 @@
   EXPECT_FALSE(v1->Equals(v3));  // different vector lengths
 }
 
+TEST_F(NodesVectorTest, VectorKindMattersOnReduce) {
+  HVecOperation* v0 = new (&allocator_)
+      HVecReplicateScalar(&allocator_, parameter_, Primitive::kPrimInt, 4);
+
+  HVecReduce* v1 = new (&allocator_) HVecReduce(
+      &allocator_, v0, Primitive::kPrimInt, 4, HVecReduce::kSum);
+  HVecReduce* v2 = new (&allocator_) HVecReduce(
+      &allocator_, v0, Primitive::kPrimInt, 4, HVecReduce::kMin);
+  HVecReduce* v3 = new (&allocator_) HVecReduce(
+      &allocator_, v0, Primitive::kPrimInt, 4, HVecReduce::kMax);
+
+  EXPECT_FALSE(v0->CanBeMoved());
+  EXPECT_TRUE(v1->CanBeMoved());
+  EXPECT_TRUE(v2->CanBeMoved());
+  EXPECT_TRUE(v3->CanBeMoved());
+
+  EXPECT_EQ(HVecReduce::kSum, v1->GetKind());
+  EXPECT_EQ(HVecReduce::kMin, v2->GetKind());
+  EXPECT_EQ(HVecReduce::kMax, v3->GetKind());
+
+  EXPECT_TRUE(v1->Equals(v1));
+  EXPECT_TRUE(v2->Equals(v2));
+  EXPECT_TRUE(v3->Equals(v3));
+
+  EXPECT_FALSE(v1->Equals(v2));  // different kinds
+  EXPECT_FALSE(v1->Equals(v3));
+}
+
 }  // namespace art