Skip to content

Commit 3d9a89b

Browse files
committed
cmd/compile: use integer min/max instructions on riscv64
When GORISCV64 enables rva22u64, make use of integer MIN/MINU/MAX/MAXU instructions in compiler rewrite rules. Change-Id: I4e7c514516acad03f2869d4c8936f06582cf7ea9 Reviewed-on: https://go-review.googlesource.com/c/go/+/559660 Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Carlos Amedee <carlos@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Meng Zhuo <mengzhuo1203@gmail.com>
1 parent 2709358 commit 3d9a89b

File tree

7 files changed

+212
-2
lines changed

7 files changed

+212
-2
lines changed

src/cmd/compile/internal/riscv64/ssa.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,8 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
288288
ssa.OpRISCV64FADDS, ssa.OpRISCV64FSUBS, ssa.OpRISCV64FMULS, ssa.OpRISCV64FDIVS,
289289
ssa.OpRISCV64FEQS, ssa.OpRISCV64FNES, ssa.OpRISCV64FLTS, ssa.OpRISCV64FLES,
290290
ssa.OpRISCV64FADDD, ssa.OpRISCV64FSUBD, ssa.OpRISCV64FMULD, ssa.OpRISCV64FDIVD,
291-
ssa.OpRISCV64FEQD, ssa.OpRISCV64FNED, ssa.OpRISCV64FLTD, ssa.OpRISCV64FLED,
292-
ssa.OpRISCV64FSGNJD:
291+
ssa.OpRISCV64FEQD, ssa.OpRISCV64FNED, ssa.OpRISCV64FLTD, ssa.OpRISCV64FLED, ssa.OpRISCV64FSGNJD,
292+
ssa.OpRISCV64MIN, ssa.OpRISCV64MAX, ssa.OpRISCV64MINU, ssa.OpRISCV64MAXU:
293293
r := v.Reg()
294294
r1 := v.Args[0].Reg()
295295
r2 := v.Args[1].Reg()

src/cmd/compile/internal/ssa/_gen/RISCV64.rules

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,3 +834,13 @@
834834
(F(MADD|NMADD|MSUB|NMSUB)S x y neg:(FNEGS z)) && neg.Uses == 1 => (F(MSUB|NMSUB|MADD|NMADD)S x y z)
835835
(F(MADD|NMADD|MSUB|NMSUB)D neg:(FNEGD x) y z) && neg.Uses == 1 => (F(NMSUB|MSUB|NMADD|MADD)D x y z)
836836
(F(MADD|NMADD|MSUB|NMSUB)D x y neg:(FNEGD z)) && neg.Uses == 1 => (F(MSUB|NMSUB|MADD|NMADD)D x y z)
837+
838+
//
839+
// Optimisations for rva22u64 and above.
840+
//
841+
842+
// Integer minimum and maximum.
843+
(Min64 x y) && buildcfg.GORISCV64 >= 22 => (MIN x y)
844+
(Max64 x y) && buildcfg.GORISCV64 >= 22 => (MAX x y)
845+
(Min64u x y) && buildcfg.GORISCV64 >= 22 => (MINU x y)
846+
(Max64u x y) && buildcfg.GORISCV64 >= 22 => (MAXU x y)

src/cmd/compile/internal/ssa/_gen/RISCV64Ops.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,12 @@ func init() {
235235
{name: "XOR", argLength: 2, reg: gp21, asm: "XOR", commutative: true}, // arg0 ^ arg1
236236
{name: "XORI", argLength: 1, reg: gp11, asm: "XORI", aux: "Int64"}, // arg0 ^ auxint
237237

238+
// Minimum and maximum
239+
{name: "MIN", argLength: 2, reg: gp21, asm: "MIN", commutative: true}, // min(arg0,arg1), signed
240+
{name: "MAX", argLength: 2, reg: gp21, asm: "MAX", commutative: true}, // max(arg0,arg1), signed
241+
{name: "MINU", argLength: 2, reg: gp21, asm: "MINU", commutative: true}, // min(arg0,arg1), unsigned
242+
{name: "MAXU", argLength: 2, reg: gp21, asm: "MAXU", commutative: true}, // max(arg0,arg1), unsigned
243+
238244
// Generate boolean values
239245
{name: "SEQZ", argLength: 1, reg: gp11, asm: "SEQZ"}, // arg0 == 0, result is 0 or 1
240246
{name: "SNEZ", argLength: 1, reg: gp11, asm: "SNEZ"}, // arg0 != 0, result is 0 or 1

src/cmd/compile/internal/ssa/_gen/genericOps.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,12 @@ var genericOps = []opData{
285285
{name: "Abs", argLength: 1}, // absolute value arg0
286286
{name: "Copysign", argLength: 2}, // copy sign from arg0 to arg1
287287

288+
// Integer min/max implementation, if hardware is available.
289+
{name: "Min64", argLength: 2}, // min(arg0,arg1), signed
290+
{name: "Max64", argLength: 2}, // max(arg0,arg1), signed
291+
{name: "Min64u", argLength: 2}, // min(arg0,arg1), unsigned
292+
{name: "Max64u", argLength: 2}, // max(arg0,arg1), unsigned
293+
288294
// Float min/max implementation, if hardware is available.
289295
{name: "Min64F", argLength: 2}, // min(arg0,arg1)
290296
{name: "Min32F", argLength: 2}, // min(arg0,arg1)

src/cmd/compile/internal/ssa/opGen.go

Lines changed: 88 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cmd/compile/internal/ssa/rewriteRISCV64.go

Lines changed: 81 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cmd/compile/internal/ssagen/ssa.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3785,6 +3785,25 @@ func (s *state) minMax(n *ir.CallExpr) *ssa.Value {
37853785
})
37863786
}
37873787

3788+
if typ.IsInteger() {
3789+
if Arch.LinkArch.Family == sys.RISCV64 && buildcfg.GORISCV64 >= 22 && typ.Size() == 8 {
3790+
var op ssa.Op
3791+
switch {
3792+
case typ.IsSigned() && n.Op() == ir.OMIN:
3793+
op = ssa.OpMin64
3794+
case typ.IsSigned() && n.Op() == ir.OMAX:
3795+
op = ssa.OpMax64
3796+
case typ.IsUnsigned() && n.Op() == ir.OMIN:
3797+
op = ssa.OpMin64u
3798+
case typ.IsUnsigned() && n.Op() == ir.OMAX:
3799+
op = ssa.OpMax64u
3800+
}
3801+
return fold(func(x, a *ssa.Value) *ssa.Value {
3802+
return s.newValue2(op, typ, x, a)
3803+
})
3804+
}
3805+
}
3806+
37883807
lt := s.ssaOp(ir.OLT, typ)
37893808

37903809
return fold(func(x, a *ssa.Value) *ssa.Value {

0 commit comments

Comments
 (0)