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]
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) {
}