From 4d180f71dca041a39b50b9dec8a0ebec5cc02b90 Mon Sep 17 00:00:00 2001 From: ruinan Date: Thu, 18 Aug 2022 01:31:57 +0000 Subject: cmd/compile: omit redundant sign/unsign extension on arm64 On Arm64, all 32-bit instructions will ignore the upper 32 bits and clear them to zero for the result. No need to do an unsign extend before a 32 bit op. This CL removes the redundant unsign extension only for the existing 32-bit opcodes, and also omits the sign extension when the upper bit of the result can be predicted. Fixes #42162 Change-Id: I61e6670bfb8982572430e67a4fa61134a3ea240a CustomizedGitHooks: yes Reviewed-on: https://go-review.googlesource.com/c/go/+/427454 Reviewed-by: Keith Randall Auto-Submit: Eric Fang Reviewed-by: Keith Randall Run-TryBot: Eric Fang Reviewed-by: Cherry Mui TryBot-Result: Gopher Robot --- test/codegen/noextend.go | 94 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) (limited to 'test/codegen') diff --git a/test/codegen/noextend.go b/test/codegen/noextend.go index e4081e3915..61c98a796a 100644 --- a/test/codegen/noextend.go +++ b/test/codegen/noextend.go @@ -6,6 +6,8 @@ package codegen +import "math/bits" + var sval64 [8]int64 var sval32 [8]int32 var sval16 [8]int16 @@ -185,3 +187,95 @@ func cmp64(u8 *uint8, x16 *int16, u16 *uint16, x32 *int32, u32 *uint32) bool { } return false } + +// no unsign extension following 32 bits ops + +func noUnsignEXT(t1, t2, t3, t4 uint32, k int64) uint64 { + var ret uint64 + + // arm64:"RORW",-"MOVWU" + ret += uint64(bits.RotateLeft32(t1, 7)) + + // arm64:"MULW",-"MOVWU" + ret *= uint64(t1 * t2) + + // arm64:"MNEGW",-"MOVWU" + ret += uint64(-t1 * t3) + + // arm64:"UDIVW",-"MOVWU" + ret += uint64(t1 / t4) + + // arm64:-"MOVWU" + ret += uint64(t2 % t3) + + // arm64:"MSUBW",-"MOVWU" + ret += uint64(t1 - t2*t3) + + // arm64:"MADDW",-"MOVWU" + ret += uint64(t3*t4 + t2) + + // arm64:"REVW",-"MOVWU" + ret += uint64(bits.ReverseBytes32(t1)) + + // arm64:"RBITW",-"MOVWU" + ret += uint64(bits.Reverse32(t1)) + + // arm64:"CLZW",-"MOVWU" + ret += uint64(bits.LeadingZeros32(t1)) + + // arm64:"REV16W",-"MOVWU" + ret += uint64(((t1 & 0xff00ff00) >> 8) | ((t1 & 0x00ff00ff) << 8)) + + // arm64:"EXTRW",-"MOVWU" + ret += uint64((t1 << 25) | (t2 >> 7)) + + return ret +} + +// no sign extension when the upper bits of the result are zero + +func noSignEXT(x int) int64 { + t1 := int32(x) + + var ret int64 + + // arm64:-"MOVW" + ret += int64(t1 & 1) + + // arm64:-"MOVW" + ret += int64(int32(x & 0x7fffffff)) + + // arm64:-"MOVH" + ret += int64(int16(x & 0x7fff)) + + // arm64:-"MOVB" + ret += int64(int8(x & 0x7f)) + + return ret +} + +// corner cases that sign extension must not be omitted + +func shouldSignEXT(x int) int64 { + t1 := int32(x) + + var ret int64 + + // arm64:"MOVW" + ret += int64(t1 & (-1)) + + // arm64:"MOVW" + ret += int64(int32(x & 0x80000000)) + + // arm64:"MOVW" + ret += int64(int32(x & 0x1100000011111111)) + + // arm64:"MOVH" + ret += int64(int16(x & 0x1100000000001111)) + + // arm64:"MOVB" + ret += int64(int8(x & 0x1100000000000011)) + + return ret + +} -- cgit v1.3