From: Jakub Ciolek Date: Sat, 19 Apr 2025 10:31:26 +0000 (+0200) Subject: cmd/compile: add 2 phiopt cases X-Git-Tag: go1.25rc1~331 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=c9d0fad5cbeb8ec60c7b21bb48f101e835241274;p=gostls13.git cmd/compile: add 2 phiopt cases 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 Auto-Submit: Keith Randall Reviewed-by: Keith Randall Run-TryBot: Jakub Ciolek TryBot-Bypass: Keith Randall Reviewed-by: Cherry Mui LUCI-TryBot-Result: Go LUCI --- diff --git a/src/cmd/compile/internal/ssa/phiopt.go b/src/cmd/compile/internal/ssa/phiopt.go index 037845eacf..034ee4c661 100644 --- a/src/cmd/compile/internal/ssa/phiopt.go +++ b/src/cmd/compile/internal/ssa/phiopt.go @@ -119,6 +119,33 @@ func phiopt(f *Func) { continue } } + // Replaces + // if a { x = value } else { x = a } with x = a && value. + // Requires that value dominates x. + if v.Args[1-reverse] == b0.Controls[0] { + if tmp := v.Args[reverse]; sdom.IsAncestorEq(tmp.Block, b) { + v.reset(OpAndB) + v.SetArgs2(b0.Controls[0], tmp) + if f.pass.debug > 0 { + f.Warnl(b.Pos, "converted OpPhi to %v", v.Op) + } + continue + } + } + + // Replaces + // if a { x = a } else { x = value } with x = a || value. + // Requires that value dominates x. + if v.Args[reverse] == b0.Controls[0] { + if tmp := v.Args[1-reverse]; sdom.IsAncestorEq(tmp.Block, b) { + v.reset(OpOrB) + v.SetArgs2(b0.Controls[0], tmp) + if f.pass.debug > 0 { + f.Warnl(b.Pos, "converted OpPhi to %v", v.Op) + } + continue + } + } } } // strengthen phi optimization. diff --git a/test/codegen/bool.go b/test/codegen/bool.go index 2024759a5c..760dbbcf7b 100644 --- a/test/codegen/bool.go +++ b/test/codegen/bool.go @@ -62,6 +62,30 @@ func convertEqBool64(x uint64) bool { 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" diff --git a/test/phiopt.go b/test/phiopt.go index 9e21bfdba5..206a117fbb 100644 --- a/test/phiopt.go +++ b/test/phiopt.go @@ -129,5 +129,27 @@ func f9(a, b int) bool { return c } +//go:noinline +func f10and(a bool, b bool) bool { + var x bool + if a { + x = b + } else { + x = a + } + return x // ERROR "converted OpPhi to AndB$" +} + +//go:noinline +func f11or(a bool, b bool) bool { + var x bool + if a { + x = a + } else { + x = b + } + return x // ERROR "converted OpPhi to OrB$" +} + func main() { }