From 4974ac6874a1fdeb50a025e84f03bb354a400ea7 Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Mon, 20 Apr 2020 15:40:38 -0700 Subject: [PATCH] cmd/compile: use cheaper implementation of oneBit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 TryBot-Result: Gobot Gobot Reviewed-by: Michael Munday --- src/cmd/compile/internal/ssa/rewrite.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cmd/compile/internal/ssa/rewrite.go b/src/cmd/compile/internal/ssa/rewrite.go index d222b164fdd6a1..923d50a03faadc 100644 --- a/src/cmd/compile/internal/ssa/rewrite.go +++ b/src/cmd/compile/internal/ssa/rewrite.go @@ -397,11 +397,11 @@ func ntz32(x int32) int { return bits.TrailingZeros32(uint32(x)) } 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 {