diff options
author | 2017-10-13 08:33:17 +0200 | |
---|---|---|
committer | 2017-10-13 08:35:24 +0200 | |
commit | 89b8df04fb1a2f10ab011e0b7d813098e095fbb9 (patch) | |
tree | 0b3f39060d69ab0d6409a57b29a632f9ed44b917 /compiler/optimizing/loop_optimization.cc | |
parent | e478ed98446bff1ede5084c755313ee84afc036f (diff) |
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
Diffstat (limited to 'compiler/optimizing/loop_optimization.cc')
-rw-r--r-- | compiler/optimizing/loop_optimization.cc | 27 |
1 files changed, 19 insertions, 8 deletions
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); } |