-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
go/ssa/interp: implement min/max builtins
Updates golang/go#59488. Change-Id: I68c90ddf0f9dea2c6506b9ab43beb522cbdf5fdd Reviewed-on: https://go-review.googlesource.com/c/tools/+/497516 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> gopls-CI: kokoro <noreply+kokoro@google.com> Reviewed-by: Tim King <taking@google.com>
- Loading branch information
Showing
5 changed files
with
228 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
// Copyright 2023 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
//go:build go1.21 | ||
// +build go1.21 | ||
|
||
package interp_test | ||
|
||
func init() { | ||
testdataTests = append(testdataTests, "minmax.go") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
// Copyright 2023 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package main | ||
|
||
import ( | ||
"fmt" | ||
"math" | ||
) | ||
|
||
func main() { | ||
TestMinFloat() | ||
TestMaxFloat() | ||
TestMinMaxInt() | ||
TestMinMaxUint8() | ||
TestMinMaxString() | ||
} | ||
|
||
func errorf(format string, args ...any) { panic(fmt.Sprintf(format, args...)) } | ||
func fatalf(format string, args ...any) { panic(fmt.Sprintf(format, args...)) } | ||
|
||
// derived from $GOROOT/src/runtime/minmax_test.go | ||
|
||
var ( | ||
zero = math.Copysign(0, +1) | ||
negZero = math.Copysign(0, -1) | ||
inf = math.Inf(+1) | ||
negInf = math.Inf(-1) | ||
nan = math.NaN() | ||
) | ||
|
||
var tests = []struct{ min, max float64 }{ | ||
{1, 2}, | ||
{-2, 1}, | ||
{negZero, zero}, | ||
{zero, inf}, | ||
{negInf, zero}, | ||
{negInf, inf}, | ||
{1, inf}, | ||
{negInf, 1}, | ||
} | ||
|
||
var all = []float64{1, 2, -1, -2, zero, negZero, inf, negInf, nan} | ||
|
||
func eq(x, y float64) bool { | ||
return x == y && math.Signbit(x) == math.Signbit(y) | ||
} | ||
|
||
func TestMinFloat() { | ||
for _, tt := range tests { | ||
if z := min(tt.min, tt.max); !eq(z, tt.min) { | ||
errorf("min(%v, %v) = %v, want %v", tt.min, tt.max, z, tt.min) | ||
} | ||
if z := min(tt.max, tt.min); !eq(z, tt.min) { | ||
errorf("min(%v, %v) = %v, want %v", tt.max, tt.min, z, tt.min) | ||
} | ||
} | ||
for _, x := range all { | ||
if z := min(nan, x); !math.IsNaN(z) { | ||
errorf("min(%v, %v) = %v, want %v", nan, x, z, nan) | ||
} | ||
if z := min(x, nan); !math.IsNaN(z) { | ||
errorf("min(%v, %v) = %v, want %v", nan, x, z, nan) | ||
} | ||
} | ||
} | ||
|
||
func TestMaxFloat() { | ||
for _, tt := range tests { | ||
if z := max(tt.min, tt.max); !eq(z, tt.max) { | ||
errorf("max(%v, %v) = %v, want %v", tt.min, tt.max, z, tt.max) | ||
} | ||
if z := max(tt.max, tt.min); !eq(z, tt.max) { | ||
errorf("max(%v, %v) = %v, want %v", tt.max, tt.min, z, tt.max) | ||
} | ||
} | ||
for _, x := range all { | ||
if z := max(nan, x); !math.IsNaN(z) { | ||
errorf("min(%v, %v) = %v, want %v", nan, x, z, nan) | ||
} | ||
if z := max(x, nan); !math.IsNaN(z) { | ||
errorf("min(%v, %v) = %v, want %v", nan, x, z, nan) | ||
} | ||
} | ||
} | ||
|
||
// testMinMax tests that min/max behave correctly on every pair of | ||
// values in vals. | ||
// | ||
// vals should be a sequence of values in strictly ascending order. | ||
func testMinMax[T int | uint8 | string](vals ...T) { | ||
for i, x := range vals { | ||
for _, y := range vals[i+1:] { | ||
if !(x < y) { | ||
fatalf("values out of order: !(%v < %v)", x, y) | ||
} | ||
|
||
if z := min(x, y); z != x { | ||
errorf("min(%v, %v) = %v, want %v", x, y, z, x) | ||
} | ||
if z := min(y, x); z != x { | ||
errorf("min(%v, %v) = %v, want %v", y, x, z, x) | ||
} | ||
|
||
if z := max(x, y); z != y { | ||
errorf("max(%v, %v) = %v, want %v", x, y, z, y) | ||
} | ||
if z := max(y, x); z != y { | ||
errorf("max(%v, %v) = %v, want %v", y, x, z, y) | ||
} | ||
} | ||
} | ||
} | ||
|
||
func TestMinMaxInt() { testMinMax[int](-7, 0, 9) } | ||
func TestMinMaxUint8() { testMinMax[uint8](0, 1, 2, 4, 7) } | ||
func TestMinMaxString() { testMinMax[string]("a", "b", "c") } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
package math | ||
|
||
func Copysign(float64, float64) float64 | ||
|
||
func NaN() float64 | ||
|
||
func Inf(int) float64 | ||
|