Skip to content

Commit

Permalink
cmd/compile/internal/ssa: use sequence of shNadd instructions instead…
Browse files Browse the repository at this point in the history
… of mul

In some cases, we can replace a mul instruction with a sequence of shNadd instructions.
Using a sequence of three shNadd instructions does not provide a performance benefit.
However, a sequence of two shNadd instructions is still faster than using a single mul instruction.

Co-Authored-By: Andrei <[email protected]>
  • Loading branch information
vacmannnn and therain7 committed Jan 8, 2025
1 parent 39f2032 commit ef1cca4
Show file tree
Hide file tree
Showing 3 changed files with 292 additions and 0 deletions.
18 changes: 18 additions & 0 deletions src/cmd/compile/internal/ssa/_gen/RISCV64.rules
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,24 @@
(ADD (SLLI [2] x) y) && buildcfg.GORISCV64 >= 22 => (SH2ADD x y)
(ADD (SLLI [3] x) y) && buildcfg.GORISCV64 >= 22 => (SH3ADD x y)

// Mul on some constants
(MUL x (MOVDconst [3])) && buildcfg.GORISCV64 >= 22 => (SH1ADD x x)
(MUL x (MOVDconst [5])) && buildcfg.GORISCV64 >= 22 => (SH2ADD x x)
(MUL x (MOVDconst [9])) && buildcfg.GORISCV64 >= 22 => (SH3ADD x x)

(MUL <t> x (MOVDconst [11])) && buildcfg.GORISCV64 >= 22 => (SH1ADD (SH2ADD <t> x x) x)
(MUL <t> x (MOVDconst [13])) && buildcfg.GORISCV64 >= 22 => (SH2ADD (SH1ADD <t> x x) x)
(MUL <t> x (MOVDconst [19])) && buildcfg.GORISCV64 >= 22 => (SH1ADD (SH3ADD <t> x x) x)
(MUL <t> x (MOVDconst [21])) && buildcfg.GORISCV64 >= 22 => (SH2ADD (SH2ADD <t> x x) x)
(MUL <t> x (MOVDconst [25])) && buildcfg.GORISCV64 >= 22 => (SH3ADD (SH1ADD <t> x x) x)
(MUL <t> x (MOVDconst [27])) && buildcfg.GORISCV64 >= 22 => (SH1ADD (SH3ADD <t> x x) (SH3ADD <t> x x))
(MUL <t> x (MOVDconst [37])) && buildcfg.GORISCV64 >= 22 => (SH2ADD (SH3ADD <t> x x) x)
(MUL <t> x (MOVDconst [41])) && buildcfg.GORISCV64 >= 22 => (SH3ADD (SH2ADD <t> x x) x)
(MUL <t> x (MOVDconst [45])) && buildcfg.GORISCV64 >= 22 => (SH2ADD (SH3ADD <t> x x) (SH3ADD <t> x x))
(MUL <t> x (MOVDconst [73])) && buildcfg.GORISCV64 >= 22 => (SH3ADD (SH3ADD <t> x x) x)
(MUL <t> x (MOVDconst [81])) && buildcfg.GORISCV64 >= 22 => (SH3ADD (SH3ADD <t> x x) (SH3ADD <t> x x))


// Integer minimum and maximum.
(Min64 x y) && buildcfg.GORISCV64 >= 22 => (MIN x y)
(Max64 x y) && buildcfg.GORISCV64 >= 22 => (MAX x y)
Expand Down
251 changes: 251 additions & 0 deletions src/cmd/compile/internal/ssa/rewriteRISCV64.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions test/codegen/shift.go
Original file line number Diff line number Diff line change
Expand Up @@ -531,3 +531,26 @@ func checkLeftShiftWithAddition(a int64, b int64) int64 {
a = a + b<<3
return a
}

//
// Multiplication by some constants
//

func checkMulByConsts(a int64, b int64, c int64, d int64, e int64) (int64, int64, int64, int64, int64) {
// riscv64/rva20u64: "MUL"
// riscv64/rva22u64: "SH1ADD"
a = a * 3
// riscv64/rva20u64: "MUL"
// riscv64/rva22u64: "SH2ADD"
b = b * 5
// riscv64/rva20u64: "MUL"
// riscv64/rva22u64: "SH2ADD", "SH1ADD"
c = c * 13
// riscv64/rva20u64: "MUL"
// riscv64/rva22u64: "SH1ADD", "SH3ADD"
d = d * 27
// riscv64/rva20u64: "MUL"
// riscv64/rva22u64: "SH3ADD", "SH3ADD"
e = e * 73
return a, b, c, d, e
}

0 comments on commit ef1cca4

Please sign in to comment.