1
0
mirror of https://github.com/golang/go synced 2024-07-03 00:40:45 +00:00
go/test/codegen/bool.go
Paul E. Murphy 773039ed5c cmd/compile/internal/ssa: on PPC64, merge (CMPconst [0] (op ...)) more aggressively
Generate the CC version of many opcodes whose result is compared against
signed 0. The approach taken here works even if the opcode result is used in
multiple places too.

Add support for ADD, ADDconst, ANDN, SUB, NEG, CNTLZD, NOR conversions
to their CC opcode variant. These are the most commonly used variants.

Also, do not set clobberFlags of CNTLZD and CNTLZW, they do not clobber
flags.

This results in about 1% smaller text sections in kubernetes binaries,
and no regressions in the crypto benchmarks.

Change-Id: I9e0381944869c3774106bf348dead5ecb96dffda
Reviewed-on: https://go-review.googlesource.com/c/go/+/538636
Run-TryBot: Paul Murphy <murp@ibm.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jayanth Krishnamurthy <jayanth.krishnamurthy@ibm.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com>
2023-11-13 22:12:32 +00:00

277 lines
6.7 KiB
Go

// asmcheck
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package codegen
import (
"math/bits"
)
// This file contains codegen tests related to boolean simplifications/optimizations.
func convertNeq0B(x uint8, c bool) bool {
// amd64:"ANDL\t[$]1",-"SETNE"
// ppc64x:"RLDICL",-"CMPW",-"ISEL"
b := x&1 != 0
return c && b
}
func convertNeq0W(x uint16, c bool) bool {
// amd64:"ANDL\t[$]1",-"SETNE"
// ppc64x:"RLDICL",-"CMPW",-"ISEL"
b := x&1 != 0
return c && b
}
func convertNeq0L(x uint32, c bool) bool {
// amd64:"ANDL\t[$]1",-"SETB"
// ppc64x:"RLDICL",-"CMPW",-"ISEL"
b := x&1 != 0
return c && b
}
func convertNeq0Q(x uint64, c bool) bool {
// amd64:"ANDL\t[$]1",-"SETB"
// ppc64x:"RLDICL",-"CMP",-"ISEL"
b := x&1 != 0
return c && b
}
func convertNeqBool32(x uint32) bool {
// ppc64x:"RLDICL",-"CMPW",-"ISEL"
return x&1 != 0
}
func convertEqBool32(x uint32) bool {
// ppc64x:"RLDICL",-"CMPW","XOR",-"ISEL"
return x&1 == 0
}
func convertNeqBool64(x uint64) bool {
// ppc64x:"RLDICL",-"CMP",-"ISEL"
return x&1 != 0
}
func convertEqBool64(x uint64) bool {
// ppc64x:"RLDICL","XOR",-"CMP",-"ISEL"
return x&1 == 0
}
func TestSetEq64(x uint64, y uint64) bool {
// ppc64x/power10:"SETBC\tCR0EQ",-"ISEL"
// ppc64x/power9:"CMP","ISEL",-"SETBC\tCR0EQ"
// ppc64x/power8:"CMP","ISEL",-"SETBC\tCR0EQ"
b := x == y
return b
}
func TestSetNeq64(x uint64, y uint64) bool {
// ppc64x/power10:"SETBCR\tCR0EQ",-"ISEL"
// ppc64x/power9:"CMP","ISEL",-"SETBCR\tCR0EQ"
// ppc64x/power8:"CMP","ISEL",-"SETBCR\tCR0EQ"
b := x != y
return b
}
func TestSetLt64(x uint64, y uint64) bool {
// ppc64x/power10:"SETBC\tCR0GT",-"ISEL"
// ppc64x/power9:"CMP","ISEL",-"SETBC\tCR0GT"
// ppc64x/power8:"CMP","ISEL",-"SETBC\tCR0GT"
b := x < y
return b
}
func TestSetLe64(x uint64, y uint64) bool {
// ppc64x/power10:"SETBCR\tCR0LT",-"ISEL"
// ppc64x/power9:"CMP","ISEL",-"SETBCR\tCR0LT"
// ppc64x/power8:"CMP","ISEL",-"SETBCR\tCR0LT"
b := x <= y
return b
}
func TestSetGt64(x uint64, y uint64) bool {
// ppc64x/power10:"SETBC\tCR0LT",-"ISEL"
// ppc64x/power9:"CMP","ISEL",-"SETBC\tCR0LT"
// ppc64x/power8:"CMP","ISEL",-"SETBC\tCR0LT"
b := x > y
return b
}
func TestSetGe64(x uint64, y uint64) bool {
// ppc64x/power10:"SETBCR\tCR0GT",-"ISEL"
// ppc64x/power9:"CMP","ISEL",-"SETBCR\tCR0GT"
// ppc64x/power8:"CMP","ISEL",-"SETBCR\tCR0GT"
b := x >= y
return b
}
func TestSetLtFp64(x float64, y float64) bool {
// ppc64x/power10:"SETBC\tCR0LT",-"ISEL"
// ppc64x/power9:"FCMP","ISEL",-"SETBC\tCR0LT"
// ppc64x/power8:"FCMP","ISEL",-"SETBC\tCR0LT"
b := x < y
return b
}
func TestSetLeFp64(x float64, y float64) bool {
// ppc64x/power10:"SETBC\tCR0LT","SETBC\tCR0EQ","OR",-"ISEL",-"ISEL"
// ppc64x/power9:"ISEL","ISEL",-"SETBC\tCR0LT",-"SETBC\tCR0EQ","OR"
// ppc64x/power8:"ISEL","ISEL",-"SETBC\tCR0LT",-"SETBC\tCR0EQ","OR"
b := x <= y
return b
}
func TestSetGtFp64(x float64, y float64) bool {
// ppc64x/power10:"SETBC\tCR0LT",-"ISEL"
// ppc64x/power9:"FCMP","ISEL",-"SETBC\tCR0LT"
// ppc64x/power8:"FCMP","ISEL",-"SETBC\tCR0LT"
b := x > y
return b
}
func TestSetGeFp64(x float64, y float64) bool {
// ppc64x/power10:"SETBC\tCR0LT","SETBC\tCR0EQ","OR",-"ISEL",-"ISEL"
// ppc64x/power9:"ISEL","ISEL",-"SETBC\tCR0LT",-"SETBC\tCR0EQ","OR"
// ppc64x/power8:"ISEL","ISEL",-"SETBC\tCR0LT",-"SETBC\tCR0EQ","OR"
b := x >= y
return b
}
func TestSetInvEq64(x uint64, y uint64) bool {
// ppc64x/power10:"SETBCR\tCR0EQ",-"ISEL"
// ppc64x/power9:"CMP","ISEL",-"SETBCR\tCR0EQ"
// ppc64x/power8:"CMP","ISEL",-"SETBCR\tCR0EQ"
b := !(x == y)
return b
}
func TestSetInvNeq64(x uint64, y uint64) bool {
// ppc64x/power10:"SETBC\tCR0EQ",-"ISEL"
// ppc64x/power9:"CMP","ISEL",-"SETBC\tCR0EQ"
// ppc64x/power8:"CMP","ISEL",-"SETBC\tCR0EQ"
b := !(x != y)
return b
}
func TestSetInvLt64(x uint64, y uint64) bool {
// ppc64x/power10:"SETBCR\tCR0GT",-"ISEL"
// ppc64x/power9:"CMP","ISEL",-"SETBCR\tCR0GT"
// ppc64x/power8:"CMP","ISEL",-"SETBCR\tCR0GT"
b := !(x < y)
return b
}
func TestSetInvLe64(x uint64, y uint64) bool {
// ppc64x/power10:"SETBC\tCR0LT",-"ISEL"
// ppc64x/power9:"CMP","ISEL",-"SETBC\tCR0LT"
// ppc64x/power8:"CMP","ISEL",-"SETBC\tCR0LT"
b := !(x <= y)
return b
}
func TestSetInvGt64(x uint64, y uint64) bool {
// ppc64x/power10:"SETBCR\tCR0LT",-"ISEL"
// ppc64x/power9:"CMP","ISEL",-"SETBCR\tCR0LT"
// ppc64x/power8:"CMP","ISEL",-"SETBCR\tCR0LT"
b := !(x > y)
return b
}
func TestSetInvGe64(x uint64, y uint64) bool {
// ppc64x/power10:"SETBC\tCR0GT",-"ISEL"
// ppc64x/power9:"CMP","ISEL",-"SETBC\tCR0GT"
// ppc64x/power8:"CMP","ISEL",-"SETBC\tCR0GT"
b := !(x >= y)
return b
}
func TestSetInvEqFp64(x float64, y float64) bool {
// ppc64x/power10:"SETBCR\tCR0EQ",-"ISEL"
// ppc64x/power9:"FCMP","ISEL",-"SETBCR\tCR0EQ"
// ppc64x/power8:"FCMP","ISEL",-"SETBCR\tCR0EQ"
b := !(x == y)
return b
}
func TestSetInvNeqFp64(x float64, y float64) bool {
// ppc64x/power10:"SETBC\tCR0EQ",-"ISEL"
// ppc64x/power9:"FCMP","ISEL",-"SETBC\tCR0EQ"
// ppc64x/power8:"FCMP","ISEL",-"SETBC\tCR0EQ"
b := !(x != y)
return b
}
func TestSetInvLtFp64(x float64, y float64) bool {
// ppc64x/power10:"SETBCR\tCR0LT",-"ISEL"
// ppc64x/power9:"FCMP","ISEL",-"SETBCR\tCR0LT"
// ppc64x/power8:"FCMP","ISEL",-"SETBCR\tCR0LT"
b := !(x < y)
return b
}
func TestSetInvLeFp64(x float64, y float64) bool {
// ppc64x/power10:"SETBC\tCR0LT",-"ISEL"
// ppc64x/power9:"FCMP","ISEL",-"SETBC\tCR0LT"
// ppc64x/power8:"FCMP","ISEL",-"SETBC\tCR0LT"
b := !(x <= y)
return b
}
func TestSetInvGtFp64(x float64, y float64) bool {
// ppc64x/power10:"SETBCR\tCR0LT",-"ISEL"
// ppc64x/power9:"FCMP","ISEL",-"SETBCR\tCR0LT"
// ppc64x/power8:"FCMP","ISEL",-"SETBCR\tCR0LT"
b := !(x > y)
return b
}
func TestSetInvGeFp64(x float64, y float64) bool {
// ppc64x/power10:"SETBC\tCR0LT",-"ISEL"
// ppc64x/power9:"FCMP","ISEL",-"SETBC\tCR0LT"
// ppc64x/power8:"FCMP","ISEL",-"SETBC\tCR0LT"
b := !(x >= y)
return b
}
func TestLogicalCompareZero(x *[64]uint64) {
// ppc64x:"ANDCC",^"AND"
b := x[0]&3
if b!=0 {
x[0] = b
}
// ppc64x:"ANDCC",^"AND"
b = x[1]&x[2]
if b!=0 {
x[1] = b
}
// ppc64x:"ANDNCC",^"ANDN"
b = x[1]&^x[2]
if b!=0 {
x[1] = b
}
// ppc64x:"ORCC",^"OR"
b = x[3]|x[4]
if b!=0 {
x[3] = b
}
// ppc64x:"SUBCC",^"SUB"
b = x[5]-x[6]
if b!=0 {
x[5] = b
}
// ppc64x:"NORCC",^"NOR"
b = ^(x[5]|x[6])
if b!=0 {
x[5] = b
}
// ppc64x:"XORCC",^"XOR"
b = x[7]^x[8]
if b!=0 {
x[7] = b
}
// ppc64x:"ADDCC",^"ADD"
b = x[9]+x[10]
if b!=0 {
x[9] = b
}
// ppc64x:"NEGCC",^"NEG"
b = -x[11]
if b!=0 {
x[11] = b
}
// ppc64x:"CNTLZDCC",^"CNTLZD"
b = uint64(bits.LeadingZeros64(x[12]))
if b!=0 {
x[12] = b
}
// ppc64x:"ADDCCC\t[$]4,"
c := int64(x[12]) + 4
if c <= 0 {
x[12] = uint64(c)
}
}