summaryrefslogtreecommitdiff
path: root/compiler/optimizing/loop_optimization.cc
diff options
context:
space:
mode:
author Goran Jakovljevic <Goran.Jakovljevic@imgtec.com> 2017-10-13 08:33:17 +0200
committer Goran Jakovljevic <Goran.Jakovljevic@imgtec.com> 2017-10-13 08:35:24 +0200
commit89b8df04fb1a2f10ab011e0b7d813098e095fbb9 (patch)
tree0b3f39060d69ab0d6409a57b29a632f9ed44b917 /compiler/optimizing/loop_optimization.cc
parente478ed98446bff1ede5084c755313ee84afc036f (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.cc27
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);
}