cmd/compile: reorder operations in multiply strength reduction Put regular shifts last, so that they can be folded into address calculations. Update #80639 Change-Id: I0a07abbc7a29e1c0c5d6b5c7ed2ae2cffe43957c Reviewed-on: https://go-review.googlesource.com/c/go/+/808200 Reviewed-by: Mark Freeman <markfreeman@google.com> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Jorropo <jorropo.pgm@gmail.com> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/src/cmd/compile/internal/ssa/config.go b/src/cmd/compile/internal/ssa/config.go index 10304e7..f963986 100644 --- a/src/cmd/compile/internal/ssa/config.go +++ b/src/cmd/compile/internal/ssa/config.go
@@ -538,20 +538,6 @@ func(m, x, y *Value) *Value { return m.Block.NewValue2(m.Pos, OpARM64SUB, m.Type, x, y) }) - // regular shifts - for i := 1; i < 64; i++ { - c := 10 - if i == 1 { - // Prefer x<<1 over x+x. - // Note that we eventually reverse this decision in ARM64latelower.rules, - // but this makes shift combining rules in ARM64.rules simpler. - c-- - } - r(1<<i, 0, c, - func(m, x, y *Value) *Value { - return m.Block.NewValue1I(m.Pos, OpARM64SLLconst, m.Type, int64(i), x) - }) - } // ADDshiftLL for i := 1; i < 64; i++ { c := 20 @@ -585,6 +571,20 @@ return m.Block.NewValue2I(m.Pos, OpARM64SUBshiftLL, m.Type, int64(i), x, y) }) } + // regular shifts + for i := 1; i < 64; i++ { + c := 10 + if i == 1 { + // Prefer x<<1 over x+x. + // Note that we eventually reverse this decision in ARM64latelower.rules, + // but this makes shift combining rules in ARM64.rules simpler. + c-- + } + r(1<<i, 0, c, + func(m, x, y *Value) *Value { + return m.Block.NewValue1I(m.Pos, OpARM64SLLconst, m.Type, int64(i), x) + }) + } case "loong64": // - multiply is 4 cycles. // - add/sub/shift/alsl are 1 cycle. @@ -608,6 +608,15 @@ return m.Block.NewValue2(m.Pos, OpLOONG64SUBV, m.Type, x, y) }) + // ADDshiftLLV + for i := 1; i < 5; i++ { + c := 10 + r(1, 1<<i, c, + func(m, x, y *Value) *Value { + return m.Block.NewValue2I(m.Pos, OpLOONG64ADDshiftLLV, m.Type, int64(i), x, y) + }) + } + // regular shifts for i := 1; i < 64; i++ { c := 10 @@ -622,15 +631,6 @@ return m.Block.NewValue1I(m.Pos, OpLOONG64SLLVconst, m.Type, int64(i), x) }) } - - // ADDshiftLLV - for i := 1; i < 5; i++ { - c := 10 - r(1, 1<<i, c, - func(m, x, y *Value) *Value { - return m.Block.NewValue2I(m.Pos, OpLOONG64ADDshiftLLV, m.Type, int64(i), x, y) - }) - } } c.mulRecipes = map[int64]mulRecipe{}
diff --git a/test/codegen/multiply.go b/test/codegen/multiply.go index 8c76fd9..54b61e4 100644 --- a/test/codegen/multiply.go +++ b/test/codegen/multiply.go
@@ -180,7 +180,7 @@ func m29(x int64) int64 { // amd64: "IMUL3Q [$]29," // arm64: "MOVD [$]29," "MUL" - // loong64: "ALSLV [$]1," "SLLV [$]5," "SUBVU" + // loong64: "ALSLV [$]1," "ALSLV [$]2," "ALSLV [$]3," return x * 29 } func m30(x int64) int64 { @@ -307,7 +307,7 @@ func mn10(x int64) int64 { // amd64: "IMUL3Q [$]-10," // arm64: "MOVD [$]-10," "MUL" - // loong64: "ADDVU" "ALSLV [$]3" "SUBVU" + // loong64: "ALSLV [$]2," "SUBVU" "ADDVU" return x * -10 } func mn11(x int64) int64 { @@ -319,13 +319,13 @@ func mn12(x int64) int64 { // amd64: "IMUL3Q [$]-12," // arm64: "LSL [$]2," "SUB R[0-9]+<<2," - // loong64: "SUBVU" "SLLV [$]2," "ALSLV [$]4," + // loong64: "ALSLV [$]2," "ALSLV [$]4," "SUBVU" return x * -12 } func mn13(x int64) int64 { // amd64: "IMUL3Q [$]-13," // arm64: "MOVD [$]-13," "MUL" - // loong64: "ALSLV [$]4," "SLLV [$]2, " "SUBVU" + // loong64: "ALSLV [$]1," "SUBVU" "ALSLV [$]4," return x * -13 } func mn14(x int64) int64 { @@ -355,7 +355,7 @@ func mn18(x int64) int64 { // amd64: "IMUL3Q [$]-18," // arm64: "MOVD [$]-18," "MUL" - // loong64: "ADDVU" "ALSLV [$]4," "SUBVU" + // loong64: "ALSLV [$]3," "SUBVU" "ADDVU" return x * -18 } func mn19(x int64) int64 { @@ -367,6 +367,6 @@ func mn20(x int64) int64 { // amd64: "IMUL3Q [$]-20," // arm64: "MOVD [$]-20," "MUL" - // loong64: "SLLV [$]2," "ALSLV [$]4," "SUBVU" + // loong64: "ALSLV [$]2," "SUBVU" "SLLV [$]2," return x * -20 }