From: Jorropo Date: Wed, 14 Aug 2024 20:28:00 +0000 (+0200) Subject: cmd/compile: compute Complement's limits from argument's limits X-Git-Tag: go1.24rc1~1040 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=2f3165973f9bf1e1a95d108c57e5257f4655ee59;p=gostls13.git cmd/compile: compute Complement's limits from argument's limits I was not sure this was correct so I exhaustively checked all possibilities: https://go.dev/play/p/hjmCLm4Iagz https://go.dev/play/p/R9RuRGKwCbN Change-Id: I85f053df825a4d77f978de42f8a1fcaf4b881def Reviewed-on: https://go-review.googlesource.com/c/go/+/605696 Reviewed-by: Keith Randall LUCI-TryBot-Result: Go LUCI Reviewed-by: David Chase Reviewed-by: Keith Randall Reviewed-by: Carlos Amedee --- diff --git a/src/cmd/compile/internal/ssa/prove.go b/src/cmd/compile/internal/ssa/prove.go index 8a351545c9..db0ad97ad0 100644 --- a/src/cmd/compile/internal/ssa/prove.go +++ b/src/cmd/compile/internal/ssa/prove.go @@ -341,6 +341,42 @@ func (l limit) exp2(b uint) limit { return r } +// Similar to add, but computes the complement of the limit for bitsize b. +func (l limit) com(b uint) limit { + switch b { + case 64: + return limit{ + min: ^l.max, + max: ^l.min, + umin: ^l.umax, + umax: ^l.umin, + } + case 32: + return limit{ + min: int64(^int32(l.max)), + max: int64(^int32(l.min)), + umin: uint64(^uint32(l.umax)), + umax: uint64(^uint32(l.umin)), + } + case 16: + return limit{ + min: int64(^int16(l.max)), + max: int64(^int16(l.min)), + umin: uint64(^uint16(l.umax)), + umax: uint64(^uint16(l.umin)), + } + case 8: + return limit{ + min: int64(^int8(l.max)), + max: int64(^int8(l.min)), + umin: uint64(^uint8(l.umax)), + umax: uint64(^uint8(l.umin)), + } + default: + panic("unreachable") + } +} + var noLimit = limit{math.MinInt64, math.MaxInt64, 0, math.MaxUint64} // a limitFact is a limit known for a particular value. @@ -1714,6 +1750,9 @@ func (ft *factsTable) flowLimit(v *Value) bool { a := ft.limits[v.Args[0].ID] b := ft.limits[v.Args[1].ID] return ft.unsignedMax(v, 1< ^uint64(0xff) { // ERROR "Disproved Less64U$" + return 42 + } + if ensureAllBranchesCouldHappen() && z <= ^uint64(0xff) { // ERROR "Proved Leq64U$" + return 1337 + } + if ensureAllBranchesCouldHappen() && z < ^uint64(0xffff) { // ERROR "Disproved Less64U$" + return 42 + } + if ensureAllBranchesCouldHappen() && z >= ^uint64(0xffff) { // ERROR "Proved Leq64U$" + return 1337 + } + return z +} + //go:noinline func useInt(a int) { }