]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: compute OR's maximum limits from argument's limits
authorJorropo <jorropo.pgm@gmail.com>
Fri, 9 Aug 2024 14:35:46 +0000 (16:35 +0200)
committerKeith Randall <khr@golang.org>
Tue, 3 Sep 2024 17:12:58 +0000 (17:12 +0000)
Change-Id: I6902c405cab7bd573f6a721a6ca7c783713ea39a
Reviewed-on: https://go-review.googlesource.com/c/go/+/604456
Reviewed-by: Keith Randall <khr@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/ssa/prove.go
test/prove.go

index 5195a486080c2c7d69171ccacd18c90e055b665d..807f198787529531c1ff1274f714d19938ff8292 100644 (file)
@@ -1698,10 +1698,12 @@ func (ft *factsTable) flowLimit(v *Value) bool {
                b := ft.limits[v.Args[1].ID]
                return ft.unsignedMax(v, minU(a.umax, b.umax))
        case OpOr64, OpOr32, OpOr16, OpOr8:
-               // OR can only make the value bigger.
+               // OR can only make the value bigger and can't flip bits proved to be zero in both inputs.
                a := ft.limits[v.Args[0].ID]
                b := ft.limits[v.Args[1].ID]
-               return ft.unsignedMin(v, maxU(a.umin, b.umin))
+               return ft.unsignedMinMax(v,
+                       maxU(a.umin, b.umin),
+                       1<<bits.Len64(a.umax|b.umax)-1)
        case OpXor64, OpXor32, OpXor16, OpXor8:
                // XOR can't flip bits that are proved to be zero in both inputs.
                a := ft.limits[v.Args[0].ID]
index 2d5d181aa951aaea22d67a84f3f0fb53179363e9..8e654044315b9f43407f2fec5d65a97322e0fccb 100644 (file)
@@ -1408,6 +1408,24 @@ func xor64(a, b uint64, ensureBothBranchesCouldHappen bool) int {
        return int(z)
 }
 
+func or64(a, b uint64, ensureBothBranchesCouldHappen bool) int {
+       a &= 0xff
+       b &= 0xfff
+
+       z := a | b
+
+       if ensureBothBranchesCouldHappen {
+               if z > 0xfff { // ERROR "Disproved Less64U$"
+                       return 42
+               }
+       } else {
+               if z <= 0xfff { // ERROR "Proved Leq64U$"
+                       return 1337
+               }
+       }
+       return int(z)
+}
+
 //go:noinline
 func useInt(a int) {
 }