cmd/compile: Eliminate bound checks on access to positive modulo #38476
Comments
Can you please post a complete snippet that actually compiles? |
package main
func test1(foo []byte) {
// _ = foo[0]
rem := len(foo) % 64
_ = foo[:rem] // I originally put _ = foo[rem] which is wrong as rem==len(foo) is possible
}
func test2(foo []byte) {
_ = foo[63]
rem := len(foo) % 64
_ = foo[rem]
}
func main(){} Running
The checks on line 4 and 10 are expected, but line 6 and 12 should be eliminated |
@cbeuw if len(foo) == 0, then rem is 0, so |
@cuonglm That's correct, which is why |
@cuonglm Actually there is a +-1 error in the first case, because it's possible |
The complication with the general case of proving that r := x%m && m > 0 --> 0 <= r < m Is that by the time prove runs, the modulus for constant x%C => x-(x/C*C) However, for the specific case above where r := x&m && m >= 0 --> 0 <= r <= m
|
I think this may not quite be a duplicate, but requires the same or similar solution as #29872. We talked there of delaying div reduction to only the lateopt pass. This would leave the mods in place for the prove pass to see. |
Given something in the form
The compiler currently (1.14) inserts a bound check on
foo[:rem]
, but0 <= rem <= len(foo)
is guaranteed sincerem
is the modulo of a positive integer.It would be even nicer if the compiler can figure out the general form
x > 0 ∧ r = x % m ⇒ 0 ≤ r < m
, so that operations likecan have the bound check eliminated too.
This sort of expression usually props up when dealing with block-oriented algorithms, such as ciphers:
https://github.com/golang/crypto/blob/0848c9571904fcbcb24543358ca8b5a7dbfde875/chacha20/chacha_generic.go#L213
https://github.com/golang/crypto/blob/0848c9571904fcbcb24543358ca8b5a7dbfde875/poly1305/sum_amd64.go#L42
The text was updated successfully, but these errors were encountered: