Source file src/cmd/compile/internal/test/testdata/fp_test.go

     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  
     7  package main
     8  
     9  import (
    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
    19  func 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
    43  func 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
    86  func add64_ssa(a, b float64) float64 {
    87  	return a + b
    88  }
    89  
    90  //go:noinline
    91  func mul64_ssa(a, b float64) float64 {
    92  	return a * b
    93  }
    94  
    95  //go:noinline
    96  func sub64_ssa(a, b float64) float64 {
    97  	return a - b
    98  }
    99  
   100  //go:noinline
   101  func div64_ssa(a, b float64) float64 {
   102  	return a / b
   103  }
   104  
   105  //go:noinline
   106  func neg64_ssa(a, b float64) float64 {
   107  	return -a + -1*b
   108  }
   109  
   110  //go:noinline
   111  func add32_ssa(a, b float32) float32 {
   112  	return a + b
   113  }
   114  
   115  //go:noinline
   116  func mul32_ssa(a, b float32) float32 {
   117  	return a * b
   118  }
   119  
   120  //go:noinline
   121  func sub32_ssa(a, b float32) float32 {
   122  	return a - b
   123  }
   124  
   125  //go:noinline
   126  func div32_ssa(a, b float32) float32 {
   127  	return a / b
   128  }
   129  
   130  //go:noinline
   131  func neg32_ssa(a, b float32) float32 {
   132  	return -a + -1*b
   133  }
   134  
   135  //go:noinline
   136  func 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
   151  func 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  
   165  func 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  
   236  func 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  
   363  const (
   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
   383  func 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
   700  func 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
  1017  func le64_ssa(x, y float64) bool {
  1018  	return x <= y
  1019  }
  1020  
  1021  //go:noinline
  1022  func ge64_ssa(x, y float64) bool {
  1023  	return x >= y
  1024  }
  1025  
  1026  //go:noinline
  1027  func lt64_ssa(x, y float64) bool {
  1028  	return x < y
  1029  }
  1030  
  1031  //go:noinline
  1032  func gt64_ssa(x, y float64) bool {
  1033  	return x > y
  1034  }
  1035  
  1036  //go:noinline
  1037  func eq64_ssa(x, y float64) bool {
  1038  	return x == y
  1039  }
  1040  
  1041  //go:noinline
  1042  func ne64_ssa(x, y float64) bool {
  1043  	return x != y
  1044  }
  1045  
  1046  //go:noinline
  1047  func eqbr64_ssa(x, y float64) float64 {
  1048  	if x == y {
  1049  		return 17
  1050  	}
  1051  	return 42
  1052  }
  1053  
  1054  //go:noinline
  1055  func nebr64_ssa(x, y float64) float64 {
  1056  	if x != y {
  1057  		return 17
  1058  	}
  1059  	return 42
  1060  }
  1061  
  1062  //go:noinline
  1063  func gebr64_ssa(x, y float64) float64 {
  1064  	if x >= y {
  1065  		return 17
  1066  	}
  1067  	return 42
  1068  }
  1069  
  1070  //go:noinline
  1071  func lebr64_ssa(x, y float64) float64 {
  1072  	if x <= y {
  1073  		return 17
  1074  	}
  1075  	return 42
  1076  }
  1077  
  1078  //go:noinline
  1079  func ltbr64_ssa(x, y float64) float64 {
  1080  	if x < y {
  1081  		return 17
  1082  	}
  1083  	return 42
  1084  }
  1085  
  1086  //go:noinline
  1087  func gtbr64_ssa(x, y float64) float64 {
  1088  	if x > y {
  1089  		return 17
  1090  	}
  1091  	return 42
  1092  }
  1093  
  1094  //go:noinline
  1095  func le32_ssa(x, y float32) bool {
  1096  	return x <= y
  1097  }
  1098  
  1099  //go:noinline
  1100  func ge32_ssa(x, y float32) bool {
  1101  	return x >= y
  1102  }
  1103  
  1104  //go:noinline
  1105  func lt32_ssa(x, y float32) bool {
  1106  	return x < y
  1107  }
  1108  
  1109  //go:noinline
  1110  func gt32_ssa(x, y float32) bool {
  1111  	return x > y
  1112  }
  1113  
  1114  //go:noinline
  1115  func eq32_ssa(x, y float32) bool {
  1116  	return x == y
  1117  }
  1118  
  1119  //go:noinline
  1120  func ne32_ssa(x, y float32) bool {
  1121  	return x != y
  1122  }
  1123  
  1124  //go:noinline
  1125  func eqbr32_ssa(x, y float32) float32 {
  1126  	if x == y {
  1127  		return 17
  1128  	}
  1129  	return 42
  1130  }
  1131  
  1132  //go:noinline
  1133  func nebr32_ssa(x, y float32) float32 {
  1134  	if x != y {
  1135  		return 17
  1136  	}
  1137  	return 42
  1138  }
  1139  
  1140  //go:noinline
  1141  func gebr32_ssa(x, y float32) float32 {
  1142  	if x >= y {
  1143  		return 17
  1144  	}
  1145  	return 42
  1146  }
  1147  
  1148  //go:noinline
  1149  func lebr32_ssa(x, y float32) float32 {
  1150  	if x <= y {
  1151  		return 17
  1152  	}
  1153  	return 42
  1154  }
  1155  
  1156  //go:noinline
  1157  func ltbr32_ssa(x, y float32) float32 {
  1158  	if x < y {
  1159  		return 17
  1160  	}
  1161  	return 42
  1162  }
  1163  
  1164  //go:noinline
  1165  func gtbr32_ssa(x, y float32) float32 {
  1166  	if x > y {
  1167  		return 17
  1168  	}
  1169  	return 42
  1170  }
  1171  
  1172  //go:noinline
  1173  func F32toU8_ssa(x float32) uint8 {
  1174  	return uint8(x)
  1175  }
  1176  
  1177  //go:noinline
  1178  func F32toI8_ssa(x float32) int8 {
  1179  	return int8(x)
  1180  }
  1181  
  1182  //go:noinline
  1183  func F32toU16_ssa(x float32) uint16 {
  1184  	return uint16(x)
  1185  }
  1186  
  1187  //go:noinline
  1188  func F32toI16_ssa(x float32) int16 {
  1189  	return int16(x)
  1190  }
  1191  
  1192  //go:noinline
  1193  func F32toU32_ssa(x float32) uint32 {
  1194  	return uint32(x)
  1195  }
  1196  
  1197  //go:noinline
  1198  func F32toI32_ssa(x float32) int32 {
  1199  	return int32(x)
  1200  }
  1201  
  1202  //go:noinline
  1203  func F32toU64_ssa(x float32) uint64 {
  1204  	return uint64(x)
  1205  }
  1206  
  1207  //go:noinline
  1208  func F32toI64_ssa(x float32) int64 {
  1209  	return int64(x)
  1210  }
  1211  
  1212  //go:noinline
  1213  func F64toU8_ssa(x float64) uint8 {
  1214  	return uint8(x)
  1215  }
  1216  
  1217  //go:noinline
  1218  func F64toI8_ssa(x float64) int8 {
  1219  	return int8(x)
  1220  }
  1221  
  1222  //go:noinline
  1223  func F64toU16_ssa(x float64) uint16 {
  1224  	return uint16(x)
  1225  }
  1226  
  1227  //go:noinline
  1228  func F64toI16_ssa(x float64) int16 {
  1229  	return int16(x)
  1230  }
  1231  
  1232  //go:noinline
  1233  func F64toU32_ssa(x float64) uint32 {
  1234  	return uint32(x)
  1235  }
  1236  
  1237  //go:noinline
  1238  func F64toI32_ssa(x float64) int32 {
  1239  	return int32(x)
  1240  }
  1241  
  1242  //go:noinline
  1243  func F64toU64_ssa(x float64) uint64 {
  1244  	return uint64(x)
  1245  }
  1246  
  1247  //go:noinline
  1248  func F64toI64_ssa(x float64) int64 {
  1249  	return int64(x)
  1250  }
  1251  
  1252  func 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  
  1264  func 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  
  1276  func 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  
  1368  func 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  
  1375  func 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  
  1382  func 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  
  1389  func 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  
  1396  func 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  
  1402  func 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  
  1408  func 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  
  1414  func 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  
  1420  func 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  
  1426  func 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  
  1432  func 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  
  1438  func 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  
  1444  func 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  
  1454  func 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  
  1464  var ev64 [2]float64 = [2]float64{42.0, 17.0}
  1465  var ev32 [2]float32 = [2]float32{42.0, 17.0}
  1466  
  1467  func 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  
  1505  func 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  
  1511  func 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
  1518  func cx128sum_ssa(a, b complex128) complex128 {
  1519  	return a + b
  1520  }
  1521  
  1522  //go:noinline
  1523  func cx128diff_ssa(a, b complex128) complex128 {
  1524  	return a - b
  1525  }
  1526  
  1527  //go:noinline
  1528  func cx128prod_ssa(a, b complex128) complex128 {
  1529  	return a * b
  1530  }
  1531  
  1532  //go:noinline
  1533  func cx128quot_ssa(a, b complex128) complex128 {
  1534  	return a / b
  1535  }
  1536  
  1537  //go:noinline
  1538  func cx128neg_ssa(a complex128) complex128 {
  1539  	return -a
  1540  }
  1541  
  1542  //go:noinline
  1543  func cx128real_ssa(a complex128) float64 {
  1544  	return real(a)
  1545  }
  1546  
  1547  //go:noinline
  1548  func cx128imag_ssa(a complex128) float64 {
  1549  	return imag(a)
  1550  }
  1551  
  1552  //go:noinline
  1553  func cx128cnst_ssa(a complex128) complex128 {
  1554  	b := 2 + 3i
  1555  	return a * b
  1556  }
  1557  
  1558  //go:noinline
  1559  func cx64sum_ssa(a, b complex64) complex64 {
  1560  	return a + b
  1561  }
  1562  
  1563  //go:noinline
  1564  func cx64diff_ssa(a, b complex64) complex64 {
  1565  	return a - b
  1566  }
  1567  
  1568  //go:noinline
  1569  func cx64prod_ssa(a, b complex64) complex64 {
  1570  	return a * b
  1571  }
  1572  
  1573  //go:noinline
  1574  func cx64quot_ssa(a, b complex64) complex64 {
  1575  	return a / b
  1576  }
  1577  
  1578  //go:noinline
  1579  func cx64neg_ssa(a complex64) complex64 {
  1580  	return -a
  1581  }
  1582  
  1583  //go:noinline
  1584  func cx64real_ssa(a complex64) float32 {
  1585  	return real(a)
  1586  }
  1587  
  1588  //go:noinline
  1589  func cx64imag_ssa(a complex64) float32 {
  1590  	return imag(a)
  1591  }
  1592  
  1593  //go:noinline
  1594  func cx128eq_ssa(a, b complex128) bool {
  1595  	return a == b
  1596  }
  1597  
  1598  //go:noinline
  1599  func cx128ne_ssa(a, b complex128) bool {
  1600  	return a != b
  1601  }
  1602  
  1603  //go:noinline
  1604  func cx64eq_ssa(a, b complex64) bool {
  1605  	return a == b
  1606  }
  1607  
  1608  //go:noinline
  1609  func cx64ne_ssa(a, b complex64) bool {
  1610  	return a != b
  1611  }
  1612  
  1613  func expectTrue(t *testing.T, s string, b bool) {
  1614  	if !b {
  1615  		t.Errorf("expected true for %s, got false", s)
  1616  	}
  1617  }
  1618  func expectFalse(t *testing.T, s string, b bool) {
  1619  	if b {
  1620  		t.Errorf("expected false for %s, got true", s)
  1621  	}
  1622  }
  1623  
  1624  func 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  
  1654  func 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.
  1683  func 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  

View as plain text