]> gitweb.factorcode.org Git - factor.git/blob - basis/math/vectors/simd/simd-tests.factor
Merge branch 'master' of git://factorcode.org/git/factor
[factor.git] / basis / math / vectors / simd / simd-tests.factor
1 USING: accessors arrays classes compiler compiler.tree.debugger
2 effects fry io kernel kernel.private math math.functions
3 math.private math.vectors math.vectors.simd
4 math.vectors.simd.private prettyprint random sequences system
5 tools.test vocabs assocs compiler.cfg.debugger words
6 locals combinators cpu.architecture namespaces byte-arrays alien
7 specialized-arrays classes.struct eval classes.algebra sets
8 quotations math.constants compiler.units splitting ;
9 FROM: math.vectors.simd.intrinsics => alien-vector set-alien-vector ;
10 QUALIFIED-WITH: alien.c-types c
11 SPECIALIZED-ARRAY: c:float
12 IN: math.vectors.simd.tests
13
14 ! Test type propagation
15 [ V{ float } ] [ [ { float-4 } declare norm-sq ] final-classes ] unit-test
16
17 [ V{ float } ] [ [ { float-4 } declare norm ] final-classes ] unit-test
18
19 [ V{ float-4 } ] [ [ { float-4 } declare normalize ] final-classes ] unit-test
20
21 [ V{ float-4 } ] [ [ { float-4 float-4 } declare v+ ] final-classes ] unit-test
22
23 [ V{ float } ] [ [ { float-4 } declare second ] final-classes ] unit-test
24
25 [ V{ int-4 } ] [ [ { int-4 int-4 } declare v+ ] final-classes ] unit-test
26
27 [ t ] [ [ { int-4 } declare second ] final-classes first integer class<= ] unit-test
28
29 [ V{ longlong-2 } ] [ [ { longlong-2 longlong-2 } declare v+ ] final-classes ] unit-test
30
31 [ V{ integer } ] [ [ { longlong-2 } declare second ] final-classes ] unit-test
32
33 ! Test puns; only on x86
34 cpu x86? [
35     [ double-2{ 4 1024 } ] [
36         float-4{ 0 1 0 2 }
37         [ { float-4 } declare dup v+ underlying>> double-2 boa dup v+ ] compile-call
38     ] unit-test
39 ] when
40
41 ! Fuzz testing
42 CONSTANT: simd-classes
43     {
44         char-16
45         uchar-16
46         short-8
47         ushort-8
48         int-4
49         uint-4
50         longlong-2
51         ulonglong-2
52         float-4
53         double-2
54     }
55
56 SYMBOLS: -> +vector+ +any-vector+ +scalar+ +boolean+ +nonnegative+ +literal+ ;
57
58 CONSTANT: vector-words
59     H{
60         { [v-] { +vector+ +vector+ -> +vector+ } }
61         { distance { +vector+ +vector+ -> +nonnegative+ } }
62         { n*v { +scalar+ +vector+ -> +vector+ } }
63         { n+v { +scalar+ +vector+ -> +vector+ } }
64         { n-v { +scalar+ +vector+ -> +vector+ } }
65         { n/v { +scalar+ +vector+ -> +vector+ } }
66         { norm { +vector+ -> +nonnegative+ } }
67         { norm-sq { +vector+ -> +nonnegative+ } }
68         { normalize { +vector+ -> +vector+ } }
69         { v* { +vector+ +vector+ -> +vector+ } }
70         { vs* { +vector+ +vector+ -> +vector+ } }
71         { v*n { +vector+ +scalar+ -> +vector+ } }
72         { v*high { +vector+ +vector+ -> +vector+ } }
73         { v*hs+ { +vector+ +vector+ -> +vector+ } }
74         { v+ { +vector+ +vector+ -> +vector+ } }
75         { vs+ { +vector+ +vector+ -> +vector+ } }
76         { v+- { +vector+ +vector+ -> +vector+ } }
77         { v+n { +vector+ +scalar+ -> +vector+ } }
78         { v- { +vector+ +vector+ -> +vector+ } }
79         { vneg { +vector+ -> +vector+ } }
80         { vs- { +vector+ +vector+ -> +vector+ } }
81         { v-n { +vector+ +scalar+ -> +vector+ } }
82         { v. { +vector+ +vector+ -> +scalar+ } }
83         { vsad { +vector+ +vector+ -> +scalar+ } }
84         { v/ { +vector+ +vector+ -> +vector+ } }
85         { v/n { +vector+ +scalar+ -> +vector+ } }
86         { vceiling { +vector+ -> +vector+ } }
87         { vfloor { +vector+ -> +vector+ } }
88         { vmax { +vector+ +vector+ -> +vector+ } }
89         { vmin { +vector+ +vector+ -> +vector+ } }
90         { vavg { +vector+ +vector+ -> +vector+ } }
91         { vneg { +vector+ -> +vector+ } }
92         { vtruncate { +vector+ -> +vector+ } }
93         { sum { +vector+ -> +scalar+ } }
94         { vabs { +vector+ -> +vector+ } }
95         { vsqrt { +vector+ -> +vector+ } }
96         { vbitand { +vector+ +vector+ -> +vector+ } }
97         { vbitandn { +vector+ +vector+ -> +vector+ } }
98         { vbitor { +vector+ +vector+ -> +vector+ } }
99         { vbitxor { +vector+ +vector+ -> +vector+ } }
100         { vbitnot { +vector+ -> +vector+ } }
101         { vand { +vector+ +vector+ -> +vector+ } }
102         { vandn { +vector+ +vector+ -> +vector+ } }
103         { vor { +vector+ +vector+ -> +vector+ } }
104         { vxor { +vector+ +vector+ -> +vector+ } }
105         { vnot { +vector+ -> +vector+ } }
106         { vlshift { +vector+ +scalar+ -> +vector+ } }
107         { vrshift { +vector+ +scalar+ -> +vector+ } }
108         { (vmerge-head) { +vector+ +vector+ -> +vector+ } }
109         { (vmerge-tail) { +vector+ +vector+ -> +vector+ } }
110         { v<= { +vector+ +vector+ -> +vector+ } }
111         { v< { +vector+ +vector+ -> +vector+ } }
112         { v= { +vector+ +vector+ -> +vector+ } }
113         { v> { +vector+ +vector+ -> +vector+ } }
114         { v>= { +vector+ +vector+ -> +vector+ } }
115         { vunordered? { +vector+ +vector+ -> +vector+ } }
116     }
117
118 : vector-word-inputs ( schema -- seq ) { -> } split first ;
119
120 : with-ctors ( -- seq )
121     simd-classes [ [ name>> "-with" append ] [ vocabulary>> ] bi lookup ] map ;
122
123 : boa-ctors ( -- seq )
124     simd-classes [ [ name>> "-boa" append ] [ vocabulary>> ] bi lookup ] map ;
125
126 : check-optimizer ( seq quot eq-quot -- failures )
127     dup '[
128         @
129         [ dup [ class ] { } map-as ] dip '[ _ declare @ ]
130         {
131             [ "print-mr" get [ nip test-mr mr. ] [ 2drop ] if ]
132             [ "print-checks" get [ [ . ] bi@ ] [ 2drop ] if ]
133             [ [ [ call ] dip call ] call( quot quot -- result ) ]
134             [ [ [ call ] dip compile-call ] call( quot quot -- result ) ]
135             [ [ t "always-inline-simd-intrinsics" [ [ call ] dip compile-call ] with-variable ] call( quot quot -- result ) ]
136         } 2cleave
137         [ drop @ ] [ nip @ ] 3bi and not
138     ] filter ; inline
139
140 "== Checking -new constructors" print
141
142 [ { } ] [
143     simd-classes [ [ [ ] ] dip '[ _ new ] ] [ = ] check-optimizer
144 ] unit-test
145
146 [ { } ] [
147     simd-classes [ '[ _ new ] compile-call [ zero? ] all? not ] filter
148 ] unit-test
149
150 "== Checking -with constructors" print
151
152 [ { } ] [
153     with-ctors [
154         [ 1000 random '[ _ ] ] dip '[ _ execute ]
155     ] [ = ] check-optimizer
156 ] unit-test
157
158 [ HEX: ffffffff ] [ HEX: ffffffff uint-4-with first ] unit-test
159
160 [ HEX: ffffffff ] [ HEX: ffffffff [ uint-4-with ] compile-call first ] unit-test
161
162 [ HEX: ffffffff ] [ [ HEX: ffffffff uint-4-with ] compile-call first ] unit-test
163
164 "== Checking -boa constructors" print
165
166 [ { } ] [
167     boa-ctors [
168         [ stack-effect in>> length [ 1000 random ] [ ] replicate-as ] keep
169         '[ _ execute ]
170     ] [ = ] check-optimizer
171 ] unit-test
172
173 [ HEX: ffffffff ] [ HEX: ffffffff 2 3 4 [ uint-4-boa ] compile-call first ] unit-test
174
175 "== Checking vector operations" print
176
177 : random-int-vector ( class -- vec )
178     new [ drop 1,000 random ] map ;
179 : random-float-vector ( class -- vec )
180     new [
181         drop
182         1000 random
183         10 swap <array> 0/0. suffix random
184     ] map ;
185
186 : random-vector ( class elt-class -- vec )
187     float =
188     [ random-float-vector ]
189     [ random-int-vector ] if ;
190
191 :: check-vector-op ( word inputs class elt-class -- inputs quot )
192     inputs [
193         {
194             { +vector+ [ class elt-class random-vector ] }
195             { +scalar+ [ 1000 random elt-class float = [ >float ] when ] }
196         } case
197     ] [ ] map-as
198     word '[ _ execute ] ;
199
200 : remove-float-words ( alist -- alist' )
201     { vsqrt n/v v/n v/ normalize } unique assoc-diff ;
202
203 : remove-integer-words ( alist -- alist' )
204     { vlshift vrshift v*high v*hs+ } unique assoc-diff ;
205
206 : boolean-ops ( -- words )
207     { vand vandn vor vxor vnot } ;
208
209 : remove-boolean-words ( alist -- alist' )
210     boolean-ops unique assoc-diff ;
211
212 : ops-to-check ( elt-class -- alist )
213     [ vector-words >alist ] dip
214     float = [ remove-integer-words ] [ remove-float-words ] if
215     remove-boolean-words ;
216
217 : check-vector-ops ( class elt-class compare-quot -- )
218     [
219         [ nip ops-to-check ] 2keep
220         '[ first2 vector-word-inputs _ _ check-vector-op ]
221     ] dip check-optimizer ; inline
222
223 : (approx=) ( x y -- ? )
224     {
225         { [ 2dup [ fp-nan? ] both? ] [ 2drop t ] }
226         { [ 2dup [ fp-nan? ] either? ] [ 2drop f ] }
227         { [ 2dup [ fp-infinity? ] either? ] [ fp-bitwise= ] }
228         { [ 2dup [ float? ] both? ] [ -1.e8 ~ ] }
229     } cond ;
230
231 : approx= ( x y -- ? )
232     2dup [ sequence? ] both?
233     [ [ (approx=) ] 2all? ] [ (approx=) ] if ;
234
235 : exact= ( x y -- ? )
236     {
237         { [ 2dup [ float? ] both? ] [ fp-bitwise= ] }
238         { [ 2dup [ sequence? ] both? ] [ [ fp-bitwise= ] 2all? ] }
239     } cond ;
240
241 : simd-classes&reps ( -- alist )
242     simd-classes [
243         {
244             { [ dup name>> "float" head? ] [ float [ approx= ] ] }
245             { [ dup name>> "double" head? ] [ float [ exact= ] ] }
246             [ fixnum [ = ] ]
247         } cond 3array
248     ] map ;
249
250 simd-classes&reps [
251     [ [ { } ] ] dip first3 '[ _ _ _ check-vector-ops ] unit-test
252 ] each
253
254 "== Checking boolean operations" print
255
256 : random-boolean-vector ( class -- vec )
257     new [ drop 2 random zero? ] map ;
258
259 :: check-boolean-op ( word inputs class elt-class -- inputs quot )
260     inputs [
261         {
262             { +vector+ [ class random-boolean-vector ] }
263             { +scalar+ [ 1000 random elt-class float = [ >float ] when ] }
264         } case
265     ] [ ] map-as
266     word '[ _ execute ] ;
267
268 : check-boolean-ops ( class elt-class compare-quot -- seq )
269     [
270         [ boolean-ops [ dup vector-words at ] { } map>assoc ] 2dip
271         '[ first2 vector-word-inputs _ _ check-boolean-op ]
272     ] dip check-optimizer ; inline
273
274 simd-classes&reps [
275     [ [ { } ] ] dip first3 '[ _ _ _ check-boolean-ops ] unit-test
276 ] each
277
278 "== Checking vector blend" print
279
280 [ char-16{ 0 1 22 33 4 5 6 77 8 99 110 121 12 143 14 15 } ]
281 [
282     char-16{ t  t  f  f  t  t  t  f  t  f   f   f   t   f   t   t }
283     char-16{ 0  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15 }
284     char-16{ 0 11 22 33 44 55 66 77 88 99 110 121 132 143 154 165 } v?
285 ] unit-test
286
287 [ char-16{ 0 1 22 33 4 5 6 77 8 99 110 121 12 143 14 15 } ]
288 [
289     char-16{ t  t  f  f  t  t  t  f  t  f   f   f   t   f   t   t }
290     char-16{ 0  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15 }
291     char-16{ 0 11 22 33 44 55 66 77 88 99 110 121 132 143 154 165 }
292     [ { char-16 char-16 char-16 } declare v? ] compile-call
293 ] unit-test
294
295 [ int-4{ 1 22 33 4 } ]
296 [ int-4{ t f f t } int-4{ 1 2 3 4 } int-4{ 11 22 33 44 } v? ] unit-test
297
298 [ int-4{ 1 22 33 4 } ]
299 [
300     int-4{ t f f t } int-4{ 1 2 3 4 } int-4{ 11 22 33 44 }
301     [ { int-4 int-4 int-4 } declare v? ] compile-call
302 ] unit-test
303
304 [ float-4{ 1.0 22.0 33.0 4.0 } ]
305 [ float-4{ t f f t } float-4{ 1.0 2.0 3.0 4.0 } float-4{ 11.0 22.0 33.0 44.0 } v? ] unit-test
306
307 [ float-4{ 1.0 22.0 33.0 4.0 } ]
308 [
309     float-4{ t f f t } float-4{ 1.0 2.0 3.0 4.0 } float-4{ 11.0 22.0 33.0 44.0 }
310     [ { float-4 float-4 float-4 } declare v? ] compile-call
311 ] unit-test
312
313 "== Checking shifts and permutations" print
314
315 [ char-16{ 0 1 2 4 8 1 2 4 8 1 2 4 8 1 2 4 } ]
316 [ char-16{ 1 2 4 8 1 2 4 8 1 2 4 8 1 2 4 8 } 1 hlshift ] unit-test
317
318 [ char-16{ 0 1 2 4 8 1 2 4 8 1 2 4 8 1 2 4 } ]
319 [ char-16{ 1 2 4 8 1 2 4 8 1 2 4 8 1 2 4 8 } [ { char-16 } declare 1 hlshift ] compile-call ] unit-test
320
321 [ char-16{ 0 1 2 4 8 1 2 4 8 1 2 4 8 1 2 4 } ]
322 [ char-16{ 1 2 4 8 1 2 4 8 1 2 4 8 1 2 4 8 } 1 [ { char-16 fixnum } declare hlshift ] compile-call ] unit-test
323
324 [ char-16{ 2 4 8 1 2 4 8 1 2 4 8 1 2 4 8 0 } ]
325 [ char-16{ 1 2 4 8 1 2 4 8 1 2 4 8 1 2 4 8 } 1 hrshift ] unit-test
326
327 [ char-16{ 2 4 8 1 2 4 8 1 2 4 8 1 2 4 8 0 } ]
328 [ char-16{ 1 2 4 8 1 2 4 8 1 2 4 8 1 2 4 8 } [ { char-16 } declare 1 hrshift ] compile-call ] unit-test
329
330 [ char-16{ 2 4 8 1 2 4 8 1 2 4 8 1 2 4 8 0 } ]
331 [ char-16{ 1 2 4 8 1 2 4 8 1 2 4 8 1 2 4 8 } 1 [ { char-16 fixnum } declare hrshift ] compile-call ] unit-test
332
333 ! Invalid inputs should not cause the compiler to throw errors
334 [ ] [
335     [ [ { int-4 } declare t hrshift ] (( a -- b )) define-temp drop ] with-compilation-unit
336 ] unit-test
337
338 [ ] [
339     [ [ { int-4 } declare { 3 2 1 } vshuffle ] (( a -- b )) define-temp drop ] with-compilation-unit
340 ] unit-test
341
342 ! Shuffles
343 : shuffles-for ( n -- shuffles )
344     {
345         { 2 [
346             {
347                 { 0 1 }
348                 { 1 1 }
349                 { 1 0 }
350                 { 0 0 }
351             }
352         ] }
353         { 4 [
354             {
355                 { 1 2 3 0 }
356                 { 0 1 2 3 }
357                 { 1 1 2 2 }
358                 { 0 0 1 1 }
359                 { 2 2 3 3 }
360                 { 0 1 0 1 }
361                 { 2 3 2 3 }
362                 { 0 0 2 2 }
363                 { 1 1 3 3 }
364                 { 0 1 0 1 }
365                 { 2 2 3 3 }
366             }
367         ] }
368         { 8 [
369             4 shuffles-for
370             4 shuffles-for
371             [ [ 4 + ] map ] map
372             [ append ] 2map
373         ] }
374         [ dup '[ _ random ] replicate 1array ]
375     } case ;
376
377 simd-classes [
378     [ [ { } ] ] dip
379     [ new length shuffles-for ] keep
380     '[
381         _ [ [ _ new [ length iota ] keep like 1quotation ] dip '[ _ vshuffle ] ]
382         [ = ] check-optimizer
383     ] unit-test
384 ] each
385
386 "== Checking variable shuffles" print
387
388 : random-shift-vector ( class -- vec )
389     new [ drop 16 random ] map ;
390
391 :: test-shift-vector ( class -- ? )
392     [
393         class random-int-vector :> src
394         char-16 random-shift-vector :> perm
395         { class char-16 } :> decl
396     
397         src perm vshuffle
398         src perm [ decl declare vshuffle ] compile-call
399         =
400     ] call( -- ? ) ;
401
402 { char-16 uchar-16 short-8 ushort-8 int-4 uint-4 longlong-2 ulonglong-2 }
403 [ 10 swap '[ [ t ] [ _ test-shift-vector ] unit-test ] times ] each
404
405 "== Checking vector tests" print
406
407 :: test-vector-tests-bool ( vector declaration -- none? any? all? )
408     [
409         vector
410         [ [ declaration declare vnone? ] compile-call ]
411         [ [ declaration declare vany?  ] compile-call ]
412         [ [ declaration declare vall?  ] compile-call ] tri
413     ] call( -- none? any? all? ) ;
414
415 : yes ( -- x ) t ;
416 : no ( -- x ) f ;
417
418 :: test-vector-tests-branch ( vector declaration -- none? any? all? )
419     [
420         vector
421         [ [ declaration declare vnone? [ yes ] [ no ] if ] compile-call ]
422         [ [ declaration declare vany?  [ yes ] [ no ] if ] compile-call ]
423         [ [ declaration declare vall?  [ yes ] [ no ] if ] compile-call ] tri
424     ] call( -- none? any? all? ) ;
425
426 TUPLE: inconsistent-vector-test bool branch ;
427
428 : ?inconsistent ( bool branch -- ?/inconsistent )
429     2dup = [ drop ] [ inconsistent-vector-test boa ] if ;
430
431 :: test-vector-tests ( vector decl -- none? any? all? )
432     [
433         vector decl test-vector-tests-bool :> ( bool-none bool-any bool-all )
434         vector decl test-vector-tests-branch :> ( branch-none branch-any branch-all )
435         
436         bool-none branch-none ?inconsistent
437         bool-any  branch-any  ?inconsistent
438         bool-all  branch-all  ?inconsistent
439     ] call( -- none? any? all? ) ;
440
441 [ f t t ]
442 [ float-4{ t t t t } { float-4 } test-vector-tests ] unit-test
443 [ f t f ]
444 [ float-4{ f t t t } { float-4 } test-vector-tests ] unit-test
445 [ t f f ]
446 [ float-4{ f f f f } { float-4 } test-vector-tests ] unit-test
447
448 [ f t t ]
449 [ double-2{ t t } { double-2 } test-vector-tests ] unit-test
450 [ f t f ]
451 [ double-2{ f t } { double-2 } test-vector-tests ] unit-test
452 [ t f f ]
453 [ double-2{ f f } { double-2 } test-vector-tests ] unit-test
454
455 [ f t t ]
456 [ int-4{ t t t t } { int-4 } test-vector-tests ] unit-test
457 [ f t f ]
458 [ int-4{ f t t t } { int-4 } test-vector-tests ] unit-test
459 [ t f f ]
460 [ int-4{ f f f f } { int-4 } test-vector-tests ] unit-test
461
462 "== Checking element access" print
463
464 ! Test element access -- it should box bignums for int-4 on x86
465 : test-accesses ( seq -- failures )
466     [ length >array ] keep
467     '[ [ _ 1quotation ] dip '[ _ swap nth ] ] [ = ] check-optimizer ; inline
468
469 [ { } ] [ float-4{ 1.0 2.0 3.0 4.0 } test-accesses ] unit-test
470 [ { } ] [ int-4{ HEX: 7fffffff 3 4 -8 } test-accesses ] unit-test
471 [ { } ] [ uint-4{ HEX: ffffffff 2 3 4 } test-accesses ] unit-test
472
473 [ HEX: 7fffffff ] [ int-4{ HEX: 7fffffff 3 4 -8 } first ] unit-test
474 [ -8 ] [ int-4{ HEX: 7fffffff 3 4 -8 } last ] unit-test
475 [ HEX: ffffffff ] [ uint-4{ HEX: ffffffff 2 3 4 } first ] unit-test
476
477 [ { } ] [ double-2{ 1.0 2.0 } test-accesses ] unit-test
478 [ { } ] [ longlong-2{ 1 2 } test-accesses ] unit-test
479 [ { } ] [ ulonglong-2{ 1 2 } test-accesses ] unit-test
480
481 "== Checking broadcast" print
482 : test-broadcast ( seq -- failures )
483     [ length >array ] keep
484     '[ [ _ 1quotation ] dip '[ _ vbroadcast ] ] [ = ] check-optimizer ;
485
486 [ { } ] [ float-4{ 1.0 2.0 3.0 4.0 } test-broadcast ] unit-test
487 [ { } ] [ int-4{ HEX: 7fffffff 3 4 -8 } test-broadcast ] unit-test
488 [ { } ] [ uint-4{ HEX: ffffffff 2 3 4 } test-broadcast ] unit-test
489
490 [ { } ] [ double-2{ 1.0 2.0 } test-broadcast ] unit-test
491 [ { } ] [ longlong-2{ 1 2 } test-broadcast ] unit-test
492 [ { } ] [ ulonglong-2{ 1 2 } test-broadcast ] unit-test
493
494 ! Make sure we use the fallback in the correct situations
495 [ int-4{ 3 3 3 3 } ] [ int-4{ 12 34 3 17 } 2 [ { int-4 fixnum } declare vbroadcast ] compile-call ] unit-test
496
497 "== Checking alien operations" print
498
499 [ float-4{ 1 2 3 4 } ] [
500     [
501         float-4{ 1 2 3 4 }
502         underlying>> 0 float-4-rep alien-vector
503     ] compile-call float-4 boa
504 ] unit-test
505
506 [ B{ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 } ] [
507     16 [ 1 ] B{ } replicate-as 16 <byte-array>
508     [
509         0 [
510             { byte-array c-ptr fixnum } declare
511             float-4-rep set-alien-vector
512         ] compile-call
513     ] keep
514 ] unit-test
515
516 [ float-array{ 1 2 3 4 } ] [
517     [
518         float-array{ 1 2 3 4 } underlying>>
519         float-array{ 4 3 2 1 } clone
520         [ underlying>> 0 float-4-rep set-alien-vector ] keep
521     ] compile-call
522 ] unit-test
523
524 STRUCT: simd-struct
525 { x float-4 }
526 { y longlong-2 }
527 { z double-2 }
528 { w int-4 } ;
529
530 [ t ] [ [ simd-struct <struct> ] compile-call >c-ptr [ 0 = ] all? ] unit-test
531
532 [
533     float-4{ 1 2 3 4 }
534     longlong-2{ 2 1 }
535     double-2{ 4 3 }
536     int-4{ 1 2 3 4 }
537 ] [
538     simd-struct <struct>
539     float-4{ 1 2 3 4 } >>x
540     longlong-2{ 2 1 } >>y
541     double-2{ 4 3 } >>z
542     int-4{ 1 2 3 4 } >>w
543     { [ x>> ] [ y>> ] [ z>> ] [ w>> ] } cleave
544 ] unit-test
545
546 [
547     float-4{ 1 2 3 4 }
548     longlong-2{ 2 1 }
549     double-2{ 4 3 }
550     int-4{ 1 2 3 4 }
551 ] [
552     [
553         simd-struct <struct>
554         float-4{ 1 2 3 4 } >>x
555         longlong-2{ 2 1 } >>y
556         double-2{ 4 3 } >>z
557         int-4{ 1 2 3 4 } >>w
558         { [ x>> ] [ y>> ] [ z>> ] [ w>> ] } cleave
559     ] compile-call
560 ] unit-test
561
562 "== Misc tests" print
563
564 [ ] [ char-16 new 1array stack. ] unit-test
565
566 ! CSSA bug
567 [ 4000000 ] [
568     int-4{ 1000 1000 1000 1000 }
569     [ { int-4 } declare dup [ * ] [ + ] 2map-reduce ] compile-call
570 ] unit-test
571
572 ! Coalescing was too aggressive
573 :: broken ( axis theta -- a b c )
574    axis { float-4 } declare drop
575    theta { float } declare drop
576
577    theta cos float-4-with :> cc
578    theta sin float-4-with :> ss
579    
580    axis cc v+ :> diagonal
581
582    diagonal cc ss ; inline
583
584 [ t ] [
585     float-4{ 1.0 0.0 1.0 0.0 } pi [ broken 3array ]
586     [ compile-call ] [ call ] 3bi =
587 ] unit-test
588
589 ! Spilling SIMD values -- this basically just tests that the
590 ! stack was aligned properly by the runtime
591
592 : simd-spill-test-1 ( a b c -- v )
593     { float-4 float-4 float } declare 
594     [ v+ ] dip sin v*n ;
595
596 [ float-4{ 0 0 0 0 } ]
597 [ float-4{ 1 2 3 4 } float-4{ 4 5 6 7 } 0.0 simd-spill-test-1 ] unit-test
598
599 : simd-spill-test-2 ( a b d c -- v )
600     { float float-4 float-4 float } declare 
601     [ [ 3.0 + ] 2dip v+ ] dip sin v*n n*v ;
602
603 [ float-4{ 0 0 0 0 } ]
604 [ 5.0 float-4{ 1 2 3 4 } float-4{ 4 5 6 7 } 0.0 simd-spill-test-2 ] unit-test