Skip to content

Commit b003afe

Browse files
bmkesslerbradfitz
authored andcommitted
cmd/compile: intrinsify RotateLeft32 on wasm
wasm has 32-bit versions of all integer operations. This change lowers RotateLeft32 to i32.rotl on wasm and intrinsifies the math/bits call. Benchmarking on amd64 under node.js this is ~25% faster. node v10.15.3/amd64 name old time/op new time/op delta RotateLeft 8.37ns ± 1% 8.28ns ± 0% -1.05% (p=0.029 n=4+4) RotateLeft8 11.9ns ± 1% 11.8ns ± 0% ~ (p=0.167 n=5+5) RotateLeft16 11.8ns ± 0% 11.8ns ± 0% ~ (all equal) RotateLeft32 11.9ns ± 1% 8.7ns ± 0% -26.32% (p=0.008 n=5+5) RotateLeft64 8.31ns ± 1% 8.43ns ± 2% ~ (p=0.063 n=5+5) Updates #31265 Change-Id: I5b8e155978faeea536c4f6427ac9564d2f096a46 Reviewed-on: https://go-review.googlesource.com/c/go/+/182359 Run-TryBot: Brian Kessler <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Richard Musiol <[email protected]>
1 parent 12dbd20 commit b003afe

File tree

7 files changed

+35
-29
lines changed

7 files changed

+35
-29
lines changed

src/cmd/compile/internal/gc/ssa.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -3504,7 +3504,7 @@ func init() {
35043504
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
35053505
return s.newValue2(ssa.OpRotateLeft32, types.Types[TUINT32], args[0], args[1])
35063506
},
3507-
sys.AMD64, sys.ARM, sys.ARM64, sys.S390X, sys.PPC64)
3507+
sys.AMD64, sys.ARM, sys.ARM64, sys.S390X, sys.PPC64, sys.Wasm)
35083508
addF("math/bits", "RotateLeft64",
35093509
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
35103510
return s.newValue2(ssa.OpRotateLeft64, types.Types[TUINT64], args[0], args[1])

src/cmd/compile/internal/ssa/gen/Wasm.rules

+2-3
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,8 @@
147147
// Lowering rotates
148148
(RotateLeft8 <t> x (I64Const [c])) -> (Or8 (Lsh8x64 <t> x (I64Const [c&7])) (Rsh8Ux64 <t> x (I64Const [-c&7])))
149149
(RotateLeft16 <t> x (I64Const [c])) -> (Or16 (Lsh16x64 <t> x (I64Const [c&15])) (Rsh16Ux64 <t> x (I64Const [-c&15])))
150-
(RotateLeft32 <t> x (I64Const [c])) -> (Or32 (Lsh32x64 <t> x (I64Const [c&31])) (Rsh32Ux64 <t> x (I64Const [-c&31])))
150+
(RotateLeft32 x y) -> (I32Rotl x y)
151+
(RotateLeft64 x y) -> (I64Rotl x y)
151152

152153
// Lowering comparisons
153154
(Less64 x y) -> (I64LtS x y)
@@ -362,8 +363,6 @@
362363

363364
(BitLen64 x) -> (I64Sub (I64Const [64]) (I64Clz x))
364365

365-
(RotateLeft64 x y) -> (I64Rotl x y)
366-
367366
(PopCount64 x) -> (I64Popcnt x)
368367
(PopCount32 x) -> (I64Popcnt (ZeroExt32to64 x))
369368
(PopCount16 x) -> (I64Popcnt (ZeroExt16to64 x))

src/cmd/compile/internal/ssa/gen/WasmOps.go

+1
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ func init() {
206206

207207
{name: "I64Ctz", asm: "I64Ctz", argLength: 1, reg: gp11, typ: "Int64"}, // ctz(arg0)
208208
{name: "I64Clz", asm: "I64Clz", argLength: 1, reg: gp11, typ: "Int64"}, // clz(arg0)
209+
{name: "I32Rotl", asm: "I32Rotl", argLength: 2, reg: gp21, typ: "Int32"}, // rotl(arg0, arg1)
209210
{name: "I64Rotl", asm: "I64Rotl", argLength: 2, reg: gp21, typ: "Int64"}, // rotl(arg0, arg1)
210211
{name: "I64Popcnt", asm: "I64Popcnt", argLength: 1, reg: gp11, typ: "Int64"}, // popcnt(arg0)
211212
}

src/cmd/compile/internal/ssa/opGen.go

+15
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cmd/compile/internal/ssa/rewriteWasm.go

+6-25
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cmd/compile/internal/wasm/ssa.go

+6
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,12 @@ func ssaGenValueOnStack(s *gc.SSAGenState, v *ssa.Value, extend bool) {
299299
getValue64(s, v.Args[1])
300300
s.Prog(v.Op.Asm())
301301

302+
case ssa.OpWasmI32Rotl:
303+
getValue32(s, v.Args[0])
304+
getValue32(s, v.Args[1])
305+
s.Prog(wasm.AI32Rotl)
306+
s.Prog(wasm.AI64ExtendI32U)
307+
302308
case ssa.OpWasmI64DivS:
303309
getValue64(s, v.Args[0])
304310
getValue64(s, v.Args[1])

test/codegen/mathbits.go

+4
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ func RotateLeft32(n uint32) uint32 {
213213
// ppc64:"ROTLW"
214214
// ppc64le:"ROTLW"
215215
// s390x:"RLL"
216+
// wasm:"I32Rotl"
216217
return bits.RotateLeft32(n, 9)
217218
}
218219

@@ -232,6 +233,7 @@ func RotateLeftVariable(n uint, m int) uint {
232233
// ppc64:"ROTL"
233234
// ppc64le:"ROTL"
234235
// s390x:"RLLG"
236+
// wasm:"I64Rotl"
235237
return bits.RotateLeft(n, m)
236238
}
237239

@@ -241,6 +243,7 @@ func RotateLeftVariable64(n uint64, m int) uint64 {
241243
// ppc64:"ROTL"
242244
// ppc64le:"ROTL"
243245
// s390x:"RLLG"
246+
// wasm:"I64Rotl"
244247
return bits.RotateLeft64(n, m)
245248
}
246249

@@ -251,6 +254,7 @@ func RotateLeftVariable32(n uint32, m int) uint32 {
251254
// ppc64:"ROTLW"
252255
// ppc64le:"ROTLW"
253256
// s390x:"RLL"
257+
// wasm:"I32Rotl"
254258
return bits.RotateLeft32(n, m)
255259
}
256260

0 commit comments

Comments
 (0)