From 4373754bc990fc13b27ae823f977bc6328cc331e Mon Sep 17 00:00:00 2001 From: Michael Munday Date: Sat, 30 Aug 2025 21:53:37 +0100 Subject: [PATCH] cmd/compile: add store to load forwarding rules on riscv64 Adds the equivalent integer variants of the floating point rules added in CL 599235. Change-Id: Ibe03c26383059821d99cea2337799e6416b4c581 Reviewed-on: https://go-review.googlesource.com/c/go/+/700175 Reviewed-by: Michael Pratt Auto-Submit: Keith Randall Reviewed-by: Julian Zhu LUCI-TryBot-Result: Go LUCI Reviewed-by: Keith Randall Reviewed-by: Keith Randall --- .../compile/internal/ssa/_gen/RISCV64.rules | 2 + .../compile/internal/ssa/rewriteRISCV64.go | 133 ++++++++++++++++++ 2 files changed, 135 insertions(+) diff --git a/src/cmd/compile/internal/ssa/_gen/RISCV64.rules b/src/cmd/compile/internal/ssa/_gen/RISCV64.rules index 151f3412ce..821f822746 100644 --- a/src/cmd/compile/internal/ssa/_gen/RISCV64.rules +++ b/src/cmd/compile/internal/ssa/_gen/RISCV64.rules @@ -716,6 +716,8 @@ (MOVWUreg x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWUload [off] {sym} ptr mem) // Replace load from same location as preceding store with copy. +(MOV(D|W|H|B)load [off] {sym} ptr1 (MOV(D|W|H|B)store [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => (MOV(D|W|H|B)reg x) +(MOV(W|H|B)Uload [off] {sym} ptr1 (MOV(W|H|B)store [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => (MOV(W|H|B)Ureg x) (MOVDload [off] {sym} ptr1 (FMOVDstore [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => (FMVXD x) (FMOVDload [off] {sym} ptr1 (MOVDstore [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => (FMVDX x) (MOVWload [off] {sym} ptr1 (FMOVWstore [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => (FMVXS x) diff --git a/src/cmd/compile/internal/ssa/rewriteRISCV64.go b/src/cmd/compile/internal/ssa/rewriteRISCV64.go index 1e80669672..e2c400b0c5 100644 --- a/src/cmd/compile/internal/ssa/rewriteRISCV64.go +++ b/src/cmd/compile/internal/ssa/rewriteRISCV64.go @@ -4740,6 +4740,25 @@ func rewriteValueRISCV64_OpRISCV64MOVBUload(v *Value) bool { v.AddArg2(base, mem) return true } + // match: (MOVBUload [off] {sym} ptr1 (MOVBstore [off] {sym} ptr2 x _)) + // cond: isSamePtr(ptr1, ptr2) + // result: (MOVBUreg x) + for { + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) + ptr1 := v_0 + if v_1.Op != OpRISCV64MOVBstore || auxIntToInt32(v_1.AuxInt) != off || auxToSym(v_1.Aux) != sym { + break + } + x := v_1.Args[1] + ptr2 := v_1.Args[0] + if !(isSamePtr(ptr1, ptr2)) { + break + } + v.reset(OpRISCV64MOVBUreg) + v.AddArg(x) + return true + } return false } func rewriteValueRISCV64_OpRISCV64MOVBUreg(v *Value) bool { @@ -5049,6 +5068,25 @@ func rewriteValueRISCV64_OpRISCV64MOVBload(v *Value) bool { v.AddArg2(base, mem) return true } + // match: (MOVBload [off] {sym} ptr1 (MOVBstore [off] {sym} ptr2 x _)) + // cond: isSamePtr(ptr1, ptr2) + // result: (MOVBreg x) + for { + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) + ptr1 := v_0 + if v_1.Op != OpRISCV64MOVBstore || auxIntToInt32(v_1.AuxInt) != off || auxToSym(v_1.Aux) != sym { + break + } + x := v_1.Args[1] + ptr2 := v_1.Args[0] + if !(isSamePtr(ptr1, ptr2)) { + break + } + v.reset(OpRISCV64MOVBreg) + v.AddArg(x) + return true + } return false } func rewriteValueRISCV64_OpRISCV64MOVBreg(v *Value) bool { @@ -5397,6 +5435,25 @@ func rewriteValueRISCV64_OpRISCV64MOVDload(v *Value) bool { v.AddArg2(base, mem) return true } + // match: (MOVDload [off] {sym} ptr1 (MOVDstore [off] {sym} ptr2 x _)) + // cond: isSamePtr(ptr1, ptr2) + // result: (MOVDreg x) + for { + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) + ptr1 := v_0 + if v_1.Op != OpRISCV64MOVDstore || auxIntToInt32(v_1.AuxInt) != off || auxToSym(v_1.Aux) != sym { + break + } + x := v_1.Args[1] + ptr2 := v_1.Args[0] + if !(isSamePtr(ptr1, ptr2)) { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } // match: (MOVDload [off] {sym} ptr1 (FMOVDstore [off] {sym} ptr2 x _)) // cond: isSamePtr(ptr1, ptr2) // result: (FMVXD x) @@ -5616,6 +5673,25 @@ func rewriteValueRISCV64_OpRISCV64MOVHUload(v *Value) bool { v.AddArg2(base, mem) return true } + // match: (MOVHUload [off] {sym} ptr1 (MOVHstore [off] {sym} ptr2 x _)) + // cond: isSamePtr(ptr1, ptr2) + // result: (MOVHUreg x) + for { + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) + ptr1 := v_0 + if v_1.Op != OpRISCV64MOVHstore || auxIntToInt32(v_1.AuxInt) != off || auxToSym(v_1.Aux) != sym { + break + } + x := v_1.Args[1] + ptr2 := v_1.Args[0] + if !(isSamePtr(ptr1, ptr2)) { + break + } + v.reset(OpRISCV64MOVHUreg) + v.AddArg(x) + return true + } return false } func rewriteValueRISCV64_OpRISCV64MOVHUreg(v *Value) bool { @@ -5782,6 +5858,25 @@ func rewriteValueRISCV64_OpRISCV64MOVHload(v *Value) bool { v.AddArg2(base, mem) return true } + // match: (MOVHload [off] {sym} ptr1 (MOVHstore [off] {sym} ptr2 x _)) + // cond: isSamePtr(ptr1, ptr2) + // result: (MOVHreg x) + for { + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) + ptr1 := v_0 + if v_1.Op != OpRISCV64MOVHstore || auxIntToInt32(v_1.AuxInt) != off || auxToSym(v_1.Aux) != sym { + break + } + x := v_1.Args[1] + ptr2 := v_1.Args[0] + if !(isSamePtr(ptr1, ptr2)) { + break + } + v.reset(OpRISCV64MOVHreg) + v.AddArg(x) + return true + } return false } func rewriteValueRISCV64_OpRISCV64MOVHreg(v *Value) bool { @@ -6141,6 +6236,25 @@ func rewriteValueRISCV64_OpRISCV64MOVWUload(v *Value) bool { v.AddArg2(base, mem) return true } + // match: (MOVWUload [off] {sym} ptr1 (MOVWstore [off] {sym} ptr2 x _)) + // cond: isSamePtr(ptr1, ptr2) + // result: (MOVWUreg x) + for { + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) + ptr1 := v_0 + if v_1.Op != OpRISCV64MOVWstore || auxIntToInt32(v_1.AuxInt) != off || auxToSym(v_1.Aux) != sym { + break + } + x := v_1.Args[1] + ptr2 := v_1.Args[0] + if !(isSamePtr(ptr1, ptr2)) { + break + } + v.reset(OpRISCV64MOVWUreg) + v.AddArg(x) + return true + } // match: (MOVWUload [off] {sym} ptr1 (FMOVWstore [off] {sym} ptr2 x _)) // cond: isSamePtr(ptr1, ptr2) // result: (MOVWUreg (FMVXS x)) @@ -6352,6 +6466,25 @@ func rewriteValueRISCV64_OpRISCV64MOVWload(v *Value) bool { v.AddArg2(base, mem) return true } + // match: (MOVWload [off] {sym} ptr1 (MOVWstore [off] {sym} ptr2 x _)) + // cond: isSamePtr(ptr1, ptr2) + // result: (MOVWreg x) + for { + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) + ptr1 := v_0 + if v_1.Op != OpRISCV64MOVWstore || auxIntToInt32(v_1.AuxInt) != off || auxToSym(v_1.Aux) != sym { + break + } + x := v_1.Args[1] + ptr2 := v_1.Args[0] + if !(isSamePtr(ptr1, ptr2)) { + break + } + v.reset(OpRISCV64MOVWreg) + v.AddArg(x) + return true + } // match: (MOVWload [off] {sym} ptr1 (FMOVWstore [off] {sym} ptr2 x _)) // cond: isSamePtr(ptr1, ptr2) // result: (FMVXS x) -- 2.52.0