This is the second attempt. The first attempt was CL 229127,
which got rolled back by CL 229177, because it caused
an infinite loop during compilation on some platforms.
I didn't notice that the trybots hadn't completed when I submitted; mea culpa.
The bug was that we were checking x&(x-1)==0, which is also true of 0,
which does not have exactly one bit set.
This caused an infinite rewrite rule loop.
Updates #38547
file before after Δ %
compile
19678112 19669808 -8304 -0.042%
total
113143160 113134856 -8304 -0.007%
Change-Id: I417a4f806e1ba61277e31bab2e57dd3f1ac7e835
Reviewed-on: https://go-review.googlesource.com/c/go/+/229197
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Michael Munday <mike.munday@ibm.com>
func ntz16(x int16) int { return bits.TrailingZeros16(uint16(x)) }
func ntz8(x int8) int { return bits.TrailingZeros8(uint8(x)) }
-func oneBit(x int64) bool { return bits.OnesCount64(uint64(x)) == 1 }
-func oneBit8(x int8) bool { return bits.OnesCount8(uint8(x)) == 1 }
-func oneBit16(x int16) bool { return bits.OnesCount16(uint16(x)) == 1 }
-func oneBit32(x int32) bool { return bits.OnesCount32(uint32(x)) == 1 }
-func oneBit64(x int64) bool { return bits.OnesCount64(uint64(x)) == 1 }
+func oneBit(x int64) bool { return x&(x-1) == 0 && x != 0 }
+func oneBit8(x int8) bool { return x&(x-1) == 0 && x != 0 }
+func oneBit16(x int16) bool { return x&(x-1) == 0 && x != 0 }
+func oneBit32(x int32) bool { return x&(x-1) == 0 && x != 0 }
+func oneBit64(x int64) bool { return x&(x-1) == 0 && x != 0 }
// nlo returns the number of leading ones.
func nlo(x int64) int64 {