Skip to content

Commit 074b73b

Browse files
committed
cmd/compile: fix s390x load-combining rules
MOVD{reg,nop} operations (added in CL 36256) inserted to preserve type information were blocking the load-combining rules. Fix this by merging type changes into loads wherever possible. Fixes #19059. Change-Id: I8a1df06eb0f231b40ae43107d4a3bd0b9c441b59 Reviewed-on: https://go-review.googlesource.com/36843 Run-TryBot: Michael Munday <[email protected]> Reviewed-by: Keith Randall <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent 40c27ed commit 074b73b

File tree

3 files changed

+674
-21
lines changed

3 files changed

+674
-21
lines changed

src/cmd/compile/internal/gc/asm_test.go

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,33 +227,64 @@ func f(b []byte) uint32 {
227227
return binary.LittleEndian.Uint32(b)
228228
}
229229
`,
230-
[]string{"\tMOVWZ\t\\(.*\\),"},
230+
[]string{"\tMOVWBR\t\\(.*\\),"},
231231
},
232232
{"s390x", "linux", `
233233
import "encoding/binary"
234234
func f(b []byte, i int) uint32 {
235235
return binary.LittleEndian.Uint32(b[i:])
236236
}
237237
`,
238-
[]string{"\tMOVWZ\t\\(.*\\)\\(.*\\*1\\),"},
238+
[]string{"\tMOVWBR\t\\(.*\\)\\(.*\\*1\\),"},
239239
},
240240
{"s390x", "linux", `
241241
import "encoding/binary"
242242
func f(b []byte) uint64 {
243243
return binary.LittleEndian.Uint64(b)
244244
}
245245
`,
246-
[]string{"\tMOVD\t\\(.*\\),"},
246+
[]string{"\tMOVDBR\t\\(.*\\),"},
247247
},
248248
{"s390x", "linux", `
249249
import "encoding/binary"
250250
func f(b []byte, i int) uint64 {
251251
return binary.LittleEndian.Uint64(b[i:])
252252
}
253+
`,
254+
[]string{"\tMOVDBR\t\\(.*\\)\\(.*\\*1\\),"},
255+
},
256+
{"s390x", "linux", `
257+
import "encoding/binary"
258+
func f(b []byte) uint32 {
259+
return binary.BigEndian.Uint32(b)
260+
}
261+
`,
262+
[]string{"\tMOVWZ\t\\(.*\\),"},
263+
},
264+
{"s390x", "linux", `
265+
import "encoding/binary"
266+
func f(b []byte, i int) uint32 {
267+
return binary.BigEndian.Uint32(b[i:])
268+
}
269+
`,
270+
[]string{"\tMOVWZ\t\\(.*\\)\\(.*\\*1\\),"},
271+
},
272+
{"s390x", "linux", `
273+
import "encoding/binary"
274+
func f(b []byte) uint64 {
275+
return binary.BigEndian.Uint64(b)
276+
}
277+
`,
278+
[]string{"\tMOVD\t\\(.*\\),"},
279+
},
280+
{"s390x", "linux", `
281+
import "encoding/binary"
282+
func f(b []byte, i int) uint64 {
283+
return binary.BigEndian.Uint64(b[i:])
284+
}
253285
`,
254286
[]string{"\tMOVD\t\\(.*\\)\\(.*\\*1\\),"},
255287
},
256-
// TODO: s390x big-endian tests.
257288

258289
// Structure zeroing. See issue #18370.
259290
{"amd64", "linux", `

src/cmd/compile/internal/ssa/gen/S390X.rules

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,40 @@
457457
// MOVDnop doesn't emit instruction, only for ensuring the type.
458458
(MOVDreg x) && x.Uses == 1 -> (MOVDnop x)
459459

460+
// Fold type changes into loads.
461+
(MOVDreg <t> x:(MOVBZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZload <t> [off] {sym} ptr mem)
462+
(MOVDreg <t> x:(MOVBload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBload <t> [off] {sym} ptr mem)
463+
(MOVDreg <t> x:(MOVHZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZload <t> [off] {sym} ptr mem)
464+
(MOVDreg <t> x:(MOVHload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHload <t> [off] {sym} ptr mem)
465+
(MOVDreg <t> x:(MOVWZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZload <t> [off] {sym} ptr mem)
466+
(MOVDreg <t> x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWload <t> [off] {sym} ptr mem)
467+
(MOVDreg <t> x:(MOVDload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVDload <t> [off] {sym} ptr mem)
468+
469+
(MOVDnop <t> x:(MOVBZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZload <t> [off] {sym} ptr mem)
470+
(MOVDnop <t> x:(MOVBload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBload <t> [off] {sym} ptr mem)
471+
(MOVDnop <t> x:(MOVHZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZload <t> [off] {sym} ptr mem)
472+
(MOVDnop <t> x:(MOVHload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHload <t> [off] {sym} ptr mem)
473+
(MOVDnop <t> x:(MOVWZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZload <t> [off] {sym} ptr mem)
474+
(MOVDnop <t> x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWload <t> [off] {sym} ptr mem)
475+
(MOVDnop <t> x:(MOVDload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVDload <t> [off] {sym} ptr mem)
476+
477+
// TODO(mundaym): uncomment rules once signed indexed loads are added.
478+
(MOVDreg <t> x:(MOVBZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZloadidx <t> [off] {sym} ptr idx mem)
479+
//(MOVDreg <t> x:(MOVBloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBloadidx <t> [off] {sym} ptr idx mem)
480+
(MOVDreg <t> x:(MOVHZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZloadidx <t> [off] {sym} ptr idx mem)
481+
//(MOVDreg <t> x:(MOVHloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHloadidx <t> [off] {sym} ptr idx mem)
482+
(MOVDreg <t> x:(MOVWZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZloadidx <t> [off] {sym} ptr idx mem)
483+
//(MOVDreg <t> x:(MOVWloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWloadidx <t> [off] {sym} ptr idx mem)
484+
(MOVDreg <t> x:(MOVDloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVDloadidx <t> [off] {sym} ptr idx mem)
485+
486+
(MOVDnop <t> x:(MOVBZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZloadidx <t> [off] {sym} ptr idx mem)
487+
//(MOVDnop <t> x:(MOVBloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBloadidx <t> [off] {sym} ptr idx mem)
488+
(MOVDnop <t> x:(MOVHZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZloadidx <t> [off] {sym} ptr idx mem)
489+
//(MOVDnop <t> x:(MOVHloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHloadidx <t> [off] {sym} ptr idx mem)
490+
(MOVDnop <t> x:(MOVWZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZloadidx <t> [off] {sym} ptr idx mem)
491+
//(MOVDnop <t> x:(MOVWloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWloadidx <t> [off] {sym} ptr idx mem)
492+
(MOVDnop <t> x:(MOVDloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVDloadidx <t> [off] {sym} ptr idx mem)
493+
460494
// Fold sign extensions into conditional moves of constants.
461495
// Designed to remove the MOVBZreg inserted by the If lowering.
462496
(MOVBZreg x:(MOVDLT (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)

0 commit comments

Comments
 (0)