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