@@ -550,7 +550,7 @@ struct TraitsLane : public Base {
550550 // according to Base.
551551 // Corresponds to a conditional swap, which is one "node" of a sorting
552552 // network. Min/Max are cheaper than compare + blend at least for integers.
553- template <bool kMirror = false , class D >
553+ template <PairLayout kLayout = PairLayout:: kIndependent , class D >
554554 HWY_INLINE void Sort2 (D d, Vec<D>& a, Vec<D>& b) const {
555555 const Base* base = static_cast <const Base*>(this );
556556
@@ -559,7 +559,8 @@ struct TraitsLane : public Base {
559559 // and two blends, except for mirrored floats: selecting opposite inputs
560560 // on a tie there would duplicate one zero after the lanes are merged.
561561#if HWY_AVX3 < HWY_TARGET && HWY_TARGET <= HWY_SSSE3
562- if (sizeof (TFromD<D>) == 8 && !(kMirror && IsFloat<TFromD<D>>())) {
562+ if (sizeof (TFromD<D>) == 8 &&
563+ !(kLayout == PairLayout::kMirrored && IsFloat<TFromD<D>>())) {
563564 const Mask<D> cmp = base->Compare (d, a, b);
564565 a = IfThenElse (cmp, a, b);
565566 b = IfThenElse (cmp, b, a_copy);
@@ -570,7 +571,7 @@ struct TraitsLane : public Base {
570571 // Some floating-point Min/Max instructions both choose the second operand
571572 // for equal zeros. Keep one of each input. Mirrored lanes already compare
572573 // the same pair in opposite orders before selecting one result per lane.
573- if constexpr (! kMirror && IsFloat<TFromD<D>>()) {
574+ if constexpr (kLayout == PairLayout:: kIndependent && IsFloat<TFromD<D>>()) {
574575 b = base->Last (d, b, a_copy);
575576 } else {
576577 b = base->Last (d, a_copy, b);
@@ -588,7 +589,7 @@ struct TraitsLane : public Base {
588589 const Vec<D> cmp = VecFromMask (d, base->Compare (d, v, swapped));
589590 return IfVecThenElse (DupOdd (cmp), swapped, v);
590591#else
591- Sort2<true >(d, v, swapped);
592+ Sort2<PairLayout:: kMirrored >(d, v, swapped);
592593 return base->OddEvenKeys (swapped, v);
593594#endif
594595 }
@@ -598,7 +599,7 @@ struct TraitsLane : public Base {
598599 HWY_INLINE Vec<D> SortPairsDistance1 (D d, Vec<D> v) const {
599600 const Base* base = static_cast <const Base*>(this );
600601 Vec<D> swapped = base->ReverseKeys2 (d, v);
601- Sort2<true >(d, v, swapped);
602+ Sort2<PairLayout:: kMirrored >(d, v, swapped);
602603 return base->OddEvenKeys (swapped, v);
603604 }
604605
@@ -607,7 +608,7 @@ struct TraitsLane : public Base {
607608 HWY_INLINE Vec<D> SortPairsReverse4 (D d, Vec<D> v) const {
608609 const Base* base = static_cast <const Base*>(this );
609610 Vec<D> swapped = base->ReverseKeys4 (d, v);
610- Sort2<true >(d, v, swapped);
611+ Sort2<PairLayout:: kMirrored >(d, v, swapped);
611612 return base->OddEvenPairs (d, swapped, v);
612613 }
613614
@@ -618,7 +619,7 @@ struct TraitsLane : public Base {
618619 Vec<D> swapped = base->SwapAdjacentQuads (d, v);
619620 // Only used in Merge16, so this will not be used on AVX2 (which only has 4
620621 // u64 lanes), so skip the above optimization for 64-bit AVX2.
621- Sort2<true >(d, v, swapped);
622+ Sort2<PairLayout:: kMirrored >(d, v, swapped);
622623 return base->OddEvenQuads (d, swapped, v);
623624 }
624625};
0 commit comments