aboutsummaryrefslogtreecommitdiff
path: root/test/codegen/noextend.go
diff options
context:
space:
mode:
authorruinan <ruinan.sun@arm.com>2022-08-18 01:31:57 +0000
committerGopher Robot <gobot@golang.org>2023-02-28 03:16:44 +0000
commit4d180f71dca041a39b50b9dec8a0ebec5cc02b90 (patch)
treede718da37f917630d4dab3620a23fba111fbee52 /test/codegen/noextend.go
parentdd16258f48bc9e328ef2086a49da0432fe46f413 (diff)
downloadgo-4d180f71dca041a39b50b9dec8a0ebec5cc02b90.tar.xz
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 <khr@google.com> Auto-Submit: Eric Fang <eric.fang@arm.com> Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Eric Fang <eric.fang@arm.com> Reviewed-by: Cherry Mui <cherryyz@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'test/codegen/noextend.go')
-rw-r--r--test/codegen/noextend.go94
1 files changed, 94 insertions, 0 deletions
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
+
+}