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
 }