mirror of
https://github.com/golang/go.git
synced 2025-05-23 16:31:27 +00:00
Add 2 more cases: if a { x = value } else { x = a } => x = a && value if a { x = a } else { x = value } => x = a || value AND case goes from: 00006 (8) TESTB AX, AX 00007 (8) JNE 9 00008 (13) MOVL AX, BX 00009 (13) MOVL BX, AX 00010 (13) RET to: 00006 (13) ANDL BX, AX 00007 (13) RET OR goes from: 00006 (19) TESTB AX, AX 00007 (19) JNE 9 00008 (24) MOVL BX, AX 00009 (24) RET to: 00006 (24) ORL BX, AX 00007 (24) RET compilecmp linux/amd64: runtime runtime.lock2 847 -> 869 (+2.60%) runtime.addspecial 542 -> 517 (-4.61%) runtime.tracebackPCs changed runtime.scanstack changed runtime.mallocinit changed runtime.traceback2 2238 -> 2206 (-1.43%) runtime [cmd/compile] runtime.lock2 860 -> 882 (+2.56%) runtime.scanstack changed runtime.addspecial 542 -> 517 (-4.61%) runtime.traceback2 2238 -> 2206 (-1.43%) runtime.lockWithRank 870 -> 890 (+2.30%) runtime.tracebackPCs changed runtime.mallocinit changed strconv strconv.ryuFtoaFixed32 changed strconv.ryuFtoaFixed64 639 -> 638 (-0.16%) strconv.readFloat changed strconv.ryuFtoaShortest changed strings strings.(*Replacer).build changed strconv [cmd/compile] strconv.readFloat changed strconv.ryuFtoaFixed64 639 -> 638 (-0.16%) strconv.ryuFtoaFixed32 changed strconv.ryuFtoaShortest changed strings [cmd/compile] strings.(*Replacer).build changed regexp regexp.makeOnePass.func1 changed regexp [cmd/compile] regexp.makeOnePass.func1 changed encoding/json encoding/json.indirect changed database/sql database/sql.driverArgsConnLocked changed vendor/golang.org/x/text/unicode/norm vendor/golang.org/x/text/unicode/norm.Form.transform changed go/doc/comment go/doc/comment.parseSpans changed internal/diff internal/diff.tgs changed log/slog log/slog.(*handleState).appendNonBuiltIns 1898 -> 1877 (-1.11%) testing/fstest testing/fstest.(*fsTester).checkGlob changed runtime/pprof runtime/pprof.(*profileBuilder).build changed cmd/internal/dwarf cmd/internal/dwarf.isEmptyInlinedCall 254 -> 244 (-3.94%) go/printer go/printer.keepTypeColumn 302 -> 270 (-10.60%) go/printer.(*printer).binaryExpr changed cmd/compile/internal/syntax cmd/compile/internal/syntax.(*scanner).rune changed cmd/compile/internal/syntax.(*scanner).number 2137 -> 2153 (+0.75%) Change-Id: I7f95f54b03a35d0b616c40f38b415a7feb71be73 Reviewed-on: https://go-review.googlesource.com/c/go/+/666835 Reviewed-by: Keith Randall <khr@golang.org> Auto-Submit: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@google.com> Run-TryBot: Jakub Ciolek <jakub@ciolek.dev> TryBot-Bypass: Keith Randall <khr@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
316 lines
7.3 KiB
Go
316 lines
7.3 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"
|
|
// amd64:"ANDL","XORL",-"BTL",-"SETCC"
|
|
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"
|
|
// amd64:"ANDL","XORL",-"BTL",-"SETCC"
|
|
return x&1 == 0
|
|
}
|
|
|
|
func phiAnd(a, b bool) bool {
|
|
var x bool
|
|
// amd64:-"TESTB"
|
|
if a {
|
|
x = b
|
|
} else {
|
|
x = a
|
|
}
|
|
// amd64:"ANDL"
|
|
return x
|
|
}
|
|
|
|
func phiOr(a, b bool) bool {
|
|
var x bool
|
|
// amd64:-"TESTB"
|
|
if a {
|
|
x = a
|
|
} else {
|
|
x = b
|
|
}
|
|
// amd64:"ORL"
|
|
return x
|
|
}
|
|
|
|
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)
|
|
}
|
|
|
|
// ppc64x:"MULHDUCC",^"MULHDU"
|
|
hi, _ := bits.Mul64(x[13], x[14])
|
|
if hi != 0 {
|
|
x[14] = hi
|
|
}
|
|
|
|
}
|
|
|
|
func constantWrite(b bool, p *bool) {
|
|
if b {
|
|
// amd64:`MOVB\t[$]1, \(`
|
|
*p = b
|
|
}
|
|
}
|