From 89b8df04fb1a2f10ab011e0b7d813098e095fbb9 Mon Sep 17 00:00:00 2001 From: Goran Jakovljevic Date: Fri, 13 Oct 2017 08:33:17 +0200 Subject: Fix min/max SIMD reduction Use HVecReplicateScalar instead of HVecSetScalars when creating an initial vector for min/max. This way we are preventing that zeroes from the initial vector are taken into account for min/max calculations. Otherwise, min(MAX_INT, x[0],.., x[n-1]) = 0 if each x[i] is positive which is incorrect. Added regression test cases in 661-checker-simd-reduc. Test: ./testrunner.py --target --optimizing in QEMU (arm64) Change-Id: I1779eefc7f2ab9971dec561b2e1fbf262652410e --- compiler/optimizing/loop_optimization.cc | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'compiler/optimizing/loop_optimization.cc') diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc index 645915e2f8..69c6b94c6b 100644 --- a/compiler/optimizing/loop_optimization.cc +++ b/compiler/optimizing/loop_optimization.cc @@ -1623,17 +1623,28 @@ void HLoopOptimization::GenerateVecReductionPhiInputs(HPhi* phi, HInstruction* r } // Prepare the new initialization. if (vector_mode_ == kVector) { - // Generate a [initial, 0, .., 0] vector. + // Generate a [initial, 0, .., 0] vector for add or + // a [initial, initial, .., initial] vector for min/max. HVecOperation* red_vector = new_red->AsVecOperation(); + HVecReduce::ReductionKind kind = GetReductionKind(red_vector); size_t vector_length = red_vector->GetVectorLength(); DataType::Type type = red_vector->GetPackedType(); - new_init = Insert(vector_preheader_, - new (global_allocator_) HVecSetScalars(global_allocator_, - &new_init, - type, - vector_length, - 1, - kNoDexPc)); + if (kind == HVecReduce::ReductionKind::kSum) { + new_init = Insert(vector_preheader_, + new (global_allocator_) HVecSetScalars(global_allocator_, + &new_init, + type, + vector_length, + 1, + kNoDexPc)); + } else { + new_init = Insert(vector_preheader_, + new (global_allocator_) HVecReplicateScalar(global_allocator_, + new_init, + type, + vector_length, + kNoDexPc)); + } } else { new_init = ReduceAndExtractIfNeeded(new_init); } -- cgit v1.2.3-59-g8ed1b