• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Tests floating point arithmetic expressions
6
7package main
8
9import (
10	"fmt"
11	"testing"
12)
13
14// manysub_ssa is designed to tickle bugs that depend on register
15// pressure or unfriendly operand ordering in registers (and at
16// least once it succeeded in this).
17//
18//go:noinline
19func manysub_ssa(a, b, c, d float64) (aa, ab, ac, ad, ba, bb, bc, bd, ca, cb, cc, cd, da, db, dc, dd float64) {
20	aa = a + 11.0 - a
21	ab = a - b
22	ac = a - c
23	ad = a - d
24	ba = b - a
25	bb = b + 22.0 - b
26	bc = b - c
27	bd = b - d
28	ca = c - a
29	cb = c - b
30	cc = c + 33.0 - c
31	cd = c - d
32	da = d - a
33	db = d - b
34	dc = d - c
35	dd = d + 44.0 - d
36	return
37}
38
39// fpspill_ssa attempts to trigger a bug where phis with floating point values
40// were stored in non-fp registers causing an error in doasm.
41//
42//go:noinline
43func fpspill_ssa(a int) float64 {
44
45	ret := -1.0
46	switch a {
47	case 0:
48		ret = 1.0
49	case 1:
50		ret = 1.1
51	case 2:
52		ret = 1.2
53	case 3:
54		ret = 1.3
55	case 4:
56		ret = 1.4
57	case 5:
58		ret = 1.5
59	case 6:
60		ret = 1.6
61	case 7:
62		ret = 1.7
63	case 8:
64		ret = 1.8
65	case 9:
66		ret = 1.9
67	case 10:
68		ret = 1.10
69	case 11:
70		ret = 1.11
71	case 12:
72		ret = 1.12
73	case 13:
74		ret = 1.13
75	case 14:
76		ret = 1.14
77	case 15:
78		ret = 1.15
79	case 16:
80		ret = 1.16
81	}
82	return ret
83}
84
85//go:noinline
86func add64_ssa(a, b float64) float64 {
87	return a + b
88}
89
90//go:noinline
91func mul64_ssa(a, b float64) float64 {
92	return a * b
93}
94
95//go:noinline
96func sub64_ssa(a, b float64) float64 {
97	return a - b
98}
99
100//go:noinline
101func div64_ssa(a, b float64) float64 {
102	return a / b
103}
104
105//go:noinline
106func neg64_ssa(a, b float64) float64 {
107	return -a + -1*b
108}
109
110//go:noinline
111func add32_ssa(a, b float32) float32 {
112	return a + b
113}
114
115//go:noinline
116func mul32_ssa(a, b float32) float32 {
117	return a * b
118}
119
120//go:noinline
121func sub32_ssa(a, b float32) float32 {
122	return a - b
123}
124
125//go:noinline
126func div32_ssa(a, b float32) float32 {
127	return a / b
128}
129
130//go:noinline
131func neg32_ssa(a, b float32) float32 {
132	return -a + -1*b
133}
134
135//go:noinline
136func conv2Float64_ssa(a int8, b uint8, c int16, d uint16,
137	e int32, f uint32, g int64, h uint64, i float32) (aa, bb, cc, dd, ee, ff, gg, hh, ii float64) {
138	aa = float64(a)
139	bb = float64(b)
140	cc = float64(c)
141	hh = float64(h)
142	dd = float64(d)
143	ee = float64(e)
144	ff = float64(f)
145	gg = float64(g)
146	ii = float64(i)
147	return
148}
149
150//go:noinline
151func conv2Float32_ssa(a int8, b uint8, c int16, d uint16,
152	e int32, f uint32, g int64, h uint64, i float64) (aa, bb, cc, dd, ee, ff, gg, hh, ii float32) {
153	aa = float32(a)
154	bb = float32(b)
155	cc = float32(c)
156	dd = float32(d)
157	ee = float32(e)
158	ff = float32(f)
159	gg = float32(g)
160	hh = float32(h)
161	ii = float32(i)
162	return
163}
164
165func integer2floatConversions(t *testing.T) {
166	{
167		a, b, c, d, e, f, g, h, i := conv2Float64_ssa(0, 0, 0, 0, 0, 0, 0, 0, 0)
168		expectAll64(t, "zero64", 0, a, b, c, d, e, f, g, h, i)
169	}
170	{
171		a, b, c, d, e, f, g, h, i := conv2Float64_ssa(1, 1, 1, 1, 1, 1, 1, 1, 1)
172		expectAll64(t, "one64", 1, a, b, c, d, e, f, g, h, i)
173	}
174	{
175		a, b, c, d, e, f, g, h, i := conv2Float32_ssa(0, 0, 0, 0, 0, 0, 0, 0, 0)
176		expectAll32(t, "zero32", 0, a, b, c, d, e, f, g, h, i)
177	}
178	{
179		a, b, c, d, e, f, g, h, i := conv2Float32_ssa(1, 1, 1, 1, 1, 1, 1, 1, 1)
180		expectAll32(t, "one32", 1, a, b, c, d, e, f, g, h, i)
181	}
182	{
183		// Check maximum values
184		a, b, c, d, e, f, g, h, i := conv2Float64_ssa(127, 255, 32767, 65535, 0x7fffffff, 0xffffffff, 0x7fffFFFFffffFFFF, 0xffffFFFFffffFFFF, 3.402823e38)
185		expect64(t, "a", a, 127)
186		expect64(t, "b", b, 255)
187		expect64(t, "c", c, 32767)
188		expect64(t, "d", d, 65535)
189		expect64(t, "e", e, float64(int32(0x7fffffff)))
190		expect64(t, "f", f, float64(uint32(0xffffffff)))
191		expect64(t, "g", g, float64(int64(0x7fffffffffffffff)))
192		expect64(t, "h", h, float64(uint64(0xffffffffffffffff)))
193		expect64(t, "i", i, float64(float32(3.402823e38)))
194	}
195	{
196		// Check minimum values (and tweaks for unsigned)
197		a, b, c, d, e, f, g, h, i := conv2Float64_ssa(-128, 254, -32768, 65534, ^0x7fffffff, 0xfffffffe, ^0x7fffFFFFffffFFFF, 0xffffFFFFffffF401, 1.5e-45)
198		expect64(t, "a", a, -128)
199		expect64(t, "b", b, 254)
200		expect64(t, "c", c, -32768)
201		expect64(t, "d", d, 65534)
202		expect64(t, "e", e, float64(^int32(0x7fffffff)))
203		expect64(t, "f", f, float64(uint32(0xfffffffe)))
204		expect64(t, "g", g, float64(^int64(0x7fffffffffffffff)))
205		expect64(t, "h", h, float64(uint64(0xfffffffffffff401)))
206		expect64(t, "i", i, float64(float32(1.5e-45)))
207	}
208	{
209		// Check maximum values
210		a, b, c, d, e, f, g, h, i := conv2Float32_ssa(127, 255, 32767, 65535, 0x7fffffff, 0xffffffff, 0x7fffFFFFffffFFFF, 0xffffFFFFffffFFFF, 3.402823e38)
211		expect32(t, "a", a, 127)
212		expect32(t, "b", b, 255)
213		expect32(t, "c", c, 32767)
214		expect32(t, "d", d, 65535)
215		expect32(t, "e", e, float32(int32(0x7fffffff)))
216		expect32(t, "f", f, float32(uint32(0xffffffff)))
217		expect32(t, "g", g, float32(int64(0x7fffffffffffffff)))
218		expect32(t, "h", h, float32(uint64(0xffffffffffffffff)))
219		expect32(t, "i", i, float32(float64(3.402823e38)))
220	}
221	{
222		// Check minimum values (and tweaks for unsigned)
223		a, b, c, d, e, f, g, h, i := conv2Float32_ssa(-128, 254, -32768, 65534, ^0x7fffffff, 0xfffffffe, ^0x7fffFFFFffffFFFF, 0xffffFFFFffffF401, 1.5e-45)
224		expect32(t, "a", a, -128)
225		expect32(t, "b", b, 254)
226		expect32(t, "c", c, -32768)
227		expect32(t, "d", d, 65534)
228		expect32(t, "e", e, float32(^int32(0x7fffffff)))
229		expect32(t, "f", f, float32(uint32(0xfffffffe)))
230		expect32(t, "g", g, float32(^int64(0x7fffffffffffffff)))
231		expect32(t, "h", h, float32(uint64(0xfffffffffffff401)))
232		expect32(t, "i", i, float32(float64(1.5e-45)))
233	}
234}
235
236func multiplyAdd(t *testing.T) {
237	{
238		// Test that a multiply-accumulate operation with intermediate
239		// rounding forced by a float32() cast produces the expected
240		// result.
241		// Test cases generated experimentally on a system (s390x) that
242		// supports fused multiply-add instructions.
243		var tests = [...]struct{ x, y, z, res float32 }{
244			{0.6046603, 0.9405091, 0.6645601, 1.2332485},      // fused multiply-add result: 1.2332486
245			{0.67908466, 0.21855305, 0.20318687, 0.3516029},   // fused multiply-add result: 0.35160288
246			{0.29311424, 0.29708257, 0.752573, 0.8396522},     // fused multiply-add result: 0.8396521
247			{0.5305857, 0.2535405, 0.282081, 0.41660595},      // fused multiply-add result: 0.41660598
248			{0.29711226, 0.89436173, 0.097454615, 0.36318043}, // fused multiply-add result: 0.36318046
249			{0.6810783, 0.24151509, 0.31152245, 0.47601312},   // fused multiply-add result: 0.47601315
250			{0.73023146, 0.18292491, 0.4283571, 0.5619346},    // fused multiply-add result: 0.56193465
251			{0.89634174, 0.32208398, 0.7211478, 1.009845},     // fused multiply-add result: 1.0098451
252			{0.6280982, 0.12675293, 0.2813303, 0.36094356},    // fused multiply-add result: 0.3609436
253			{0.29400632, 0.75316125, 0.15096405, 0.3723982},   // fused multiply-add result: 0.37239823
254		}
255		check := func(s string, got, expected float32) {
256			if got != expected {
257				fmt.Printf("multiplyAdd: %s, expected %g, got %g\n", s, expected, got)
258			}
259		}
260		for _, t := range tests {
261			check(
262				fmt.Sprintf("float32(%v * %v) + %v", t.x, t.y, t.z),
263				func(x, y, z float32) float32 {
264					return float32(x*y) + z
265				}(t.x, t.y, t.z),
266				t.res)
267
268			check(
269				fmt.Sprintf("%v += float32(%v * %v)", t.z, t.x, t.y),
270				func(x, y, z float32) float32 {
271					z += float32(x * y)
272					return z
273				}(t.x, t.y, t.z),
274				t.res)
275		}
276	}
277	{
278		// Test that a multiply-accumulate operation with intermediate
279		// rounding forced by a float64() cast produces the expected
280		// result.
281		// Test cases generated experimentally on a system (s390x) that
282		// supports fused multiply-add instructions.
283		var tests = [...]struct{ x, y, z, res float64 }{
284			{0.4688898449024232, 0.28303415118044517, 0.29310185733681576, 0.42581369658590373}, // fused multiply-add result: 0.4258136965859037
285			{0.7886049150193449, 0.3618054804803169, 0.8805431227416171, 1.1658647029293308},    // fused multiply-add result: 1.1658647029293305
286			{0.7302314772948083, 0.18292491645390843, 0.4283570818068078, 0.5619346137829748},   // fused multiply-add result: 0.5619346137829747
287			{0.6908388315056789, 0.7109071952999951, 0.5637795958152644, 1.0549018919252924},    // fused multiply-add result: 1.0549018919252926
288			{0.4584424785756506, 0.6001655953233308, 0.02626515060968944, 0.3014065536855481},   // fused multiply-add result: 0.30140655368554814
289			{0.539210105890946, 0.9756748149873165, 0.7507630564795985, 1.2768567767840384},     // fused multiply-add result: 1.2768567767840386
290			{0.7830349733960021, 0.3932509992288867, 0.1304138461737918, 0.4383431318929343},    // fused multiply-add result: 0.43834313189293433
291			{0.6841751300974551, 0.6530402051353608, 0.524499759549865, 0.9712936268572192},     // fused multiply-add result: 0.9712936268572193
292			{0.3691117091643448, 0.826454125634742, 0.34768170859156955, 0.6527356034505334},    // fused multiply-add result: 0.6527356034505333
293			{0.16867966833433606, 0.33136826030698385, 0.8279280961505588, 0.8838231843956668},  // fused multiply-add result: 0.8838231843956669
294		}
295		check := func(s string, got, expected float64) {
296			if got != expected {
297				fmt.Printf("multiplyAdd: %s, expected %g, got %g\n", s, expected, got)
298			}
299		}
300		for _, t := range tests {
301			check(
302				fmt.Sprintf("float64(%v * %v) + %v", t.x, t.y, t.z),
303				func(x, y, z float64) float64 {
304					return float64(x*y) + z
305				}(t.x, t.y, t.z),
306				t.res)
307
308			check(
309				fmt.Sprintf("%v += float64(%v * %v)", t.z, t.x, t.y),
310				func(x, y, z float64) float64 {
311					z += float64(x * y)
312					return z
313				}(t.x, t.y, t.z),
314				t.res)
315		}
316	}
317	{
318		// Test that a multiply-accumulate operation with intermediate
319		// rounding forced by a complex128() cast produces the expected
320		// result.
321		// Test cases generated experimentally on a system (s390x) that
322		// supports fused multiply-add instructions.
323		var tests = [...]struct {
324			x, y float64
325			res  complex128
326		}{
327			{0.6046602879796196, 0.9405090880450124, (2.754489951983871 + 3i)},    // fused multiply-add result: (2.7544899519838713 + 3i)
328			{0.09696951891448456, 0.30091186058528707, (0.5918204173287407 + 3i)}, // fused multiply-add result: (0.5918204173287408 + 3i)
329			{0.544155573000885, 0.27850762181610883, (1.910974340818764 + 3i)},    // fused multiply-add result: (1.9109743408187638 + 3i)
330			{0.9769168685862624, 0.07429099894984302, (3.0050416047086297 + 3i)},  // fused multiply-add result: (3.00504160470863 + 3i)
331			{0.9269868035744142, 0.9549454404167818, (3.735905851140024 + 3i)},    // fused multiply-add result: (3.7359058511400245 + 3i)
332			{0.7109071952999951, 0.5637795958152644, (2.69650118171525 + 3i)},     // fused multiply-add result: (2.6965011817152496 + 3i)
333			{0.7558235074915978, 0.40380328579570035, (2.671273808270494 + 3i)},   // fused multiply-add result: (2.6712738082704934 + 3i)
334			{0.13065111702897217, 0.9859647293402467, (1.3779180804271633 + 3i)},  // fused multiply-add result: (1.3779180804271631 + 3i)
335			{0.8963417453962161, 0.3220839705208817, (3.0111092067095298 + 3i)},   // fused multiply-add result: (3.01110920670953 + 3i)
336			{0.39998376285699544, 0.497868113342702, (1.697819401913688 + 3i)},    // fused multiply-add result: (1.6978194019136883 + 3i)
337		}
338		check := func(s string, got, expected complex128) {
339			if got != expected {
340				fmt.Printf("multiplyAdd: %s, expected %v, got %v\n", s, expected, got)
341			}
342		}
343		for _, t := range tests {
344			check(
345				fmt.Sprintf("complex128(complex(%v, 1)*3) + complex(%v, 0)", t.x, t.y),
346				func(x, y float64) complex128 {
347					return complex128(complex(x, 1)*3) + complex(y, 0)
348				}(t.x, t.y),
349				t.res)
350
351			check(
352				fmt.Sprintf("z := complex(%v, 1); z += complex128(complex(%v, 1) * 3)", t.y, t.x),
353				func(x, y float64) complex128 {
354					z := complex(y, 0)
355					z += complex128(complex(x, 1) * 3)
356					return z
357				}(t.x, t.y),
358				t.res)
359		}
360	}
361}
362
363const (
364	aa = 0x1000000000000000
365	ab = 0x100000000000000
366	ac = 0x10000000000000
367	ad = 0x1000000000000
368	ba = 0x100000000000
369	bb = 0x10000000000
370	bc = 0x1000000000
371	bd = 0x100000000
372	ca = 0x10000000
373	cb = 0x1000000
374	cc = 0x100000
375	cd = 0x10000
376	da = 0x1000
377	db = 0x100
378	dc = 0x10
379	dd = 0x1
380)
381
382//go:noinline
383func compares64_ssa(a, b, c, d float64) (lt, le, eq, ne, ge, gt uint64) {
384	if a < a {
385		lt += aa
386	}
387	if a < b {
388		lt += ab
389	}
390	if a < c {
391		lt += ac
392	}
393	if a < d {
394		lt += ad
395	}
396
397	if b < a {
398		lt += ba
399	}
400	if b < b {
401		lt += bb
402	}
403	if b < c {
404		lt += bc
405	}
406	if b < d {
407		lt += bd
408	}
409
410	if c < a {
411		lt += ca
412	}
413	if c < b {
414		lt += cb
415	}
416	if c < c {
417		lt += cc
418	}
419	if c < d {
420		lt += cd
421	}
422
423	if d < a {
424		lt += da
425	}
426	if d < b {
427		lt += db
428	}
429	if d < c {
430		lt += dc
431	}
432	if d < d {
433		lt += dd
434	}
435
436	if a <= a {
437		le += aa
438	}
439	if a <= b {
440		le += ab
441	}
442	if a <= c {
443		le += ac
444	}
445	if a <= d {
446		le += ad
447	}
448
449	if b <= a {
450		le += ba
451	}
452	if b <= b {
453		le += bb
454	}
455	if b <= c {
456		le += bc
457	}
458	if b <= d {
459		le += bd
460	}
461
462	if c <= a {
463		le += ca
464	}
465	if c <= b {
466		le += cb
467	}
468	if c <= c {
469		le += cc
470	}
471	if c <= d {
472		le += cd
473	}
474
475	if d <= a {
476		le += da
477	}
478	if d <= b {
479		le += db
480	}
481	if d <= c {
482		le += dc
483	}
484	if d <= d {
485		le += dd
486	}
487
488	if a == a {
489		eq += aa
490	}
491	if a == b {
492		eq += ab
493	}
494	if a == c {
495		eq += ac
496	}
497	if a == d {
498		eq += ad
499	}
500
501	if b == a {
502		eq += ba
503	}
504	if b == b {
505		eq += bb
506	}
507	if b == c {
508		eq += bc
509	}
510	if b == d {
511		eq += bd
512	}
513
514	if c == a {
515		eq += ca
516	}
517	if c == b {
518		eq += cb
519	}
520	if c == c {
521		eq += cc
522	}
523	if c == d {
524		eq += cd
525	}
526
527	if d == a {
528		eq += da
529	}
530	if d == b {
531		eq += db
532	}
533	if d == c {
534		eq += dc
535	}
536	if d == d {
537		eq += dd
538	}
539
540	if a != a {
541		ne += aa
542	}
543	if a != b {
544		ne += ab
545	}
546	if a != c {
547		ne += ac
548	}
549	if a != d {
550		ne += ad
551	}
552
553	if b != a {
554		ne += ba
555	}
556	if b != b {
557		ne += bb
558	}
559	if b != c {
560		ne += bc
561	}
562	if b != d {
563		ne += bd
564	}
565
566	if c != a {
567		ne += ca
568	}
569	if c != b {
570		ne += cb
571	}
572	if c != c {
573		ne += cc
574	}
575	if c != d {
576		ne += cd
577	}
578
579	if d != a {
580		ne += da
581	}
582	if d != b {
583		ne += db
584	}
585	if d != c {
586		ne += dc
587	}
588	if d != d {
589		ne += dd
590	}
591
592	if a >= a {
593		ge += aa
594	}
595	if a >= b {
596		ge += ab
597	}
598	if a >= c {
599		ge += ac
600	}
601	if a >= d {
602		ge += ad
603	}
604
605	if b >= a {
606		ge += ba
607	}
608	if b >= b {
609		ge += bb
610	}
611	if b >= c {
612		ge += bc
613	}
614	if b >= d {
615		ge += bd
616	}
617
618	if c >= a {
619		ge += ca
620	}
621	if c >= b {
622		ge += cb
623	}
624	if c >= c {
625		ge += cc
626	}
627	if c >= d {
628		ge += cd
629	}
630
631	if d >= a {
632		ge += da
633	}
634	if d >= b {
635		ge += db
636	}
637	if d >= c {
638		ge += dc
639	}
640	if d >= d {
641		ge += dd
642	}
643
644	if a > a {
645		gt += aa
646	}
647	if a > b {
648		gt += ab
649	}
650	if a > c {
651		gt += ac
652	}
653	if a > d {
654		gt += ad
655	}
656
657	if b > a {
658		gt += ba
659	}
660	if b > b {
661		gt += bb
662	}
663	if b > c {
664		gt += bc
665	}
666	if b > d {
667		gt += bd
668	}
669
670	if c > a {
671		gt += ca
672	}
673	if c > b {
674		gt += cb
675	}
676	if c > c {
677		gt += cc
678	}
679	if c > d {
680		gt += cd
681	}
682
683	if d > a {
684		gt += da
685	}
686	if d > b {
687		gt += db
688	}
689	if d > c {
690		gt += dc
691	}
692	if d > d {
693		gt += dd
694	}
695
696	return
697}
698
699//go:noinline
700func compares32_ssa(a, b, c, d float32) (lt, le, eq, ne, ge, gt uint64) {
701	if a < a {
702		lt += aa
703	}
704	if a < b {
705		lt += ab
706	}
707	if a < c {
708		lt += ac
709	}
710	if a < d {
711		lt += ad
712	}
713
714	if b < a {
715		lt += ba
716	}
717	if b < b {
718		lt += bb
719	}
720	if b < c {
721		lt += bc
722	}
723	if b < d {
724		lt += bd
725	}
726
727	if c < a {
728		lt += ca
729	}
730	if c < b {
731		lt += cb
732	}
733	if c < c {
734		lt += cc
735	}
736	if c < d {
737		lt += cd
738	}
739
740	if d < a {
741		lt += da
742	}
743	if d < b {
744		lt += db
745	}
746	if d < c {
747		lt += dc
748	}
749	if d < d {
750		lt += dd
751	}
752
753	if a <= a {
754		le += aa
755	}
756	if a <= b {
757		le += ab
758	}
759	if a <= c {
760		le += ac
761	}
762	if a <= d {
763		le += ad
764	}
765
766	if b <= a {
767		le += ba
768	}
769	if b <= b {
770		le += bb
771	}
772	if b <= c {
773		le += bc
774	}
775	if b <= d {
776		le += bd
777	}
778
779	if c <= a {
780		le += ca
781	}
782	if c <= b {
783		le += cb
784	}
785	if c <= c {
786		le += cc
787	}
788	if c <= d {
789		le += cd
790	}
791
792	if d <= a {
793		le += da
794	}
795	if d <= b {
796		le += db
797	}
798	if d <= c {
799		le += dc
800	}
801	if d <= d {
802		le += dd
803	}
804
805	if a == a {
806		eq += aa
807	}
808	if a == b {
809		eq += ab
810	}
811	if a == c {
812		eq += ac
813	}
814	if a == d {
815		eq += ad
816	}
817
818	if b == a {
819		eq += ba
820	}
821	if b == b {
822		eq += bb
823	}
824	if b == c {
825		eq += bc
826	}
827	if b == d {
828		eq += bd
829	}
830
831	if c == a {
832		eq += ca
833	}
834	if c == b {
835		eq += cb
836	}
837	if c == c {
838		eq += cc
839	}
840	if c == d {
841		eq += cd
842	}
843
844	if d == a {
845		eq += da
846	}
847	if d == b {
848		eq += db
849	}
850	if d == c {
851		eq += dc
852	}
853	if d == d {
854		eq += dd
855	}
856
857	if a != a {
858		ne += aa
859	}
860	if a != b {
861		ne += ab
862	}
863	if a != c {
864		ne += ac
865	}
866	if a != d {
867		ne += ad
868	}
869
870	if b != a {
871		ne += ba
872	}
873	if b != b {
874		ne += bb
875	}
876	if b != c {
877		ne += bc
878	}
879	if b != d {
880		ne += bd
881	}
882
883	if c != a {
884		ne += ca
885	}
886	if c != b {
887		ne += cb
888	}
889	if c != c {
890		ne += cc
891	}
892	if c != d {
893		ne += cd
894	}
895
896	if d != a {
897		ne += da
898	}
899	if d != b {
900		ne += db
901	}
902	if d != c {
903		ne += dc
904	}
905	if d != d {
906		ne += dd
907	}
908
909	if a >= a {
910		ge += aa
911	}
912	if a >= b {
913		ge += ab
914	}
915	if a >= c {
916		ge += ac
917	}
918	if a >= d {
919		ge += ad
920	}
921
922	if b >= a {
923		ge += ba
924	}
925	if b >= b {
926		ge += bb
927	}
928	if b >= c {
929		ge += bc
930	}
931	if b >= d {
932		ge += bd
933	}
934
935	if c >= a {
936		ge += ca
937	}
938	if c >= b {
939		ge += cb
940	}
941	if c >= c {
942		ge += cc
943	}
944	if c >= d {
945		ge += cd
946	}
947
948	if d >= a {
949		ge += da
950	}
951	if d >= b {
952		ge += db
953	}
954	if d >= c {
955		ge += dc
956	}
957	if d >= d {
958		ge += dd
959	}
960
961	if a > a {
962		gt += aa
963	}
964	if a > b {
965		gt += ab
966	}
967	if a > c {
968		gt += ac
969	}
970	if a > d {
971		gt += ad
972	}
973
974	if b > a {
975		gt += ba
976	}
977	if b > b {
978		gt += bb
979	}
980	if b > c {
981		gt += bc
982	}
983	if b > d {
984		gt += bd
985	}
986
987	if c > a {
988		gt += ca
989	}
990	if c > b {
991		gt += cb
992	}
993	if c > c {
994		gt += cc
995	}
996	if c > d {
997		gt += cd
998	}
999
1000	if d > a {
1001		gt += da
1002	}
1003	if d > b {
1004		gt += db
1005	}
1006	if d > c {
1007		gt += dc
1008	}
1009	if d > d {
1010		gt += dd
1011	}
1012
1013	return
1014}
1015
1016//go:noinline
1017func le64_ssa(x, y float64) bool {
1018	return x <= y
1019}
1020
1021//go:noinline
1022func ge64_ssa(x, y float64) bool {
1023	return x >= y
1024}
1025
1026//go:noinline
1027func lt64_ssa(x, y float64) bool {
1028	return x < y
1029}
1030
1031//go:noinline
1032func gt64_ssa(x, y float64) bool {
1033	return x > y
1034}
1035
1036//go:noinline
1037func eq64_ssa(x, y float64) bool {
1038	return x == y
1039}
1040
1041//go:noinline
1042func ne64_ssa(x, y float64) bool {
1043	return x != y
1044}
1045
1046//go:noinline
1047func eqbr64_ssa(x, y float64) float64 {
1048	if x == y {
1049		return 17
1050	}
1051	return 42
1052}
1053
1054//go:noinline
1055func nebr64_ssa(x, y float64) float64 {
1056	if x != y {
1057		return 17
1058	}
1059	return 42
1060}
1061
1062//go:noinline
1063func gebr64_ssa(x, y float64) float64 {
1064	if x >= y {
1065		return 17
1066	}
1067	return 42
1068}
1069
1070//go:noinline
1071func lebr64_ssa(x, y float64) float64 {
1072	if x <= y {
1073		return 17
1074	}
1075	return 42
1076}
1077
1078//go:noinline
1079func ltbr64_ssa(x, y float64) float64 {
1080	if x < y {
1081		return 17
1082	}
1083	return 42
1084}
1085
1086//go:noinline
1087func gtbr64_ssa(x, y float64) float64 {
1088	if x > y {
1089		return 17
1090	}
1091	return 42
1092}
1093
1094//go:noinline
1095func le32_ssa(x, y float32) bool {
1096	return x <= y
1097}
1098
1099//go:noinline
1100func ge32_ssa(x, y float32) bool {
1101	return x >= y
1102}
1103
1104//go:noinline
1105func lt32_ssa(x, y float32) bool {
1106	return x < y
1107}
1108
1109//go:noinline
1110func gt32_ssa(x, y float32) bool {
1111	return x > y
1112}
1113
1114//go:noinline
1115func eq32_ssa(x, y float32) bool {
1116	return x == y
1117}
1118
1119//go:noinline
1120func ne32_ssa(x, y float32) bool {
1121	return x != y
1122}
1123
1124//go:noinline
1125func eqbr32_ssa(x, y float32) float32 {
1126	if x == y {
1127		return 17
1128	}
1129	return 42
1130}
1131
1132//go:noinline
1133func nebr32_ssa(x, y float32) float32 {
1134	if x != y {
1135		return 17
1136	}
1137	return 42
1138}
1139
1140//go:noinline
1141func gebr32_ssa(x, y float32) float32 {
1142	if x >= y {
1143		return 17
1144	}
1145	return 42
1146}
1147
1148//go:noinline
1149func lebr32_ssa(x, y float32) float32 {
1150	if x <= y {
1151		return 17
1152	}
1153	return 42
1154}
1155
1156//go:noinline
1157func ltbr32_ssa(x, y float32) float32 {
1158	if x < y {
1159		return 17
1160	}
1161	return 42
1162}
1163
1164//go:noinline
1165func gtbr32_ssa(x, y float32) float32 {
1166	if x > y {
1167		return 17
1168	}
1169	return 42
1170}
1171
1172//go:noinline
1173func F32toU8_ssa(x float32) uint8 {
1174	return uint8(x)
1175}
1176
1177//go:noinline
1178func F32toI8_ssa(x float32) int8 {
1179	return int8(x)
1180}
1181
1182//go:noinline
1183func F32toU16_ssa(x float32) uint16 {
1184	return uint16(x)
1185}
1186
1187//go:noinline
1188func F32toI16_ssa(x float32) int16 {
1189	return int16(x)
1190}
1191
1192//go:noinline
1193func F32toU32_ssa(x float32) uint32 {
1194	return uint32(x)
1195}
1196
1197//go:noinline
1198func F32toI32_ssa(x float32) int32 {
1199	return int32(x)
1200}
1201
1202//go:noinline
1203func F32toU64_ssa(x float32) uint64 {
1204	return uint64(x)
1205}
1206
1207//go:noinline
1208func F32toI64_ssa(x float32) int64 {
1209	return int64(x)
1210}
1211
1212//go:noinline
1213func F64toU8_ssa(x float64) uint8 {
1214	return uint8(x)
1215}
1216
1217//go:noinline
1218func F64toI8_ssa(x float64) int8 {
1219	return int8(x)
1220}
1221
1222//go:noinline
1223func F64toU16_ssa(x float64) uint16 {
1224	return uint16(x)
1225}
1226
1227//go:noinline
1228func F64toI16_ssa(x float64) int16 {
1229	return int16(x)
1230}
1231
1232//go:noinline
1233func F64toU32_ssa(x float64) uint32 {
1234	return uint32(x)
1235}
1236
1237//go:noinline
1238func F64toI32_ssa(x float64) int32 {
1239	return int32(x)
1240}
1241
1242//go:noinline
1243func F64toU64_ssa(x float64) uint64 {
1244	return uint64(x)
1245}
1246
1247//go:noinline
1248func F64toI64_ssa(x float64) int64 {
1249	return int64(x)
1250}
1251
1252func floatsToInts(t *testing.T, x float64, expected int64) {
1253	y := float32(x)
1254	expectInt64(t, "F64toI8", int64(F64toI8_ssa(x)), expected)
1255	expectInt64(t, "F64toI16", int64(F64toI16_ssa(x)), expected)
1256	expectInt64(t, "F64toI32", int64(F64toI32_ssa(x)), expected)
1257	expectInt64(t, "F64toI64", int64(F64toI64_ssa(x)), expected)
1258	expectInt64(t, "F32toI8", int64(F32toI8_ssa(y)), expected)
1259	expectInt64(t, "F32toI16", int64(F32toI16_ssa(y)), expected)
1260	expectInt64(t, "F32toI32", int64(F32toI32_ssa(y)), expected)
1261	expectInt64(t, "F32toI64", int64(F32toI64_ssa(y)), expected)
1262}
1263
1264func floatsToUints(t *testing.T, x float64, expected uint64) {
1265	y := float32(x)
1266	expectUint64(t, "F64toU8", uint64(F64toU8_ssa(x)), expected)
1267	expectUint64(t, "F64toU16", uint64(F64toU16_ssa(x)), expected)
1268	expectUint64(t, "F64toU32", uint64(F64toU32_ssa(x)), expected)
1269	expectUint64(t, "F64toU64", uint64(F64toU64_ssa(x)), expected)
1270	expectUint64(t, "F32toU8", uint64(F32toU8_ssa(y)), expected)
1271	expectUint64(t, "F32toU16", uint64(F32toU16_ssa(y)), expected)
1272	expectUint64(t, "F32toU32", uint64(F32toU32_ssa(y)), expected)
1273	expectUint64(t, "F32toU64", uint64(F32toU64_ssa(y)), expected)
1274}
1275
1276func floatingToIntegerConversionsTest(t *testing.T) {
1277	floatsToInts(t, 0.0, 0)
1278	floatsToInts(t, 0.5, 0)
1279	floatsToInts(t, 0.9, 0)
1280	floatsToInts(t, 1.0, 1)
1281	floatsToInts(t, 1.5, 1)
1282	floatsToInts(t, 127.0, 127)
1283	floatsToInts(t, -1.0, -1)
1284	floatsToInts(t, -128.0, -128)
1285
1286	floatsToUints(t, 0.0, 0)
1287	floatsToUints(t, 1.0, 1)
1288	floatsToUints(t, 255.0, 255)
1289
1290	for j := uint(0); j < 24; j++ {
1291		// Avoid hard cases in the construction
1292		// of the test inputs.
1293		v := int64(1<<62) | int64(1<<(62-j))
1294		w := uint64(v)
1295		f := float32(v)
1296		d := float64(v)
1297		expectUint64(t, "2**62...", F32toU64_ssa(f), w)
1298		expectUint64(t, "2**62...", F64toU64_ssa(d), w)
1299		expectInt64(t, "2**62...", F32toI64_ssa(f), v)
1300		expectInt64(t, "2**62...", F64toI64_ssa(d), v)
1301		expectInt64(t, "2**62...", F32toI64_ssa(-f), -v)
1302		expectInt64(t, "2**62...", F64toI64_ssa(-d), -v)
1303		w += w
1304		f += f
1305		d += d
1306		expectUint64(t, "2**63...", F32toU64_ssa(f), w)
1307		expectUint64(t, "2**63...", F64toU64_ssa(d), w)
1308	}
1309
1310	for j := uint(0); j < 16; j++ {
1311		// Avoid hard cases in the construction
1312		// of the test inputs.
1313		v := int32(1<<30) | int32(1<<(30-j))
1314		w := uint32(v)
1315		f := float32(v)
1316		d := float64(v)
1317		expectUint32(t, "2**30...", F32toU32_ssa(f), w)
1318		expectUint32(t, "2**30...", F64toU32_ssa(d), w)
1319		expectInt32(t, "2**30...", F32toI32_ssa(f), v)
1320		expectInt32(t, "2**30...", F64toI32_ssa(d), v)
1321		expectInt32(t, "2**30...", F32toI32_ssa(-f), -v)
1322		expectInt32(t, "2**30...", F64toI32_ssa(-d), -v)
1323		w += w
1324		f += f
1325		d += d
1326		expectUint32(t, "2**31...", F32toU32_ssa(f), w)
1327		expectUint32(t, "2**31...", F64toU32_ssa(d), w)
1328	}
1329
1330	for j := uint(0); j < 15; j++ {
1331		// Avoid hard cases in the construction
1332		// of the test inputs.
1333		v := int16(1<<14) | int16(1<<(14-j))
1334		w := uint16(v)
1335		f := float32(v)
1336		d := float64(v)
1337		expectUint16(t, "2**14...", F32toU16_ssa(f), w)
1338		expectUint16(t, "2**14...", F64toU16_ssa(d), w)
1339		expectInt16(t, "2**14...", F32toI16_ssa(f), v)
1340		expectInt16(t, "2**14...", F64toI16_ssa(d), v)
1341		expectInt16(t, "2**14...", F32toI16_ssa(-f), -v)
1342		expectInt16(t, "2**14...", F64toI16_ssa(-d), -v)
1343		w += w
1344		f += f
1345		d += d
1346		expectUint16(t, "2**15...", F32toU16_ssa(f), w)
1347		expectUint16(t, "2**15...", F64toU16_ssa(d), w)
1348	}
1349
1350	expectInt32(t, "-2147483648", F32toI32_ssa(-2147483648), -2147483648)
1351
1352	expectInt32(t, "-2147483648", F64toI32_ssa(-2147483648), -2147483648)
1353	expectInt32(t, "-2147483647", F64toI32_ssa(-2147483647), -2147483647)
1354	expectUint32(t, "4294967295", F64toU32_ssa(4294967295), 4294967295)
1355
1356	expectInt16(t, "-32768", F64toI16_ssa(-32768), -32768)
1357	expectInt16(t, "-32768", F32toI16_ssa(-32768), -32768)
1358
1359	// NB more of a pain to do these for 32-bit because of lost bits in Float32 mantissa
1360	expectInt16(t, "32767", F64toI16_ssa(32767), 32767)
1361	expectInt16(t, "32767", F32toI16_ssa(32767), 32767)
1362	expectUint16(t, "32767", F64toU16_ssa(32767), 32767)
1363	expectUint16(t, "32767", F32toU16_ssa(32767), 32767)
1364	expectUint16(t, "65535", F64toU16_ssa(65535), 65535)
1365	expectUint16(t, "65535", F32toU16_ssa(65535), 65535)
1366}
1367
1368func fail64(s string, f func(a, b float64) float64, a, b, e float64) {
1369	d := f(a, b)
1370	if d != e {
1371		fmt.Printf("For (float64) %v %v %v, expected %v, got %v\n", a, s, b, e, d)
1372	}
1373}
1374
1375func fail64bool(s string, f func(a, b float64) bool, a, b float64, e bool) {
1376	d := f(a, b)
1377	if d != e {
1378		fmt.Printf("For (float64) %v %v %v, expected %v, got %v\n", a, s, b, e, d)
1379	}
1380}
1381
1382func fail32(s string, f func(a, b float32) float32, a, b, e float32) {
1383	d := f(a, b)
1384	if d != e {
1385		fmt.Printf("For (float32) %v %v %v, expected %v, got %v\n", a, s, b, e, d)
1386	}
1387}
1388
1389func fail32bool(s string, f func(a, b float32) bool, a, b float32, e bool) {
1390	d := f(a, b)
1391	if d != e {
1392		fmt.Printf("For (float32) %v %v %v, expected %v, got %v\n", a, s, b, e, d)
1393	}
1394}
1395
1396func expect64(t *testing.T, s string, x, expected float64) {
1397	if x != expected {
1398		println("F64 Expected", expected, "for", s, ", got", x)
1399	}
1400}
1401
1402func expect32(t *testing.T, s string, x, expected float32) {
1403	if x != expected {
1404		println("F32 Expected", expected, "for", s, ", got", x)
1405	}
1406}
1407
1408func expectUint64(t *testing.T, s string, x, expected uint64) {
1409	if x != expected {
1410		fmt.Printf("U64 Expected 0x%016x for %s, got 0x%016x\n", expected, s, x)
1411	}
1412}
1413
1414func expectInt64(t *testing.T, s string, x, expected int64) {
1415	if x != expected {
1416		fmt.Printf("%s: Expected 0x%016x, got 0x%016x\n", s, expected, x)
1417	}
1418}
1419
1420func expectUint32(t *testing.T, s string, x, expected uint32) {
1421	if x != expected {
1422		fmt.Printf("U32 %s: Expected 0x%08x, got 0x%08x\n", s, expected, x)
1423	}
1424}
1425
1426func expectInt32(t *testing.T, s string, x, expected int32) {
1427	if x != expected {
1428		fmt.Printf("I32 %s: Expected 0x%08x, got 0x%08x\n", s, expected, x)
1429	}
1430}
1431
1432func expectUint16(t *testing.T, s string, x, expected uint16) {
1433	if x != expected {
1434		fmt.Printf("U16 %s: Expected 0x%04x, got 0x%04x\n", s, expected, x)
1435	}
1436}
1437
1438func expectInt16(t *testing.T, s string, x, expected int16) {
1439	if x != expected {
1440		fmt.Printf("I16 %s: Expected 0x%04x, got 0x%04x\n", s, expected, x)
1441	}
1442}
1443
1444func expectAll64(t *testing.T, s string, expected, a, b, c, d, e, f, g, h, i float64) {
1445	expect64(t, s+":a", a, expected)
1446	expect64(t, s+":b", b, expected)
1447	expect64(t, s+":c", c, expected)
1448	expect64(t, s+":d", d, expected)
1449	expect64(t, s+":e", e, expected)
1450	expect64(t, s+":f", f, expected)
1451	expect64(t, s+":g", g, expected)
1452}
1453
1454func expectAll32(t *testing.T, s string, expected, a, b, c, d, e, f, g, h, i float32) {
1455	expect32(t, s+":a", a, expected)
1456	expect32(t, s+":b", b, expected)
1457	expect32(t, s+":c", c, expected)
1458	expect32(t, s+":d", d, expected)
1459	expect32(t, s+":e", e, expected)
1460	expect32(t, s+":f", f, expected)
1461	expect32(t, s+":g", g, expected)
1462}
1463
1464var ev64 [2]float64 = [2]float64{42.0, 17.0}
1465var ev32 [2]float32 = [2]float32{42.0, 17.0}
1466
1467func cmpOpTest(t *testing.T,
1468	s string,
1469	f func(a, b float64) bool,
1470	g func(a, b float64) float64,
1471	ff func(a, b float32) bool,
1472	gg func(a, b float32) float32,
1473	zero, one, inf, nan float64, result uint) {
1474	fail64bool(s, f, zero, zero, result>>16&1 == 1)
1475	fail64bool(s, f, zero, one, result>>12&1 == 1)
1476	fail64bool(s, f, zero, inf, result>>8&1 == 1)
1477	fail64bool(s, f, zero, nan, result>>4&1 == 1)
1478	fail64bool(s, f, nan, nan, result&1 == 1)
1479
1480	fail64(s, g, zero, zero, ev64[result>>16&1])
1481	fail64(s, g, zero, one, ev64[result>>12&1])
1482	fail64(s, g, zero, inf, ev64[result>>8&1])
1483	fail64(s, g, zero, nan, ev64[result>>4&1])
1484	fail64(s, g, nan, nan, ev64[result>>0&1])
1485
1486	{
1487		zero := float32(zero)
1488		one := float32(one)
1489		inf := float32(inf)
1490		nan := float32(nan)
1491		fail32bool(s, ff, zero, zero, (result>>16)&1 == 1)
1492		fail32bool(s, ff, zero, one, (result>>12)&1 == 1)
1493		fail32bool(s, ff, zero, inf, (result>>8)&1 == 1)
1494		fail32bool(s, ff, zero, nan, (result>>4)&1 == 1)
1495		fail32bool(s, ff, nan, nan, result&1 == 1)
1496
1497		fail32(s, gg, zero, zero, ev32[(result>>16)&1])
1498		fail32(s, gg, zero, one, ev32[(result>>12)&1])
1499		fail32(s, gg, zero, inf, ev32[(result>>8)&1])
1500		fail32(s, gg, zero, nan, ev32[(result>>4)&1])
1501		fail32(s, gg, nan, nan, ev32[(result>>0)&1])
1502	}
1503}
1504
1505func expectCx128(t *testing.T, s string, x, expected complex128) {
1506	if x != expected {
1507		t.Errorf("Cx 128 Expected %f for %s, got %f", expected, s, x)
1508	}
1509}
1510
1511func expectCx64(t *testing.T, s string, x, expected complex64) {
1512	if x != expected {
1513		t.Errorf("Cx 64 Expected %f for %s, got %f", expected, s, x)
1514	}
1515}
1516
1517//go:noinline
1518func cx128sum_ssa(a, b complex128) complex128 {
1519	return a + b
1520}
1521
1522//go:noinline
1523func cx128diff_ssa(a, b complex128) complex128 {
1524	return a - b
1525}
1526
1527//go:noinline
1528func cx128prod_ssa(a, b complex128) complex128 {
1529	return a * b
1530}
1531
1532//go:noinline
1533func cx128quot_ssa(a, b complex128) complex128 {
1534	return a / b
1535}
1536
1537//go:noinline
1538func cx128neg_ssa(a complex128) complex128 {
1539	return -a
1540}
1541
1542//go:noinline
1543func cx128real_ssa(a complex128) float64 {
1544	return real(a)
1545}
1546
1547//go:noinline
1548func cx128imag_ssa(a complex128) float64 {
1549	return imag(a)
1550}
1551
1552//go:noinline
1553func cx128cnst_ssa(a complex128) complex128 {
1554	b := 2 + 3i
1555	return a * b
1556}
1557
1558//go:noinline
1559func cx64sum_ssa(a, b complex64) complex64 {
1560	return a + b
1561}
1562
1563//go:noinline
1564func cx64diff_ssa(a, b complex64) complex64 {
1565	return a - b
1566}
1567
1568//go:noinline
1569func cx64prod_ssa(a, b complex64) complex64 {
1570	return a * b
1571}
1572
1573//go:noinline
1574func cx64quot_ssa(a, b complex64) complex64 {
1575	return a / b
1576}
1577
1578//go:noinline
1579func cx64neg_ssa(a complex64) complex64 {
1580	return -a
1581}
1582
1583//go:noinline
1584func cx64real_ssa(a complex64) float32 {
1585	return real(a)
1586}
1587
1588//go:noinline
1589func cx64imag_ssa(a complex64) float32 {
1590	return imag(a)
1591}
1592
1593//go:noinline
1594func cx128eq_ssa(a, b complex128) bool {
1595	return a == b
1596}
1597
1598//go:noinline
1599func cx128ne_ssa(a, b complex128) bool {
1600	return a != b
1601}
1602
1603//go:noinline
1604func cx64eq_ssa(a, b complex64) bool {
1605	return a == b
1606}
1607
1608//go:noinline
1609func cx64ne_ssa(a, b complex64) bool {
1610	return a != b
1611}
1612
1613func expectTrue(t *testing.T, s string, b bool) {
1614	if !b {
1615		t.Errorf("expected true for %s, got false", s)
1616	}
1617}
1618func expectFalse(t *testing.T, s string, b bool) {
1619	if b {
1620		t.Errorf("expected false for %s, got true", s)
1621	}
1622}
1623
1624func complexTest128(t *testing.T) {
1625	var a complex128 = 1 + 2i
1626	var b complex128 = 3 + 6i
1627	sum := cx128sum_ssa(b, a)
1628	diff := cx128diff_ssa(b, a)
1629	prod := cx128prod_ssa(b, a)
1630	quot := cx128quot_ssa(b, a)
1631	neg := cx128neg_ssa(a)
1632	r := cx128real_ssa(a)
1633	i := cx128imag_ssa(a)
1634	cnst := cx128cnst_ssa(a)
1635	c1 := cx128eq_ssa(a, a)
1636	c2 := cx128eq_ssa(a, b)
1637	c3 := cx128ne_ssa(a, a)
1638	c4 := cx128ne_ssa(a, b)
1639
1640	expectCx128(t, "sum", sum, 4+8i)
1641	expectCx128(t, "diff", diff, 2+4i)
1642	expectCx128(t, "prod", prod, -9+12i)
1643	expectCx128(t, "quot", quot, 3+0i)
1644	expectCx128(t, "neg", neg, -1-2i)
1645	expect64(t, "real", r, 1)
1646	expect64(t, "imag", i, 2)
1647	expectCx128(t, "cnst", cnst, -4+7i)
1648	expectTrue(t, fmt.Sprintf("%v==%v", a, a), c1)
1649	expectFalse(t, fmt.Sprintf("%v==%v", a, b), c2)
1650	expectFalse(t, fmt.Sprintf("%v!=%v", a, a), c3)
1651	expectTrue(t, fmt.Sprintf("%v!=%v", a, b), c4)
1652}
1653
1654func complexTest64(t *testing.T) {
1655	var a complex64 = 1 + 2i
1656	var b complex64 = 3 + 6i
1657	sum := cx64sum_ssa(b, a)
1658	diff := cx64diff_ssa(b, a)
1659	prod := cx64prod_ssa(b, a)
1660	quot := cx64quot_ssa(b, a)
1661	neg := cx64neg_ssa(a)
1662	r := cx64real_ssa(a)
1663	i := cx64imag_ssa(a)
1664	c1 := cx64eq_ssa(a, a)
1665	c2 := cx64eq_ssa(a, b)
1666	c3 := cx64ne_ssa(a, a)
1667	c4 := cx64ne_ssa(a, b)
1668
1669	expectCx64(t, "sum", sum, 4+8i)
1670	expectCx64(t, "diff", diff, 2+4i)
1671	expectCx64(t, "prod", prod, -9+12i)
1672	expectCx64(t, "quot", quot, 3+0i)
1673	expectCx64(t, "neg", neg, -1-2i)
1674	expect32(t, "real", r, 1)
1675	expect32(t, "imag", i, 2)
1676	expectTrue(t, fmt.Sprintf("%v==%v", a, a), c1)
1677	expectFalse(t, fmt.Sprintf("%v==%v", a, b), c2)
1678	expectFalse(t, fmt.Sprintf("%v!=%v", a, a), c3)
1679	expectTrue(t, fmt.Sprintf("%v!=%v", a, b), c4)
1680}
1681
1682// TestFP tests that we get the right answer for floating point expressions.
1683func TestFP(t *testing.T) {
1684	a := 3.0
1685	b := 4.0
1686
1687	c := float32(3.0)
1688	d := float32(4.0)
1689
1690	tiny := float32(1.5e-45) // smallest f32 denorm = 2**(-149)
1691	dtiny := float64(tiny)   // well within range of f64
1692
1693	fail64("+", add64_ssa, a, b, 7.0)
1694	fail64("*", mul64_ssa, a, b, 12.0)
1695	fail64("-", sub64_ssa, a, b, -1.0)
1696	fail64("/", div64_ssa, a, b, 0.75)
1697	fail64("neg", neg64_ssa, a, b, -7)
1698
1699	fail32("+", add32_ssa, c, d, 7.0)
1700	fail32("*", mul32_ssa, c, d, 12.0)
1701	fail32("-", sub32_ssa, c, d, -1.0)
1702	fail32("/", div32_ssa, c, d, 0.75)
1703	fail32("neg", neg32_ssa, c, d, -7)
1704
1705	// denorm-squared should underflow to zero.
1706	fail32("*", mul32_ssa, tiny, tiny, 0)
1707
1708	// but should not underflow in float and in fact is exactly representable.
1709	fail64("*", mul64_ssa, dtiny, dtiny, 1.9636373861190906e-90)
1710
1711	// Intended to create register pressure which forces
1712	// asymmetric op into different code paths.
1713	aa, ab, ac, ad, ba, bb, bc, bd, ca, cb, cc, cd, da, db, dc, dd := manysub_ssa(1000.0, 100.0, 10.0, 1.0)
1714
1715	expect64(t, "aa", aa, 11.0)
1716	expect64(t, "ab", ab, 900.0)
1717	expect64(t, "ac", ac, 990.0)
1718	expect64(t, "ad", ad, 999.0)
1719
1720	expect64(t, "ba", ba, -900.0)
1721	expect64(t, "bb", bb, 22.0)
1722	expect64(t, "bc", bc, 90.0)
1723	expect64(t, "bd", bd, 99.0)
1724
1725	expect64(t, "ca", ca, -990.0)
1726	expect64(t, "cb", cb, -90.0)
1727	expect64(t, "cc", cc, 33.0)
1728	expect64(t, "cd", cd, 9.0)
1729
1730	expect64(t, "da", da, -999.0)
1731	expect64(t, "db", db, -99.0)
1732	expect64(t, "dc", dc, -9.0)
1733	expect64(t, "dd", dd, 44.0)
1734
1735	integer2floatConversions(t)
1736
1737	multiplyAdd(t)
1738
1739	var zero64 float64 = 0.0
1740	var one64 float64 = 1.0
1741	var inf64 float64 = 1.0 / zero64
1742	var nan64 float64 = sub64_ssa(inf64, inf64)
1743
1744	cmpOpTest(t, "!=", ne64_ssa, nebr64_ssa, ne32_ssa, nebr32_ssa, zero64, one64, inf64, nan64, 0x01111)
1745	cmpOpTest(t, "==", eq64_ssa, eqbr64_ssa, eq32_ssa, eqbr32_ssa, zero64, one64, inf64, nan64, 0x10000)
1746	cmpOpTest(t, "<=", le64_ssa, lebr64_ssa, le32_ssa, lebr32_ssa, zero64, one64, inf64, nan64, 0x11100)
1747	cmpOpTest(t, "<", lt64_ssa, ltbr64_ssa, lt32_ssa, ltbr32_ssa, zero64, one64, inf64, nan64, 0x01100)
1748	cmpOpTest(t, ">", gt64_ssa, gtbr64_ssa, gt32_ssa, gtbr32_ssa, zero64, one64, inf64, nan64, 0x00000)
1749	cmpOpTest(t, ">=", ge64_ssa, gebr64_ssa, ge32_ssa, gebr32_ssa, zero64, one64, inf64, nan64, 0x10000)
1750
1751	{
1752		lt, le, eq, ne, ge, gt := compares64_ssa(0.0, 1.0, inf64, nan64)
1753		expectUint64(t, "lt", lt, 0x0110001000000000)
1754		expectUint64(t, "le", le, 0x1110011000100000)
1755		expectUint64(t, "eq", eq, 0x1000010000100000)
1756		expectUint64(t, "ne", ne, 0x0111101111011111)
1757		expectUint64(t, "ge", ge, 0x1000110011100000)
1758		expectUint64(t, "gt", gt, 0x0000100011000000)
1759		// fmt.Printf("lt=0x%016x, le=0x%016x, eq=0x%016x, ne=0x%016x, ge=0x%016x, gt=0x%016x\n",
1760		// 	lt, le, eq, ne, ge, gt)
1761	}
1762	{
1763		lt, le, eq, ne, ge, gt := compares32_ssa(0.0, 1.0, float32(inf64), float32(nan64))
1764		expectUint64(t, "lt", lt, 0x0110001000000000)
1765		expectUint64(t, "le", le, 0x1110011000100000)
1766		expectUint64(t, "eq", eq, 0x1000010000100000)
1767		expectUint64(t, "ne", ne, 0x0111101111011111)
1768		expectUint64(t, "ge", ge, 0x1000110011100000)
1769		expectUint64(t, "gt", gt, 0x0000100011000000)
1770	}
1771
1772	floatingToIntegerConversionsTest(t)
1773	complexTest128(t)
1774	complexTest64(t)
1775}
1776