Skip to content

Commit d574856

Browse files
Jorropogopherbot
authored andcommitted
cmd/compile: learn transitive proofs for safe negative signed adds
I've split this into it's own CL to make git bisect more effective. Change-Id: Ib2c6dbc82fb04f50f2d17fbe6626c9fc322fb478 Reviewed-on: https://go-review.googlesource.com/c/go/+/685820 Auto-Submit: Michael Knyszek <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Keith Randall <[email protected]> Reviewed-by: Keith Randall <[email protected]> Reviewed-by: Michael Knyszek <[email protected]>
1 parent 1a72920 commit d574856

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed

src/cmd/compile/internal/ssa/prove.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2212,6 +2212,20 @@ func addLocalFacts(ft *factsTable, b *Block) {
22122212
}
22132213
ft.update(b, v, v.Args[0], signed, r)
22142214
}
2215+
if x.max <= 0 && !signedAddOverflowsOrUnderflows(x.min, y.min, v.Type) {
2216+
r := lt
2217+
if !x.nonzero() {
2218+
r |= eq
2219+
}
2220+
ft.update(b, v, v.Args[1], signed, r)
2221+
}
2222+
if y.max <= 0 && !signedAddOverflowsOrUnderflows(x.min, y.min, v.Type) {
2223+
r := lt
2224+
if !y.nonzero() {
2225+
r |= eq
2226+
}
2227+
ft.update(b, v, v.Args[0], signed, r)
2228+
}
22152229
case OpAnd64, OpAnd32, OpAnd16, OpAnd8:
22162230
ft.update(b, v, v.Args[0], unsigned, lt|eq)
22172231
ft.update(b, v, v.Args[1], unsigned, lt|eq)

test/prove.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2171,6 +2171,76 @@ func transitiveProofsThroughOverflowingSignedAddPositive(x, y, z int64) {
21712171
}
21722172
}
21732173

2174+
func transitiveProofsThroughNonOverflowingSignedAddNegative(x, y, z int64) {
2175+
if x < math.MinInt64>>1 || x > 0 ||
2176+
y < math.MinInt64>>1 || y > 0 {
2177+
return
2178+
}
2179+
2180+
a := x + y
2181+
if a < z {
2182+
return
2183+
}
2184+
2185+
if x < z { // ERROR "Disproved Less64$"
2186+
return
2187+
}
2188+
if y < z { // ERROR "Disproved Less64$"
2189+
return
2190+
}
2191+
if a == x {
2192+
return
2193+
}
2194+
if a == y {
2195+
return
2196+
}
2197+
2198+
if x == 0 && y == 0 {
2199+
return
2200+
}
2201+
a = x + y
2202+
if a == x { // ERROR "Disproved Eq64$"
2203+
return
2204+
}
2205+
if a == y { // ERROR "Disproved Eq64$"
2206+
return
2207+
}
2208+
}
2209+
2210+
func transitiveProofsThroughOverflowingSignedAddNegative(x, y, z int64) {
2211+
if x >= 0 || y >= 0 {
2212+
return
2213+
}
2214+
2215+
a := x + y
2216+
if a < z {
2217+
return
2218+
}
2219+
2220+
if x < z {
2221+
return
2222+
}
2223+
if y < z {
2224+
return
2225+
}
2226+
if a == x {
2227+
return
2228+
}
2229+
if a == y {
2230+
return
2231+
}
2232+
2233+
x |= 1
2234+
y |= 1
2235+
a = x + y
2236+
if a == x {
2237+
return
2238+
}
2239+
if a == y {
2240+
return
2241+
}
2242+
}
2243+
21742244
//go:noinline
21752245
func useInt(a int) {
21762246
}

0 commit comments

Comments
 (0)