@@ -127,3 +127,120 @@ func TestAVX2PopcntDifferential(t *testing.T) {
127127 }
128128 }
129129}
130+
131+ func TestAVX2AndStoreSliceDispatch (t * testing.T ) {
132+ saved := useAVX2
133+ defer func () { useAVX2 = saved }()
134+
135+ r := rand .New (rand .NewSource (11 ))
136+ for _ , on := range []bool {false , true } {
137+ if on && ! saved {
138+ continue // CPU has no AVX2; only the fallback exists
139+ }
140+ useAVX2 = on
141+ for _ , n := range avx2TestLengths {
142+ s := randomUint64Slice (r , n )
143+ m := randomUint64Slice (r , n )
144+ expected := append ([]uint64 (nil ), s ... )
145+ andStoreSliceGo (expected , s , m )
146+
147+ dst := append ([]uint64 (nil ), s ... )
148+ andStoreSlice (dst , s , m )
149+ assert .Equalf (t , expected , dst , "separate destination avx2=%v len=%d" , on , n )
150+
151+ inPlaceLeft := append ([]uint64 (nil ), s ... )
152+ andStoreSlice (inPlaceLeft , inPlaceLeft , m )
153+ assert .Equalf (t , expected , inPlaceLeft , "left alias avx2=%v len=%d" , on , n )
154+
155+ inPlaceRight := append ([]uint64 (nil ), m ... )
156+ andStoreSlice (inPlaceRight , s , inPlaceRight )
157+ assert .Equalf (t , expected , inPlaceRight , "right alias avx2=%v len=%d" , on , n )
158+ }
159+ }
160+ }
161+
162+ func TestAVX2AndStoreSliceDifferential (t * testing.T ) {
163+ if ! useAVX2 {
164+ t .Skip ("AVX2 not available on this CPU" )
165+ }
166+ r := rand .New (rand .NewSource (13 ))
167+ for _ , n := range avx2TestLengths {
168+ for iter := 0 ; iter < 64 ; iter ++ {
169+ s := randomUint64Slice (r , n )
170+ m := randomUint64Slice (r , n )
171+ expected := append ([]uint64 (nil ), s ... )
172+ andStoreSliceGo (expected , s , m )
173+
174+ dst := append ([]uint64 (nil ), s ... )
175+ _andStoreSliceAVX2 (dst , s , m )
176+ assert .Equalf (t , expected , dst , "separate destination len=%d" , n )
177+
178+ inPlaceLeft := append ([]uint64 (nil ), s ... )
179+ _andStoreSliceAVX2 (inPlaceLeft , inPlaceLeft , m )
180+ assert .Equalf (t , expected , inPlaceLeft , "left alias len=%d" , n )
181+
182+ inPlaceRight := append ([]uint64 (nil ), m ... )
183+ _andStoreSliceAVX2 (inPlaceRight , s , inPlaceRight )
184+ assert .Equalf (t , expected , inPlaceRight , "right alias len=%d" , n )
185+ }
186+ }
187+ }
188+
189+ func TestAVX2BitmapAndStoreDispatch (t * testing.T ) {
190+ saved := useAVX2
191+ defer func () { useAVX2 = saved }()
192+
193+ newFull := func () * bitmapContainer {
194+ bc := newBitmapContainer ()
195+ for i := range bc .bitmap {
196+ bc .bitmap [i ] = ^ uint64 (0 )
197+ }
198+ bc .cardinality = maxCapacity
199+ return bc
200+ }
201+
202+ right := newBitmapContainer ()
203+ for i := range right .bitmap {
204+ right .bitmap [i ] = 0xaaaaaaaaaaaaaaaa
205+ }
206+ right .cardinality = maxCapacity / 2
207+
208+ small := newBitmapContainer ()
209+ small .bitmap [0 ] = 1
210+ small .cardinality = 1
211+
212+ for _ , on := range []bool {false , true } {
213+ if on && ! saved {
214+ continue // CPU has no AVX2; only the fallback exists
215+ }
216+ useAVX2 = on
217+
218+ answer , ok := newFull ().andBitmap (right ).(* bitmapContainer )
219+ if ! ok {
220+ t .Fatalf ("expected bitmap result with avx2=%v" , on )
221+ }
222+ assert .Equalf (t , right .bitmap , answer .bitmap , "bitmap result avx2=%v" , on )
223+ assert .Equalf (t , right .cardinality , answer .cardinality , "bitmap cardinality avx2=%v" , on )
224+
225+ inPlace := newFull ()
226+ answer , ok = inPlace .iandBitmap (right ).(* bitmapContainer )
227+ if ! ok {
228+ t .Fatalf ("expected in-place bitmap result with avx2=%v" , on )
229+ }
230+ assert .Samef (t , inPlace , answer , "in-place bitmap result avx2=%v" , on )
231+ assert .Equalf (t , right .bitmap , inPlace .bitmap , "in-place bitmap contents avx2=%v" , on )
232+
233+ arrayResult , ok := newFull ().andBitmap (small ).(* arrayContainer )
234+ if ! ok {
235+ t .Fatalf ("expected array result with avx2=%v" , on )
236+ }
237+ assert .Equalf (t , []uint16 {0 }, arrayResult .content , "array result avx2=%v" , on )
238+
239+ inPlace = newFull ()
240+ arrayResult , ok = inPlace .iandBitmap (small ).(* arrayContainer )
241+ if ! ok {
242+ t .Fatalf ("expected in-place array result with avx2=%v" , on )
243+ }
244+ assert .Equalf (t , []uint16 {0 }, arrayResult .content , "in-place array result avx2=%v" , on )
245+ }
246+ }
0 commit comments