| // run | |
| // 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. | |
| // Comparing a wrapped product difference against zero must respect the | |
| // sign of the wrapped value, even when it wraps to MinInt. | |
| package main | |
| import "fmt" | |
| // int64 (not int) so the cross product is 64-bit on every GOARCH. | |
| type point struct{ x, y int64 } | |
| //go:noinline | |
| func sign(p1, p2, p3 point) bool { | |
| return (p1.x-p3.x)*(p2.y-p3.y)-(p2.x-p3.x)*(p1.y-p3.y) < 0 | |
| } | |
| type point32 struct{ x, y int32 } | |
| //go:noinline | |
| func sign32(p1, p2, p3 point32) bool { | |
| if (p1.x-p3.x)*(p2.y-p3.y)-(p2.x-p3.x)*(p1.y-p3.y) < 0 { | |
| return true | |
| } | |
| return false | |
| } | |
| const minInt64 = -1 << 63 | |
| //go:noinline | |
| func msub64(x, y int64) bool { | |
| if minInt64-x*y < 0 { | |
| return true | |
| } | |
| return false | |
| } | |
| const minInt32 = -1 << 31 | |
| //go:noinline | |
| func msub32(x, y int32) bool { | |
| if minInt32-x*y < 0 { | |
| return true | |
| } | |
| return false | |
| } | |
| const minUint32 = uint32(1 << 31) | |
| //go:noinline | |
| func umod32(y uint32) bool { | |
| if int32(minUint32%y) < 0 { | |
| return true | |
| } | |
| return false | |
| } | |
| func main() { | |
| var bad bool | |
| check := func(name string, got, want bool) { | |
| if got != want { | |
| fmt.Printf("%s = %v, want %v\n", name, got, want) | |
| bad = true | |
| } | |
| } | |
| check("sign", sign(point{0, 2}, point{1 << 62, 0}, point{0, 0}), true) // wraps to MinInt64 | |
| check("sign32", sign32(point32{0, 2}, point32{1 << 30, 0}, point32{0, 0}), true) // wraps to MinInt32 | |
| check("msub64", msub64(0, 123), true) // minInt64 - 0 | |
| check("msub32", msub32(0, 123), true) // minInt32 - 0 | |
| check("umod32", umod32(0xffffffff), true) // minUint32 % big == minUint32 | |
| if bad { | |
| panic("InvertFlags noov MinInt miscompilation") | |
| } | |
| } |