From 061d77cb7008cf9e4d8b3b6382828b483bff032f Mon Sep 17 00:00:00 2001 From: "Paul E. Murphy" Date: Fri, 15 Sep 2023 15:20:56 -0500 Subject: [PATCH] cmd/compile/internal/ssa: on PPC64, generate large constant paddi This is only supported power10/linux/PPC64. This generates smaller, faster code by merging a pli + add into paddi. Change-Id: I1f4d522fce53aea4c072713cc119a9e0d7065acc Reviewed-on: https://go-review.googlesource.com/c/go/+/531717 Run-TryBot: Paul Murphy LUCI-TryBot-Result: Go LUCI Reviewed-by: Than McIntosh Reviewed-by: Dmitri Shuralyov TryBot-Result: Gopher Robot Reviewed-by: Lynn Boger --- .../internal/ssa/_gen/PPC64latelower.rules | 3 +++ .../internal/ssa/rewritePPC64latelower.go | 27 +++++++++++++++++++ test/codegen/arithmetic.go | 15 +++++++++++ 3 files changed, 45 insertions(+) diff --git a/src/cmd/compile/internal/ssa/_gen/PPC64latelower.rules b/src/cmd/compile/internal/ssa/_gen/PPC64latelower.rules index 5980fc922e..d5fe1276aa 100644 --- a/src/cmd/compile/internal/ssa/_gen/PPC64latelower.rules +++ b/src/cmd/compile/internal/ssa/_gen/PPC64latelower.rules @@ -33,3 +33,6 @@ // Convert rotated 32 bit masks on 32 bit values into rlwinm. In general, this leaves the upper 32 bits in an undefined state. (AND x:(MOVDconst [m]) n) && t.Size() == 4 && isPPC64WordRotateMask(m) => (RLWINM [encodePPC64RotateMask(0,m,32)] n) + +// When PCRel is supported, paddi can add a 34b signed constant in one instruction. +(ADD (MOVDconst [m]) x) && supportsPPC64PCRel() && (m<<30)>>30 == m => (ADDconst [m] x) diff --git a/src/cmd/compile/internal/ssa/rewritePPC64latelower.go b/src/cmd/compile/internal/ssa/rewritePPC64latelower.go index 8b22a7d02f..2e8ad928f8 100644 --- a/src/cmd/compile/internal/ssa/rewritePPC64latelower.go +++ b/src/cmd/compile/internal/ssa/rewritePPC64latelower.go @@ -7,6 +7,8 @@ import "cmd/compile/internal/types" func rewriteValuePPC64latelower(v *Value) bool { switch v.Op { + case OpPPC64ADD: + return rewriteValuePPC64latelower_OpPPC64ADD(v) case OpPPC64AND: return rewriteValuePPC64latelower_OpPPC64AND(v) case OpPPC64ISEL: @@ -22,6 +24,31 @@ func rewriteValuePPC64latelower(v *Value) bool { } return false } +func rewriteValuePPC64latelower_OpPPC64ADD(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (ADD (MOVDconst [m]) x) + // cond: supportsPPC64PCRel() && (m<<30)>>30 == m + // result: (ADDconst [m] x) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpPPC64MOVDconst { + continue + } + m := auxIntToInt64(v_0.AuxInt) + x := v_1 + if !(supportsPPC64PCRel() && (m<<30)>>30 == m) { + continue + } + v.reset(OpPPC64ADDconst) + v.AuxInt = int64ToAuxInt(m) + v.AddArg(x) + return true + } + break + } + return false +} func rewriteValuePPC64latelower_OpPPC64AND(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] diff --git a/test/codegen/arithmetic.go b/test/codegen/arithmetic.go index b91a904be9..0d6d969000 100644 --- a/test/codegen/arithmetic.go +++ b/test/codegen/arithmetic.go @@ -10,6 +10,21 @@ package codegen // simplifications and optimizations on integer types. // For codegen tests on float types, see floats.go. +// ----------------- // +// Addition // +// ----------------- // + +func AddLargeConst(a uint64, out []uint64) { + // ppc64x/power10:"ADD\t[$]4294967296," + // ppc64x/power9:"MOVD\t[$]i64.0000000100000000[(]SB[)]", "ADD\tR[0-9]*" + // ppc64x/power8:"MOVD\t[$]i64.0000000100000000[(]SB[)]", "ADD\tR[0-9]*" + out[0] = a + 0x100000000 + // ppc64x/power10:"ADD\t[$]-8589934592," + // ppc64x/power9:"MOVD\t[$]i64.fffffffe00000000[(]SB[)]", "ADD\tR[0-9]*" + // ppc64x/power8:"MOVD\t[$]i64.fffffffe00000000[(]SB[)]", "ADD\tR[0-9]*" + out[1] = a + 0xFFFFFFFE00000000 +} + // ----------------- // // Subtraction // // ----------------- //