On Go 1.8, version A is 25% slower faster than version B. The reason for this is because the compiler actually sets m = -1 and then does the subsequent conditional check m == -1. The compiler should be able to prove that this unnecessary.
Code that looks like this commonly occurs when a smaller inlineable helper is used for a quick path and then a conditional is used to check for a fallback. For example:
@dsnet, I'm not sure I understand the issue here. Since A, B, and C are variables, some code outside of the benchmarks could modify these, and then the benchmark functions would have to take the panic branch. We can't statically eliminate that. If A, B, and C are consts, then the compiler will recognize that it can statically prove the panic branch condition and will eliminate the panic branch in both benchmarks.
Perhaps you're suggesting that the compiler should recognize that it can lift the panic if up into both predecessor blocks and then optimize it differently in each predecessor?
@aclements The issue is that m is local, so it's not being modified elsewhere. One way to look at this is that conditional A is followed by conditional B, and both arms of A determine subsequent execution of B. B could be "inlined" (as a continuation, exactly that) into the two arms of A and then simplified.