]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: teach prove about relations between constants
authorAustin Clements <austin@google.com>
Fri, 23 Mar 2018 21:21:33 +0000 (17:21 -0400)
committerAustin Clements <austin@google.com>
Tue, 22 May 2018 14:15:42 +0000 (14:15 +0000)
Currently, we never add a relation between two constants to prove's
fact table because these are eliminated before prove runs, so it
currently doesn't handle facts like this very well even though they're
easy to prove.

We're about to start asserting some conditions that don't appear in
the SSA, but are constructed from existing SSA values that may both be
constants.

Hence, improve the fact table to understand relations between
constants by initializing the constant bounds of constant values to
the value itself, rather than noLimit.

Passes toolstash -cmp.

Change-Id: I71f8dc294e59f19433feab1c10b6d3c99b7f1e26
Reviewed-on: https://go-review.googlesource.com/102601
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/internal/ssa/prove.go

index 8e248340880b30c7e0f594e13661568f07e95dd9..b0abe7ce7de113391d7f7b7900d4c7a3717ca2df 100644 (file)
@@ -279,6 +279,21 @@ func (ft *factsTable) update(parent *Block, v, w *Value, d domain, r relation) {
                old, ok := ft.limits[v.ID]
                if !ok {
                        old = noLimit
+                       if v.isGenericIntConst() {
+                               switch d {
+                               case signed:
+                                       old.min, old.max = v.AuxInt, v.AuxInt
+                                       if v.AuxInt >= 0 {
+                                               old.umin, old.umax = uint64(v.AuxInt), uint64(v.AuxInt)
+                                       }
+                               case unsigned:
+                                       old.umin = v.AuxUnsigned()
+                                       old.umax = old.umin
+                                       if int64(old.umin) >= 0 {
+                                               old.min, old.max = int64(old.umin), int64(old.umin)
+                                       }
+                               }
+                       }
                }
                lim := noLimit
                switch d {