Skip to content

Commit 2e9cf5f

Browse files
committed
cmd/compile: simplify limit logic in prove
This replaces the open-coded intersection of limits in the prove pass with a general limit intersection operation. This should get identical results except in one case where it's more precise: when handling an equality relation, if the value is *outside* the existing range, this will reduce the range to empty rather than resetting it. This will be important to a follow-up CL where we can take advantage of empty ranges. For #23354. Change-Id: I3d3d75924f61b1da1cb604b3a9d189b26fb3a14e Reviewed-on: https://go-review.googlesource.com/87477 Run-TryBot: Austin Clements <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Keith Randall <[email protected]> Reviewed-by: Alexandru Moșoi <[email protected]>
1 parent 44e20b6 commit 2e9cf5f

File tree

1 file changed

+28
-26
lines changed

1 file changed

+28
-26
lines changed

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

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,22 @@ func (l limit) String() string {
117117
return fmt.Sprintf("sm,SM,um,UM=%d,%d,%d,%d", l.min, l.max, l.umin, l.umax)
118118
}
119119

120+
func (l limit) intersect(l2 limit) limit {
121+
if l.min < l2.min {
122+
l.min = l2.min
123+
}
124+
if l.umin < l2.umin {
125+
l.umin = l2.umin
126+
}
127+
if l.max > l2.max {
128+
l.max = l2.max
129+
}
130+
if l.umax > l2.umax {
131+
l.umax = l2.umax
132+
}
133+
return l
134+
}
135+
120136
var noLimit = limit{math.MinInt64, math.MaxInt64, 0, math.MaxUint64}
121137

122138
// a limitFact is a limit known for a particular value.
@@ -273,28 +289,20 @@ func (ft *factsTable) update(parent *Block, v, w *Value, d domain, r relation) {
273289
if !ok {
274290
old = noLimit
275291
}
276-
lim := old
277-
// Update lim with the new information we know.
292+
lim := noLimit
278293
switch d {
279294
case signed:
280295
switch r {
281296
case lt:
282-
if c-1 < lim.max {
283-
lim.max = c - 1
284-
}
297+
lim.max = c - 1
285298
case lt | eq:
286-
if c < lim.max {
287-
lim.max = c
288-
}
299+
lim.max = c
289300
case gt | eq:
290-
if c > lim.min {
291-
lim.min = c
292-
}
301+
lim.min = c
293302
case gt:
294-
if c+1 > lim.min {
295-
lim.min = c + 1
296-
}
303+
lim.min = c + 1
297304
case lt | gt:
305+
lim = old
298306
if c == lim.min {
299307
lim.min++
300308
}
@@ -319,22 +327,15 @@ func (ft *factsTable) update(parent *Block, v, w *Value, d domain, r relation) {
319327
}
320328
switch r {
321329
case lt:
322-
if uc-1 < lim.umax {
323-
lim.umax = uc - 1
324-
}
330+
lim.umax = uc - 1
325331
case lt | eq:
326-
if uc < lim.umax {
327-
lim.umax = uc
328-
}
332+
lim.umax = uc
329333
case gt | eq:
330-
if uc > lim.umin {
331-
lim.umin = uc
332-
}
334+
lim.umin = uc
333335
case gt:
334-
if uc+1 > lim.umin {
335-
lim.umin = uc + 1
336-
}
336+
lim.umin = uc + 1
337337
case lt | gt:
338+
lim = old
338339
if uc == lim.umin {
339340
lim.umin++
340341
}
@@ -347,6 +348,7 @@ func (ft *factsTable) update(parent *Block, v, w *Value, d domain, r relation) {
347348
}
348349
}
349350
ft.limitStack = append(ft.limitStack, limitFact{v.ID, old})
351+
lim = old.intersect(lim)
350352
ft.limits[v.ID] = lim
351353
if v.Block.Func.pass.debug > 2 {
352354
v.Block.Func.Warnl(parent.Pos, "parent=%s, new limits %s %s %s", parent, v, w, lim.String())

0 commit comments

Comments
 (0)