From 5c5f217b635d5bcbbda482f92264265eb61c13f2 Mon Sep 17 00:00:00 2001 From: Michael Munday Date: Thu, 25 Apr 2019 09:41:46 -0400 Subject: [PATCH] cmd/compile: improve s390x sign/zero extension removal This CL gets rid of the MOVDreg and MOVDnop SSA operations on s390x. They were originally inserted to help avoid situations where a sign/zero extension was elided but a spill invalidated the optimization. It's not really clear we need to do this though (amd64 doesn't have these ops for example) so long as we are careful when removing sign/zero extensions. Also, the MOVDreg technique doesn't work if the register is spilled before the MOVDreg op (I haven't seen that in practice). Removing these ops reduces the complexity of the rules and also allows us to unblock optimizations. For example, the compiler can now merge the loads in binary.{Big,Little}Endian.PutUint16 which it wasn't able to do before. This CL reduces the size of the .text section in the go tool by about 4.7KB (0.09%). Change-Id: Icaddae7f2e4f9b2debb6fabae845adb3f73b41db Reviewed-on: https://go-review.googlesource.com/c/go/+/173897 Run-TryBot: Michael Munday TryBot-Result: Gobot Gobot Reviewed-by: Cherry Zhang --- src/cmd/compile/internal/s390x/ssa.go | 7 +- src/cmd/compile/internal/ssa/gen/S390X.rules | 277 +- src/cmd/compile/internal/ssa/gen/S390XOps.go | 3 - src/cmd/compile/internal/ssa/opGen.go | 28 - src/cmd/compile/internal/ssa/rewriteS390X.go | 3028 ++++++++---------- test/codegen/memcombine.go | 16 + 6 files changed, 1435 insertions(+), 1924 deletions(-) diff --git a/src/cmd/compile/internal/s390x/ssa.go b/src/cmd/compile/internal/s390x/ssa.go index 7ddebe7b64..fc828946b9 100644 --- a/src/cmd/compile/internal/s390x/ssa.go +++ b/src/cmd/compile/internal/s390x/ssa.go @@ -482,7 +482,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p.To.Type = obj.TYPE_MEM p.To.Reg = v.Args[0].Reg() gc.AddAux2(&p.To, v, sc.Off()) - case ssa.OpCopy, ssa.OpS390XMOVDreg: + case ssa.OpCopy: if v.Type.IsMemory() { return } @@ -491,11 +491,6 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { if x != y { opregreg(s, moveByType(v.Type), y, x) } - case ssa.OpS390XMOVDnop: - if v.Reg() != v.Args[0].Reg() { - v.Fatalf("input[0] and output not in same register %s", v.LongString()) - } - // nothing to do case ssa.OpLoadReg: if v.Type.IsFlags() { v.Fatalf("load flags not implemented: %v", v.LongString()) diff --git a/src/cmd/compile/internal/ssa/gen/S390X.rules b/src/cmd/compile/internal/ssa/gen/S390X.rules index ee670a908d..91f88a1d63 100644 --- a/src/cmd/compile/internal/ssa/gen/S390X.rules +++ b/src/cmd/compile/internal/ssa/gen/S390X.rules @@ -443,61 +443,121 @@ // *************************** // TODO: Should the optimizations be a separate pass? -// Fold unnecessary type conversions. -(MOVDreg x) && t.Compare(x.Type) == types.CMPeq -> x -(MOVDnop x) && t.Compare(x.Type) == types.CMPeq -> x - -// Propagate constants through type conversions. -(MOVDreg (MOVDconst [c])) -> (MOVDconst [c]) -(MOVDnop (MOVDconst [c])) -> (MOVDconst [c]) - -// If a register move has only 1 use, just use the same register without emitting instruction. -// MOVDnop doesn't emit instruction, only for ensuring the type. -(MOVDreg x) && x.Uses == 1 -> (MOVDnop x) - -// Fold type changes into loads. -(MOVDreg x:(MOVBZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZload [off] {sym} ptr mem) -(MOVDreg x:(MOVBload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBload [off] {sym} ptr mem) -(MOVDreg x:(MOVHZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZload [off] {sym} ptr mem) -(MOVDreg x:(MOVHload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHload [off] {sym} ptr mem) -(MOVDreg x:(MOVWZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZload [off] {sym} ptr mem) -(MOVDreg x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWload [off] {sym} ptr mem) -(MOVDreg x:(MOVDload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVDload [off] {sym} ptr mem) - -(MOVDnop x:(MOVBZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZload [off] {sym} ptr mem) -(MOVDnop x:(MOVBload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBload [off] {sym} ptr mem) -(MOVDnop x:(MOVHZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZload [off] {sym} ptr mem) -(MOVDnop x:(MOVHload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHload [off] {sym} ptr mem) -(MOVDnop x:(MOVWZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZload [off] {sym} ptr mem) -(MOVDnop x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWload [off] {sym} ptr mem) -(MOVDnop x:(MOVDload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVDload [off] {sym} ptr mem) - -(MOVDreg x:(MOVBZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZloadidx [off] {sym} ptr idx mem) -(MOVDreg x:(MOVBloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBloadidx [off] {sym} ptr idx mem) -(MOVDreg x:(MOVHZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZloadidx [off] {sym} ptr idx mem) -(MOVDreg x:(MOVHloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHloadidx [off] {sym} ptr idx mem) -(MOVDreg x:(MOVWZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZloadidx [off] {sym} ptr idx mem) -(MOVDreg x:(MOVWloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWloadidx [off] {sym} ptr idx mem) -(MOVDreg x:(MOVDloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVDloadidx [off] {sym} ptr idx mem) - -(MOVDnop x:(MOVBZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZloadidx [off] {sym} ptr idx mem) -(MOVDnop x:(MOVBloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBloadidx [off] {sym} ptr idx mem) -(MOVDnop x:(MOVHZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZloadidx [off] {sym} ptr idx mem) -(MOVDnop x:(MOVHloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHloadidx [off] {sym} ptr idx mem) -(MOVDnop x:(MOVWZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZloadidx [off] {sym} ptr idx mem) -(MOVDnop x:(MOVWloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWloadidx [off] {sym} ptr idx mem) -(MOVDnop x:(MOVDloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVDloadidx [off] {sym} ptr idx mem) - -// Fold sign extensions into conditional moves of constants. -// Designed to remove the MOVBZreg inserted by the If lowering. -(MOVBZreg x:(MOVDLT (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x) -(MOVBZreg x:(MOVDLE (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x) -(MOVBZreg x:(MOVDGT (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x) -(MOVBZreg x:(MOVDGE (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x) -(MOVBZreg x:(MOVDEQ (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x) -(MOVBZreg x:(MOVDNE (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x) -(MOVBZreg x:(MOVDGTnoinv (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x) -(MOVBZreg x:(MOVDGEnoinv (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x) +// Note: when removing unnecessary sign/zero extensions. +// +// After a value is spilled it is restored using a sign- or zero-extension +// to register-width as appropriate for its type. For example, a uint8 will +// be restored using a MOVBZ (llgc) instruction which will zero extend the +// 8-bit value to 64-bits. +// +// This is a hazard when folding sign- and zero-extensions since we need to +// ensure not only that the value in the argument register is correctly +// extended but also that it will still be correctly extended if it is +// spilled and restored. +// +// In general this means we need type checks when the RHS of a rule is an +// OpCopy (i.e. "(... x:(...) ...) -> x"). + +// Merge double extensions. +(MOV(H|HZ)reg e:(MOV(B|BZ)reg x)) && clobberIfDead(e) -> (MOV(B|BZ)reg x) +(MOV(W|WZ)reg e:(MOV(B|BZ)reg x)) && clobberIfDead(e) -> (MOV(B|BZ)reg x) +(MOV(W|WZ)reg e:(MOV(H|HZ)reg x)) && clobberIfDead(e) -> (MOV(H|HZ)reg x) + +// Bypass redundant sign extensions. +(MOV(B|BZ)reg e:(MOVBreg x)) && clobberIfDead(e) -> (MOV(B|BZ)reg x) +(MOV(B|BZ)reg e:(MOVHreg x)) && clobberIfDead(e) -> (MOV(B|BZ)reg x) +(MOV(B|BZ)reg e:(MOVWreg x)) && clobberIfDead(e) -> (MOV(B|BZ)reg x) +(MOV(H|HZ)reg e:(MOVHreg x)) && clobberIfDead(e) -> (MOV(H|HZ)reg x) +(MOV(H|HZ)reg e:(MOVWreg x)) && clobberIfDead(e) -> (MOV(H|HZ)reg x) +(MOV(W|WZ)reg e:(MOVWreg x)) && clobberIfDead(e) -> (MOV(W|WZ)reg x) + +// Bypass redundant zero extensions. +(MOV(B|BZ)reg e:(MOVBZreg x)) && clobberIfDead(e) -> (MOV(B|BZ)reg x) +(MOV(B|BZ)reg e:(MOVHZreg x)) && clobberIfDead(e) -> (MOV(B|BZ)reg x) +(MOV(B|BZ)reg e:(MOVWZreg x)) && clobberIfDead(e) -> (MOV(B|BZ)reg x) +(MOV(H|HZ)reg e:(MOVHZreg x)) && clobberIfDead(e) -> (MOV(H|HZ)reg x) +(MOV(H|HZ)reg e:(MOVWZreg x)) && clobberIfDead(e) -> (MOV(H|HZ)reg x) +(MOV(W|WZ)reg e:(MOVWZreg x)) && clobberIfDead(e) -> (MOV(W|WZ)reg x) + +// Remove zero extensions after zero extending load. +// Note: take care that if x is spilled it is restored correctly. +(MOV(B|H|W)Zreg x:(MOVBZload _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 1) -> x +(MOV(B|H|W)Zreg x:(MOVBZloadidx _ _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 1) -> x +(MOV(H|W)Zreg x:(MOVHZload _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 2) -> x +(MOV(H|W)Zreg x:(MOVHZloadidx _ _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 2) -> x +(MOVWZreg x:(MOVWZload _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 4) -> x +(MOVWZreg x:(MOVWZloadidx _ _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 4) -> x + +// Remove sign extensions after sign extending load. +// Note: take care that if x is spilled it is restored correctly. +(MOV(B|H|W)reg x:(MOVBload _ _)) && (x.Type.IsSigned() || x.Type.Size() == 8) -> x +(MOV(B|H|W)reg x:(MOVBloadidx _ _ _)) && (x.Type.IsSigned() || x.Type.Size() == 8) -> x +(MOV(H|W)reg x:(MOVHload _ _)) && (x.Type.IsSigned() || x.Type.Size() == 8) -> x +(MOV(H|W)reg x:(MOVHloadidx _ _ _)) && (x.Type.IsSigned() || x.Type.Size() == 8) -> x +(MOVWreg x:(MOVWload _ _)) && (x.Type.IsSigned() || x.Type.Size() == 8) -> x +(MOVWreg x:(MOVWloadidx _ _ _)) && (x.Type.IsSigned() || x.Type.Size() == 8) -> x + +// Remove sign extensions after zero extending load. +// These type checks are probably unnecessary but do them anyway just in case. +(MOV(H|W)reg x:(MOVBZload _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 1) -> x +(MOV(H|W)reg x:(MOVBZloadidx _ _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 1) -> x +(MOVWreg x:(MOVHZload _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 2) -> x +(MOVWreg x:(MOVHZloadidx _ _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 2) -> x + +// Fold sign and zero extensions into loads. +// +// Note: The combined instruction must end up in the same block +// as the original load. If not, we end up making a value with +// memory type live in two different blocks, which can lead to +// multiple memory values alive simultaneously. +// +// Make sure we don't combine these ops if the load has another use. +// This prevents a single load from being split into multiple loads +// which then might return different values. See test/atomicload.go. +(MOV(B|H|W)Zreg x:(MOV(B|H|W)load [o] {s} p mem)) + && x.Uses == 1 + && clobber(x) + -> @x.Block (MOV(B|H|W)Zload [o] {s} p mem) +(MOV(B|H|W)reg x:(MOV(B|H|W)Zload [o] {s} p mem)) + && x.Uses == 1 + && clobber(x) + -> @x.Block (MOV(B|H|W)load [o] {s} p mem) +(MOV(B|H|W)Zreg x:(MOV(B|H|W)loadidx [o] {s} p i mem)) + && x.Uses == 1 + && clobber(x) + -> @x.Block (MOV(B|H|W)Zloadidx [o] {s} p i mem) +(MOV(B|H|W)reg x:(MOV(B|H|W)Zloadidx [o] {s} p i mem)) + && x.Uses == 1 + && clobber(x) + -> @x.Block (MOV(B|H|W)loadidx [o] {s} p i mem) + +// Remove zero extensions after argument load. +(MOVBZreg x:(Arg )) && !t.IsSigned() && t.Size() == 1 -> x +(MOVHZreg x:(Arg )) && !t.IsSigned() && t.Size() <= 2 -> x +(MOVWZreg x:(Arg )) && !t.IsSigned() && t.Size() <= 4 -> x + +// Remove sign extensions after argument load. +(MOVBreg x:(Arg )) && t.IsSigned() && t.Size() == 1 -> x +(MOVHreg x:(Arg )) && t.IsSigned() && t.Size() <= 2 -> x +(MOVWreg x:(Arg )) && t.IsSigned() && t.Size() <= 4 -> x + +// Fold zero extensions into constants. +(MOVBZreg (MOVDconst [c])) -> (MOVDconst [int64( uint8(c))]) +(MOVHZreg (MOVDconst [c])) -> (MOVDconst [int64(uint16(c))]) +(MOVWZreg (MOVDconst [c])) -> (MOVDconst [int64(uint32(c))]) + +// Fold sign extensions into constants. +(MOVBreg (MOVDconst [c])) -> (MOVDconst [int64( int8(c))]) +(MOVHreg (MOVDconst [c])) -> (MOVDconst [int64(int16(c))]) +(MOVWreg (MOVDconst [c])) -> (MOVDconst [int64(int32(c))]) + +// Remove zero extension of conditional move. +// Note: only for MOVBZreg for now since it is added as part of 'if' statement lowering. +(MOVBZreg x:(MOVD(LT|LE|GT|GE|EQ|NE|GTnoinv|GEnoinv) (MOVDconst [c]) (MOVDconst [d]) _)) + && int64(uint8(c)) == c + && int64(uint8(d)) == d + && (!x.Type.IsSigned() || x.Type.Size() > 1) + -> x // Fold boolean tests into blocks. (NE (CMPWconst [0] (MOVDLT (MOVDconst [0]) (MOVDconst [1]) cmp)) yes no) -> (LT cmp yes no) @@ -547,12 +607,12 @@ -> (S(LD|RD|RAD|LW|RW|RAW) x (ANDWconst [c&63] y)) (S(LD|RD|RAD|LW|RW|RAW) x (ANDWconst [c] y)) && c&63 == 63 -> (S(LD|RD|RAD|LW|RW|RAW) x y) -(SLD x (MOV(D|W|H|B|WZ|HZ|BZ)reg y)) -> (SLD x y) -(SRD x (MOV(D|W|H|B|WZ|HZ|BZ)reg y)) -> (SRD x y) -(SRAD x (MOV(D|W|H|B|WZ|HZ|BZ)reg y)) -> (SRAD x y) -(SLW x (MOV(D|W|H|B|WZ|HZ|BZ)reg y)) -> (SLW x y) -(SRW x (MOV(D|W|H|B|WZ|HZ|BZ)reg y)) -> (SRW x y) -(SRAW x (MOV(D|W|H|B|WZ|HZ|BZ)reg y)) -> (SRAW x y) +(SLD x (MOV(W|H|B|WZ|HZ|BZ)reg y)) -> (SLD x y) +(SRD x (MOV(W|H|B|WZ|HZ|BZ)reg y)) -> (SRD x y) +(SRAD x (MOV(W|H|B|WZ|HZ|BZ)reg y)) -> (SRAD x y) +(SLW x (MOV(W|H|B|WZ|HZ|BZ)reg y)) -> (SLW x y) +(SRW x (MOV(W|H|B|WZ|HZ|BZ)reg y)) -> (SRW x y) +(SRAW x (MOV(W|H|B|WZ|HZ|BZ)reg y)) -> (SRAW x y) // Constant rotate generation (RLL x (MOVDconst [c])) -> (RLLconst x [c&31]) @@ -615,99 +675,8 @@ (MOVDEQ x y (InvertFlags cmp)) -> (MOVDEQ x y cmp) (MOVDNE x y (InvertFlags cmp)) -> (MOVDNE x y cmp) -// don't extend after proper load -(MOVBreg x:(MOVBload _ _)) -> (MOVDreg x) -(MOVBZreg x:(MOVBZload _ _)) -> (MOVDreg x) -(MOVHreg x:(MOVBload _ _)) -> (MOVDreg x) -(MOVHreg x:(MOVBZload _ _)) -> (MOVDreg x) -(MOVHreg x:(MOVHload _ _)) -> (MOVDreg x) -(MOVHZreg x:(MOVBZload _ _)) -> (MOVDreg x) -(MOVHZreg x:(MOVHZload _ _)) -> (MOVDreg x) -(MOVWreg x:(MOVBload _ _)) -> (MOVDreg x) -(MOVWreg x:(MOVBZload _ _)) -> (MOVDreg x) -(MOVWreg x:(MOVHload _ _)) -> (MOVDreg x) -(MOVWreg x:(MOVHZload _ _)) -> (MOVDreg x) -(MOVWreg x:(MOVWload _ _)) -> (MOVDreg x) -(MOVWZreg x:(MOVBZload _ _)) -> (MOVDreg x) -(MOVWZreg x:(MOVHZload _ _)) -> (MOVDreg x) -(MOVWZreg x:(MOVWZload _ _)) -> (MOVDreg x) - -// don't extend if argument is already extended -(MOVBreg x:(Arg )) && is8BitInt(t) && isSigned(t) -> (MOVDreg x) -(MOVBZreg x:(Arg )) && is8BitInt(t) && !isSigned(t) -> (MOVDreg x) -(MOVHreg x:(Arg )) && (is8BitInt(t) || is16BitInt(t)) && isSigned(t) -> (MOVDreg x) -(MOVHZreg x:(Arg )) && (is8BitInt(t) || is16BitInt(t)) && !isSigned(t) -> (MOVDreg x) -(MOVWreg x:(Arg )) && (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && isSigned(t) -> (MOVDreg x) -(MOVWZreg x:(Arg )) && (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && !isSigned(t) -> (MOVDreg x) - -// fold double extensions -(MOVBreg x:(MOVBreg _)) -> (MOVDreg x) -(MOVBZreg x:(MOVBZreg _)) -> (MOVDreg x) -(MOVHreg x:(MOVBreg _)) -> (MOVDreg x) -(MOVHreg x:(MOVBZreg _)) -> (MOVDreg x) -(MOVHreg x:(MOVHreg _)) -> (MOVDreg x) -(MOVHZreg x:(MOVBZreg _)) -> (MOVDreg x) -(MOVHZreg x:(MOVHZreg _)) -> (MOVDreg x) -(MOVWreg x:(MOVBreg _)) -> (MOVDreg x) -(MOVWreg x:(MOVBZreg _)) -> (MOVDreg x) -(MOVWreg x:(MOVHreg _)) -> (MOVDreg x) -(MOVWreg x:(MOVHZreg _)) -> (MOVDreg x) -(MOVWreg x:(MOVWreg _)) -> (MOVDreg x) -(MOVWZreg x:(MOVBZreg _)) -> (MOVDreg x) -(MOVWZreg x:(MOVHZreg _)) -> (MOVDreg x) -(MOVWZreg x:(MOVWZreg _)) -> (MOVDreg x) - -(MOVBreg (MOVBZreg x)) -> (MOVBreg x) -(MOVBZreg (MOVBreg x)) -> (MOVBZreg x) -(MOVHreg (MOVHZreg x)) -> (MOVHreg x) -(MOVHZreg (MOVHreg x)) -> (MOVHZreg x) -(MOVWreg (MOVWZreg x)) -> (MOVWreg x) -(MOVWZreg (MOVWreg x)) -> (MOVWZreg x) - -// fold extensions into constants -(MOVBreg (MOVDconst [c])) -> (MOVDconst [int64(int8(c))]) -(MOVBZreg (MOVDconst [c])) -> (MOVDconst [int64(uint8(c))]) -(MOVHreg (MOVDconst [c])) -> (MOVDconst [int64(int16(c))]) -(MOVHZreg (MOVDconst [c])) -> (MOVDconst [int64(uint16(c))]) -(MOVWreg (MOVDconst [c])) -> (MOVDconst [int64(int32(c))]) -(MOVWZreg (MOVDconst [c])) -> (MOVDconst [int64(uint32(c))]) - -// sign extended loads -// Note: The combined instruction must end up in the same block -// as the original load. If not, we end up making a value with -// memory type live in two different blocks, which can lead to -// multiple memory values alive simultaneously. -// Make sure we don't combine these ops if the load has another use. -// This prevents a single load from being split into multiple loads -// which then might return different values. See test/atomicload.go. -(MOVBreg x:(MOVBZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBload [off] {sym} ptr mem) -(MOVBreg x:(MOVBload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBload [off] {sym} ptr mem) -(MOVBZreg x:(MOVBZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZload [off] {sym} ptr mem) -(MOVBZreg x:(MOVBload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZload [off] {sym} ptr mem) -(MOVHreg x:(MOVHZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHload [off] {sym} ptr mem) -(MOVHreg x:(MOVHload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHload [off] {sym} ptr mem) -(MOVHZreg x:(MOVHZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZload [off] {sym} ptr mem) -(MOVHZreg x:(MOVHload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZload [off] {sym} ptr mem) -(MOVWreg x:(MOVWZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWload [off] {sym} ptr mem) -(MOVWreg x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWload [off] {sym} ptr mem) -(MOVWZreg x:(MOVWZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZload [off] {sym} ptr mem) -(MOVWZreg x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZload [off] {sym} ptr mem) - -(MOVBreg x:(MOVBZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBloadidx [off] {sym} ptr idx mem) -(MOVBreg x:(MOVBloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBloadidx [off] {sym} ptr idx mem) -(MOVBZreg x:(MOVBZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZloadidx [off] {sym} ptr idx mem) -(MOVBZreg x:(MOVBloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZloadidx [off] {sym} ptr idx mem) -(MOVHreg x:(MOVHZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHloadidx [off] {sym} ptr idx mem) -(MOVHreg x:(MOVHloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHloadidx [off] {sym} ptr idx mem) -(MOVHZreg x:(MOVHZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZloadidx [off] {sym} ptr idx mem) -(MOVHZreg x:(MOVHloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZloadidx [off] {sym} ptr idx mem) -(MOVWreg x:(MOVWZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWloadidx [off] {sym} ptr idx mem) -(MOVWreg x:(MOVWloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWloadidx [off] {sym} ptr idx mem) -(MOVWZreg x:(MOVWZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZloadidx [off] {sym} ptr idx mem) -(MOVWZreg x:(MOVWloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZloadidx [off] {sym} ptr idx mem) - // replace load from same location as preceding store with copy -(MOVDload [off] {sym} ptr1 (MOVDstore [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) -> (MOVDreg x) +(MOVDload [off] {sym} ptr1 (MOVDstore [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) -> x (MOVWload [off] {sym} ptr1 (MOVWstore [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) -> (MOVWreg x) (MOVHload [off] {sym} ptr1 (MOVHstore [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) -> (MOVHreg x) (MOVBload [off] {sym} ptr1 (MOVBstore [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) -> (MOVBreg x) @@ -755,7 +724,7 @@ // remove unnecessary FPR <-> GPR moves (LDGR (LGDR x)) -> x -(LGDR (LDGR x)) -> (MOVDreg x) +(LGDR (LDGR x)) -> x // Don't extend before storing (MOVWstore [off] {sym} ptr (MOVWreg x) mem) -> (MOVWstore [off] {sym} ptr x mem) diff --git a/src/cmd/compile/internal/ssa/gen/S390XOps.go b/src/cmd/compile/internal/ssa/gen/S390XOps.go index 943b9c2661..d8d7fd1ef6 100644 --- a/src/cmd/compile/internal/ssa/gen/S390XOps.go +++ b/src/cmd/compile/internal/ssa/gen/S390XOps.go @@ -373,9 +373,6 @@ func init() { {name: "MOVHZreg", argLength: 1, reg: gp11sp, asm: "MOVHZ", typ: "UInt64"}, // zero extend arg0 from int16 to int64 {name: "MOVWreg", argLength: 1, reg: gp11sp, asm: "MOVW", typ: "Int64"}, // sign extend arg0 from int32 to int64 {name: "MOVWZreg", argLength: 1, reg: gp11sp, asm: "MOVWZ", typ: "UInt64"}, // zero extend arg0 from int32 to int64 - {name: "MOVDreg", argLength: 1, reg: gp11sp, asm: "MOVD"}, // move from arg0 - - {name: "MOVDnop", argLength: 1, reg: gp11, resultInArg0: true}, // nop, return arg0 in same register {name: "MOVDconst", reg: gp01, asm: "MOVD", typ: "UInt64", aux: "Int64", rematerializeable: true}, // auxint diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index 5785e361dc..959f1defa8 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -1979,8 +1979,6 @@ const ( OpS390XMOVHZreg OpS390XMOVWreg OpS390XMOVWZreg - OpS390XMOVDreg - OpS390XMOVDnop OpS390XMOVDconst OpS390XLDGR OpS390XLGDR @@ -26605,32 +26603,6 @@ var opcodeTable = [...]opInfo{ }, }, }, - { - name: "MOVDreg", - argLen: 1, - asm: s390x.AMOVD, - reg: regInfo{ - inputs: []inputInfo{ - {0, 56319}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14 SP - }, - outputs: []outputInfo{ - {0, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14 - }, - }, - }, - { - name: "MOVDnop", - argLen: 1, - resultInArg0: true, - reg: regInfo{ - inputs: []inputInfo{ - {0, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14 - }, - outputs: []outputInfo{ - {0, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14 - }, - }, - }, { name: "MOVDconst", auxType: auxInt64, diff --git a/src/cmd/compile/internal/ssa/rewriteS390X.go b/src/cmd/compile/internal/ssa/rewriteS390X.go index 2de5e1b83f..20276ed647 100644 --- a/src/cmd/compile/internal/ssa/rewriteS390X.go +++ b/src/cmd/compile/internal/ssa/rewriteS390X.go @@ -560,13 +560,13 @@ func rewriteValueS390X(v *Value) bool { case OpS390XMOVBZloadidx: return rewriteValueS390X_OpS390XMOVBZloadidx_0(v) case OpS390XMOVBZreg: - return rewriteValueS390X_OpS390XMOVBZreg_0(v) || rewriteValueS390X_OpS390XMOVBZreg_10(v) + return rewriteValueS390X_OpS390XMOVBZreg_0(v) || rewriteValueS390X_OpS390XMOVBZreg_10(v) || rewriteValueS390X_OpS390XMOVBZreg_20(v) case OpS390XMOVBload: return rewriteValueS390X_OpS390XMOVBload_0(v) case OpS390XMOVBloadidx: return rewriteValueS390X_OpS390XMOVBloadidx_0(v) case OpS390XMOVBreg: - return rewriteValueS390X_OpS390XMOVBreg_0(v) + return rewriteValueS390X_OpS390XMOVBreg_0(v) || rewriteValueS390X_OpS390XMOVBreg_10(v) case OpS390XMOVBstore: return rewriteValueS390X_OpS390XMOVBstore_0(v) || rewriteValueS390X_OpS390XMOVBstore_10(v) case OpS390XMOVBstoreconst: @@ -591,10 +591,6 @@ func rewriteValueS390X(v *Value) bool { return rewriteValueS390X_OpS390XMOVDload_0(v) case OpS390XMOVDloadidx: return rewriteValueS390X_OpS390XMOVDloadidx_0(v) - case OpS390XMOVDnop: - return rewriteValueS390X_OpS390XMOVDnop_0(v) || rewriteValueS390X_OpS390XMOVDnop_10(v) - case OpS390XMOVDreg: - return rewriteValueS390X_OpS390XMOVDreg_0(v) || rewriteValueS390X_OpS390XMOVDreg_10(v) case OpS390XMOVDstore: return rewriteValueS390X_OpS390XMOVDstore_0(v) case OpS390XMOVDstoreconst: @@ -638,7 +634,7 @@ func rewriteValueS390X(v *Value) bool { case OpS390XMOVWloadidx: return rewriteValueS390X_OpS390XMOVWloadidx_0(v) case OpS390XMOVWreg: - return rewriteValueS390X_OpS390XMOVWreg_0(v) || rewriteValueS390X_OpS390XMOVWreg_10(v) + return rewriteValueS390X_OpS390XMOVWreg_0(v) || rewriteValueS390X_OpS390XMOVWreg_10(v) || rewriteValueS390X_OpS390XMOVWreg_20(v) case OpS390XMOVWstore: return rewriteValueS390X_OpS390XMOVWstore_0(v) || rewriteValueS390X_OpS390XMOVWstore_10(v) case OpS390XMOVWstoreconst: @@ -682,23 +678,23 @@ func rewriteValueS390X(v *Value) bool { case OpS390XRLLG: return rewriteValueS390X_OpS390XRLLG_0(v) case OpS390XSLD: - return rewriteValueS390X_OpS390XSLD_0(v) || rewriteValueS390X_OpS390XSLD_10(v) + return rewriteValueS390X_OpS390XSLD_0(v) case OpS390XSLW: - return rewriteValueS390X_OpS390XSLW_0(v) || rewriteValueS390X_OpS390XSLW_10(v) + return rewriteValueS390X_OpS390XSLW_0(v) case OpS390XSRAD: - return rewriteValueS390X_OpS390XSRAD_0(v) || rewriteValueS390X_OpS390XSRAD_10(v) + return rewriteValueS390X_OpS390XSRAD_0(v) case OpS390XSRADconst: return rewriteValueS390X_OpS390XSRADconst_0(v) case OpS390XSRAW: - return rewriteValueS390X_OpS390XSRAW_0(v) || rewriteValueS390X_OpS390XSRAW_10(v) + return rewriteValueS390X_OpS390XSRAW_0(v) case OpS390XSRAWconst: return rewriteValueS390X_OpS390XSRAWconst_0(v) case OpS390XSRD: - return rewriteValueS390X_OpS390XSRD_0(v) || rewriteValueS390X_OpS390XSRD_10(v) + return rewriteValueS390X_OpS390XSRD_0(v) case OpS390XSRDconst: return rewriteValueS390X_OpS390XSRDconst_0(v) case OpS390XSRW: - return rewriteValueS390X_OpS390XSRW_0(v) || rewriteValueS390X_OpS390XSRW_10(v) + return rewriteValueS390X_OpS390XSRW_0(v) case OpS390XSTM2: return rewriteValueS390X_OpS390XSTM2_0(v) case OpS390XSTMG2: @@ -10676,14 +10672,15 @@ func rewriteValueS390X_OpS390XLEDBR_0(v *Value) bool { func rewriteValueS390X_OpS390XLGDR_0(v *Value) bool { // match: (LGDR (LDGR x)) // cond: - // result: (MOVDreg x) + // result: x for { v_0 := v.Args[0] if v_0.Op != OpS390XLDGR { break } x := v_0.Args[0] - v.reset(OpS390XMOVDreg) + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } @@ -10953,116 +10950,248 @@ func rewriteValueS390X_OpS390XMOVBZloadidx_0(v *Value) bool { return false } func rewriteValueS390X_OpS390XMOVBZreg_0(v *Value) bool { - // match: (MOVBZreg x:(MOVDLT (MOVDconst [c]) (MOVDconst [d]) _)) - // cond: int64(uint8(c)) == c && int64(uint8(d)) == d - // result: (MOVDreg x) + b := v.Block + // match: (MOVBZreg e:(MOVBreg x)) + // cond: clobberIfDead(e) + // result: (MOVBZreg x) for { - x := v.Args[0] - if x.Op != OpS390XMOVDLT { + e := v.Args[0] + if e.Op != OpS390XMOVBreg { break } - _ = x.Args[2] - x_0 := x.Args[0] - if x_0.Op != OpS390XMOVDconst { + x := e.Args[0] + if !(clobberIfDead(e)) { break } - c := x_0.AuxInt - x_1 := x.Args[1] - if x_1.Op != OpS390XMOVDconst { + v.reset(OpS390XMOVBZreg) + v.AddArg(x) + return true + } + // match: (MOVBZreg e:(MOVHreg x)) + // cond: clobberIfDead(e) + // result: (MOVBZreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVHreg { break } - d := x_1.AuxInt - if !(int64(uint8(c)) == c && int64(uint8(d)) == d) { + x := e.Args[0] + if !(clobberIfDead(e)) { break } - v.reset(OpS390XMOVDreg) + v.reset(OpS390XMOVBZreg) v.AddArg(x) return true } - // match: (MOVBZreg x:(MOVDLE (MOVDconst [c]) (MOVDconst [d]) _)) - // cond: int64(uint8(c)) == c && int64(uint8(d)) == d - // result: (MOVDreg x) + // match: (MOVBZreg e:(MOVWreg x)) + // cond: clobberIfDead(e) + // result: (MOVBZreg x) for { - x := v.Args[0] - if x.Op != OpS390XMOVDLE { + e := v.Args[0] + if e.Op != OpS390XMOVWreg { break } - _ = x.Args[2] - x_0 := x.Args[0] - if x_0.Op != OpS390XMOVDconst { + x := e.Args[0] + if !(clobberIfDead(e)) { break } - c := x_0.AuxInt - x_1 := x.Args[1] - if x_1.Op != OpS390XMOVDconst { + v.reset(OpS390XMOVBZreg) + v.AddArg(x) + return true + } + // match: (MOVBZreg e:(MOVBZreg x)) + // cond: clobberIfDead(e) + // result: (MOVBZreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVBZreg { break } - d := x_1.AuxInt - if !(int64(uint8(c)) == c && int64(uint8(d)) == d) { + x := e.Args[0] + if !(clobberIfDead(e)) { break } - v.reset(OpS390XMOVDreg) + v.reset(OpS390XMOVBZreg) v.AddArg(x) return true } - // match: (MOVBZreg x:(MOVDGT (MOVDconst [c]) (MOVDconst [d]) _)) - // cond: int64(uint8(c)) == c && int64(uint8(d)) == d - // result: (MOVDreg x) + // match: (MOVBZreg e:(MOVHZreg x)) + // cond: clobberIfDead(e) + // result: (MOVBZreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVHZreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVBZreg) + v.AddArg(x) + return true + } + // match: (MOVBZreg e:(MOVWZreg x)) + // cond: clobberIfDead(e) + // result: (MOVBZreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVWZreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVBZreg) + v.AddArg(x) + return true + } + // match: (MOVBZreg x:(MOVBZload _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVDGT { + if x.Op != OpS390XMOVBZload { break } - _ = x.Args[2] - x_0 := x.Args[0] - if x_0.Op != OpS390XMOVDconst { + _ = x.Args[1] + if !(!x.Type.IsSigned() || x.Type.Size() > 1) { break } - c := x_0.AuxInt - x_1 := x.Args[1] - if x_1.Op != OpS390XMOVDconst { + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVBZreg x:(MOVBZloadidx _ _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x + for { + x := v.Args[0] + if x.Op != OpS390XMOVBZloadidx { break } - d := x_1.AuxInt - if !(int64(uint8(c)) == c && int64(uint8(d)) == d) { + _ = x.Args[2] + if !(!x.Type.IsSigned() || x.Type.Size() > 1) { break } - v.reset(OpS390XMOVDreg) + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVBZreg x:(MOVDGE (MOVDconst [c]) (MOVDconst [d]) _)) - // cond: int64(uint8(c)) == c && int64(uint8(d)) == d - // result: (MOVDreg x) + // match: (MOVBZreg x:(MOVBZloadidx _ _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVDGE { + if x.Op != OpS390XMOVBZloadidx { break } _ = x.Args[2] - x_0 := x.Args[0] - if x_0.Op != OpS390XMOVDconst { + if !(!x.Type.IsSigned() || x.Type.Size() > 1) { break } - c := x_0.AuxInt - x_1 := x.Args[1] - if x_1.Op != OpS390XMOVDconst { + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVBZreg x:(MOVBload [o] {s} p mem)) + // cond: x.Uses == 1 && clobber(x) + // result: @x.Block (MOVBZload [o] {s} p mem) + for { + t := v.Type + x := v.Args[0] + if x.Op != OpS390XMOVBload { break } - d := x_1.AuxInt - if !(int64(uint8(c)) == c && int64(uint8(d)) == d) { + o := x.AuxInt + s := x.Aux + mem := x.Args[1] + p := x.Args[0] + if !(x.Uses == 1 && clobber(x)) { + break + } + b = x.Block + v0 := b.NewValue0(x.Pos, OpS390XMOVBZload, t) + v.reset(OpCopy) + v.AddArg(v0) + v0.AuxInt = o + v0.Aux = s + v0.AddArg(p) + v0.AddArg(mem) + return true + } + return false +} +func rewriteValueS390X_OpS390XMOVBZreg_10(v *Value) bool { + b := v.Block + // match: (MOVBZreg x:(MOVBloadidx [o] {s} p i mem)) + // cond: x.Uses == 1 && clobber(x) + // result: @x.Block (MOVBZloadidx [o] {s} p i mem) + for { + t := v.Type + x := v.Args[0] + if x.Op != OpS390XMOVBloadidx { + break + } + o := x.AuxInt + s := x.Aux + mem := x.Args[2] + p := x.Args[0] + i := x.Args[1] + if !(x.Uses == 1 && clobber(x)) { + break + } + b = x.Block + v0 := b.NewValue0(v.Pos, OpS390XMOVBZloadidx, t) + v.reset(OpCopy) + v.AddArg(v0) + v0.AuxInt = o + v0.Aux = s + v0.AddArg(p) + v0.AddArg(i) + v0.AddArg(mem) + return true + } + // match: (MOVBZreg x:(Arg )) + // cond: !t.IsSigned() && t.Size() == 1 + // result: x + for { + x := v.Args[0] + if x.Op != OpArg { break } - v.reset(OpS390XMOVDreg) + t := x.Type + if !(!t.IsSigned() && t.Size() == 1) { + break + } + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVBZreg x:(MOVDEQ (MOVDconst [c]) (MOVDconst [d]) _)) - // cond: int64(uint8(c)) == c && int64(uint8(d)) == d - // result: (MOVDreg x) + // match: (MOVBZreg (MOVDconst [c])) + // cond: + // result: (MOVDconst [int64( uint8(c))]) + for { + v_0 := v.Args[0] + if v_0.Op != OpS390XMOVDconst { + break + } + c := v_0.AuxInt + v.reset(OpS390XMOVDconst) + v.AuxInt = int64(uint8(c)) + return true + } + // match: (MOVBZreg x:(MOVDLT (MOVDconst [c]) (MOVDconst [d]) _)) + // cond: int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVDEQ { + if x.Op != OpS390XMOVDLT { break } _ = x.Args[2] @@ -11076,19 +11205,20 @@ func rewriteValueS390X_OpS390XMOVBZreg_0(v *Value) bool { break } d := x_1.AuxInt - if !(int64(uint8(c)) == c && int64(uint8(d)) == d) { + if !(int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1)) { break } - v.reset(OpS390XMOVDreg) + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVBZreg x:(MOVDNE (MOVDconst [c]) (MOVDconst [d]) _)) - // cond: int64(uint8(c)) == c && int64(uint8(d)) == d - // result: (MOVDreg x) + // match: (MOVBZreg x:(MOVDLE (MOVDconst [c]) (MOVDconst [d]) _)) + // cond: int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVDNE { + if x.Op != OpS390XMOVDLE { break } _ = x.Args[2] @@ -11102,19 +11232,20 @@ func rewriteValueS390X_OpS390XMOVBZreg_0(v *Value) bool { break } d := x_1.AuxInt - if !(int64(uint8(c)) == c && int64(uint8(d)) == d) { + if !(int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1)) { break } - v.reset(OpS390XMOVDreg) + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVBZreg x:(MOVDGTnoinv (MOVDconst [c]) (MOVDconst [d]) _)) - // cond: int64(uint8(c)) == c && int64(uint8(d)) == d - // result: (MOVDreg x) + // match: (MOVBZreg x:(MOVDGT (MOVDconst [c]) (MOVDconst [d]) _)) + // cond: int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVDGTnoinv { + if x.Op != OpS390XMOVDGT { break } _ = x.Args[2] @@ -11128,19 +11259,20 @@ func rewriteValueS390X_OpS390XMOVBZreg_0(v *Value) bool { break } d := x_1.AuxInt - if !(int64(uint8(c)) == c && int64(uint8(d)) == d) { + if !(int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1)) { break } - v.reset(OpS390XMOVDreg) + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVBZreg x:(MOVDGEnoinv (MOVDconst [c]) (MOVDconst [d]) _)) - // cond: int64(uint8(c)) == c && int64(uint8(d)) == d - // result: (MOVDreg x) + // match: (MOVBZreg x:(MOVDGE (MOVDconst [c]) (MOVDconst [d]) _)) + // cond: int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVDGEnoinv { + if x.Op != OpS390XMOVDGE { break } _ = x.Args[2] @@ -11154,187 +11286,125 @@ func rewriteValueS390X_OpS390XMOVBZreg_0(v *Value) bool { break } d := x_1.AuxInt - if !(int64(uint8(c)) == c && int64(uint8(d)) == d) { + if !(int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1)) { break } - v.reset(OpS390XMOVDreg) + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVBZreg x:(MOVBZload _ _)) - // cond: - // result: (MOVDreg x) + // match: (MOVBZreg x:(MOVDEQ (MOVDconst [c]) (MOVDconst [d]) _)) + // cond: int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVBZload { + if x.Op != OpS390XMOVDEQ { break } - _ = x.Args[1] - v.reset(OpS390XMOVDreg) - v.AddArg(x) - return true - } - // match: (MOVBZreg x:(Arg )) - // cond: is8BitInt(t) && !isSigned(t) - // result: (MOVDreg x) - for { - x := v.Args[0] - if x.Op != OpArg { + _ = x.Args[2] + x_0 := x.Args[0] + if x_0.Op != OpS390XMOVDconst { break } - t := x.Type - if !(is8BitInt(t) && !isSigned(t)) { + c := x_0.AuxInt + x_1 := x.Args[1] + if x_1.Op != OpS390XMOVDconst { break } - v.reset(OpS390XMOVDreg) - v.AddArg(x) - return true - } - return false -} -func rewriteValueS390X_OpS390XMOVBZreg_10(v *Value) bool { - b := v.Block - typ := &b.Func.Config.Types - // match: (MOVBZreg x:(MOVBZreg _)) - // cond: - // result: (MOVDreg x) - for { - x := v.Args[0] - if x.Op != OpS390XMOVBZreg { + d := x_1.AuxInt + if !(int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1)) { break } - v.reset(OpS390XMOVDreg) + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVBZreg (MOVBreg x)) - // cond: - // result: (MOVBZreg x) + // match: (MOVBZreg x:(MOVDNE (MOVDconst [c]) (MOVDconst [d]) _)) + // cond: int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x for { - v_0 := v.Args[0] - if v_0.Op != OpS390XMOVBreg { + x := v.Args[0] + if x.Op != OpS390XMOVDNE { break } - x := v_0.Args[0] - v.reset(OpS390XMOVBZreg) - v.AddArg(x) - return true - } - // match: (MOVBZreg (MOVDconst [c])) - // cond: - // result: (MOVDconst [int64(uint8(c))]) - for { - v_0 := v.Args[0] - if v_0.Op != OpS390XMOVDconst { + _ = x.Args[2] + x_0 := x.Args[0] + if x_0.Op != OpS390XMOVDconst { break } - c := v_0.AuxInt - v.reset(OpS390XMOVDconst) - v.AuxInt = int64(uint8(c)) - return true - } - // match: (MOVBZreg x:(MOVBZload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVBZload [off] {sym} ptr mem) - for { - x := v.Args[0] - if x.Op != OpS390XMOVBZload { + c := x_0.AuxInt + x_1 := x.Args[1] + if x_1.Op != OpS390XMOVDconst { break } - off := x.AuxInt - sym := x.Aux - mem := x.Args[1] - ptr := x.Args[0] - if !(x.Uses == 1 && clobber(x)) { + d := x_1.AuxInt + if !(int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1)) { break } - b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVBZload, v.Type) v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) + v.Type = x.Type + v.AddArg(x) return true } - // match: (MOVBZreg x:(MOVBload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVBZload [off] {sym} ptr mem) + // match: (MOVBZreg x:(MOVDGTnoinv (MOVDconst [c]) (MOVDconst [d]) _)) + // cond: int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVBload { + if x.Op != OpS390XMOVDGTnoinv { break } - off := x.AuxInt - sym := x.Aux - mem := x.Args[1] - ptr := x.Args[0] - if !(x.Uses == 1 && clobber(x)) { + _ = x.Args[2] + x_0 := x.Args[0] + if x_0.Op != OpS390XMOVDconst { break } - b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVBZload, v.Type) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - // match: (MOVBZreg x:(MOVBZloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVBZloadidx [off] {sym} ptr idx mem) - for { - x := v.Args[0] - if x.Op != OpS390XMOVBZloadidx { + c := x_0.AuxInt + x_1 := x.Args[1] + if x_1.Op != OpS390XMOVDconst { break } - off := x.AuxInt - sym := x.Aux - mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] - if !(x.Uses == 1 && clobber(x)) { + d := x_1.AuxInt + if !(int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1)) { break } - b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVBZloadidx, v.Type) v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) + v.Type = x.Type + v.AddArg(x) return true } - // match: (MOVBZreg x:(MOVBloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVBZloadidx [off] {sym} ptr idx mem) + return false +} +func rewriteValueS390X_OpS390XMOVBZreg_20(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // match: (MOVBZreg x:(MOVDGEnoinv (MOVDconst [c]) (MOVDconst [d]) _)) + // cond: int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVBloadidx { + if x.Op != OpS390XMOVDGEnoinv { break } - off := x.AuxInt - sym := x.Aux - mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] - if !(x.Uses == 1 && clobber(x)) { + _ = x.Args[2] + x_0 := x.Args[0] + if x_0.Op != OpS390XMOVDconst { + break + } + c := x_0.AuxInt + x_1 := x.Args[1] + if x_1.Op != OpS390XMOVDconst { + break + } + d := x_1.AuxInt + if !(int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1)) { break } - b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVBZloadidx, v.Type) v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) + v.Type = x.Type + v.AddArg(x) return true } // match: (MOVBZreg (ANDWconst [m] x)) @@ -11589,176 +11659,240 @@ func rewriteValueS390X_OpS390XMOVBloadidx_0(v *Value) bool { } func rewriteValueS390X_OpS390XMOVBreg_0(v *Value) bool { b := v.Block - typ := &b.Func.Config.Types - // match: (MOVBreg x:(MOVBload _ _)) - // cond: - // result: (MOVDreg x) + // match: (MOVBreg e:(MOVBreg x)) + // cond: clobberIfDead(e) + // result: (MOVBreg x) for { - x := v.Args[0] - if x.Op != OpS390XMOVBload { + e := v.Args[0] + if e.Op != OpS390XMOVBreg { break } - _ = x.Args[1] - v.reset(OpS390XMOVDreg) + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVBreg) v.AddArg(x) return true } - // match: (MOVBreg x:(Arg )) - // cond: is8BitInt(t) && isSigned(t) - // result: (MOVDreg x) + // match: (MOVBreg e:(MOVHreg x)) + // cond: clobberIfDead(e) + // result: (MOVBreg x) for { - x := v.Args[0] - if x.Op != OpArg { + e := v.Args[0] + if e.Op != OpS390XMOVHreg { break } - t := x.Type - if !(is8BitInt(t) && isSigned(t)) { + x := e.Args[0] + if !(clobberIfDead(e)) { break } - v.reset(OpS390XMOVDreg) + v.reset(OpS390XMOVBreg) v.AddArg(x) return true } - // match: (MOVBreg x:(MOVBreg _)) - // cond: - // result: (MOVDreg x) + // match: (MOVBreg e:(MOVWreg x)) + // cond: clobberIfDead(e) + // result: (MOVBreg x) for { - x := v.Args[0] - if x.Op != OpS390XMOVBreg { + e := v.Args[0] + if e.Op != OpS390XMOVWreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { break } - v.reset(OpS390XMOVDreg) + v.reset(OpS390XMOVBreg) v.AddArg(x) return true } - // match: (MOVBreg (MOVBZreg x)) - // cond: + // match: (MOVBreg e:(MOVBZreg x)) + // cond: clobberIfDead(e) // result: (MOVBreg x) for { - v_0 := v.Args[0] - if v_0.Op != OpS390XMOVBZreg { + e := v.Args[0] + if e.Op != OpS390XMOVBZreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { break } - x := v_0.Args[0] v.reset(OpS390XMOVBreg) v.AddArg(x) return true } - // match: (MOVBreg (MOVDconst [c])) - // cond: - // result: (MOVDconst [int64(int8(c))]) + // match: (MOVBreg e:(MOVHZreg x)) + // cond: clobberIfDead(e) + // result: (MOVBreg x) for { - v_0 := v.Args[0] - if v_0.Op != OpS390XMOVDconst { + e := v.Args[0] + if e.Op != OpS390XMOVHZreg { break } - c := v_0.AuxInt - v.reset(OpS390XMOVDconst) - v.AuxInt = int64(int8(c)) + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVBreg) + v.AddArg(x) return true } - // match: (MOVBreg x:(MOVBZload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVBload [off] {sym} ptr mem) + // match: (MOVBreg e:(MOVWZreg x)) + // cond: clobberIfDead(e) + // result: (MOVBreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVWZreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVBreg) + v.AddArg(x) + return true + } + // match: (MOVBreg x:(MOVBload _ _)) + // cond: (x.Type.IsSigned() || x.Type.Size() == 8) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVBZload { + if x.Op != OpS390XMOVBload { break } - off := x.AuxInt - sym := x.Aux - mem := x.Args[1] - ptr := x.Args[0] - if !(x.Uses == 1 && clobber(x)) { + _ = x.Args[1] + if !(x.Type.IsSigned() || x.Type.Size() == 8) { break } - b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVBload, v.Type) v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVBreg x:(MOVBloadidx _ _ _)) + // cond: (x.Type.IsSigned() || x.Type.Size() == 8) + // result: x + for { + x := v.Args[0] + if x.Op != OpS390XMOVBloadidx { + break + } + _ = x.Args[2] + if !(x.Type.IsSigned() || x.Type.Size() == 8) { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVBreg x:(MOVBloadidx _ _ _)) + // cond: (x.Type.IsSigned() || x.Type.Size() == 8) + // result: x + for { + x := v.Args[0] + if x.Op != OpS390XMOVBloadidx { + break + } + _ = x.Args[2] + if !(x.Type.IsSigned() || x.Type.Size() == 8) { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) return true } - // match: (MOVBreg x:(MOVBload [off] {sym} ptr mem)) + // match: (MOVBreg x:(MOVBZload [o] {s} p mem)) // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVBload [off] {sym} ptr mem) + // result: @x.Block (MOVBload [o] {s} p mem) for { + t := v.Type x := v.Args[0] - if x.Op != OpS390XMOVBload { + if x.Op != OpS390XMOVBZload { break } - off := x.AuxInt - sym := x.Aux + o := x.AuxInt + s := x.Aux mem := x.Args[1] - ptr := x.Args[0] + p := x.Args[0] if !(x.Uses == 1 && clobber(x)) { break } b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVBload, v.Type) + v0 := b.NewValue0(x.Pos, OpS390XMOVBload, t) v.reset(OpCopy) v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) + v0.AuxInt = o + v0.Aux = s + v0.AddArg(p) v0.AddArg(mem) return true } - // match: (MOVBreg x:(MOVBZloadidx [off] {sym} ptr idx mem)) + return false +} +func rewriteValueS390X_OpS390XMOVBreg_10(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // match: (MOVBreg x:(MOVBZloadidx [o] {s} p i mem)) // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVBloadidx [off] {sym} ptr idx mem) + // result: @x.Block (MOVBloadidx [o] {s} p i mem) for { + t := v.Type x := v.Args[0] if x.Op != OpS390XMOVBZloadidx { break } - off := x.AuxInt - sym := x.Aux + o := x.AuxInt + s := x.Aux mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] + p := x.Args[0] + i := x.Args[1] if !(x.Uses == 1 && clobber(x)) { break } b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVBloadidx, v.Type) + v0 := b.NewValue0(v.Pos, OpS390XMOVBloadidx, t) v.reset(OpCopy) v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) + v0.AuxInt = o + v0.Aux = s + v0.AddArg(p) + v0.AddArg(i) v0.AddArg(mem) return true } - // match: (MOVBreg x:(MOVBloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVBloadidx [off] {sym} ptr idx mem) + // match: (MOVBreg x:(Arg )) + // cond: t.IsSigned() && t.Size() == 1 + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVBloadidx { + if x.Op != OpArg { break } - off := x.AuxInt - sym := x.Aux - mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] - if !(x.Uses == 1 && clobber(x)) { + t := x.Type + if !(t.IsSigned() && t.Size() == 1) { break } - b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVBloadidx, v.Type) v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVBreg (MOVDconst [c])) + // cond: + // result: (MOVDconst [int64( int8(c))]) + for { + v_0 := v.Args[0] + if v_0.Op != OpS390XMOVDconst { + break + } + c := v_0.AuxInt + v.reset(OpS390XMOVDconst) + v.AuxInt = int64(int8(c)) return true } // match: (MOVBreg (ANDWconst [m] x)) @@ -14677,7 +14811,7 @@ func rewriteValueS390X_OpS390XMOVDaddridx_0(v *Value) bool { func rewriteValueS390X_OpS390XMOVDload_0(v *Value) bool { // match: (MOVDload [off] {sym} ptr1 (MOVDstore [off] {sym} ptr2 x _)) // cond: isSamePtr(ptr1, ptr2) - // result: (MOVDreg x) + // result: x for { off := v.AuxInt sym := v.Aux @@ -14699,7 +14833,8 @@ func rewriteValueS390X_OpS390XMOVDload_0(v *Value) bool { if !(isSamePtr(ptr1, ptr2)) { break } - v.reset(OpS390XMOVDreg) + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } @@ -14934,844 +15069,6 @@ func rewriteValueS390X_OpS390XMOVDloadidx_0(v *Value) bool { } return false } -func rewriteValueS390X_OpS390XMOVDnop_0(v *Value) bool { - b := v.Block - // match: (MOVDnop x) - // cond: t.Compare(x.Type) == types.CMPeq - // result: x - for { - t := v.Type - x := v.Args[0] - if !(t.Compare(x.Type) == types.CMPeq) { - break - } - v.reset(OpCopy) - v.Type = x.Type - v.AddArg(x) - return true - } - // match: (MOVDnop (MOVDconst [c])) - // cond: - // result: (MOVDconst [c]) - for { - v_0 := v.Args[0] - if v_0.Op != OpS390XMOVDconst { - break - } - c := v_0.AuxInt - v.reset(OpS390XMOVDconst) - v.AuxInt = c - return true - } - // match: (MOVDnop x:(MOVBZload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVBZload [off] {sym} ptr mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVBZload { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[1] - ptr := x.Args[0] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVBZload, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - // match: (MOVDnop x:(MOVBload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVBload [off] {sym} ptr mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVBload { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[1] - ptr := x.Args[0] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVBload, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - // match: (MOVDnop x:(MOVHZload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVHZload [off] {sym} ptr mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVHZload { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[1] - ptr := x.Args[0] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVHZload, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - // match: (MOVDnop x:(MOVHload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVHload [off] {sym} ptr mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVHload { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[1] - ptr := x.Args[0] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVHload, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - // match: (MOVDnop x:(MOVWZload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVWZload [off] {sym} ptr mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVWZload { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[1] - ptr := x.Args[0] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVWZload, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - // match: (MOVDnop x:(MOVWload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVWload [off] {sym} ptr mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVWload { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[1] - ptr := x.Args[0] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVWload, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - // match: (MOVDnop x:(MOVDload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVDload [off] {sym} ptr mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVDload { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[1] - ptr := x.Args[0] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVDload, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - // match: (MOVDnop x:(MOVBZloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVBZloadidx [off] {sym} ptr idx mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVBZloadidx { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVBZloadidx, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) - return true - } - return false -} -func rewriteValueS390X_OpS390XMOVDnop_10(v *Value) bool { - b := v.Block - // match: (MOVDnop x:(MOVBloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVBloadidx [off] {sym} ptr idx mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVBloadidx { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVBloadidx, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) - return true - } - // match: (MOVDnop x:(MOVHZloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVHZloadidx [off] {sym} ptr idx mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVHZloadidx { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVHZloadidx, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) - return true - } - // match: (MOVDnop x:(MOVHloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVHloadidx [off] {sym} ptr idx mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVHloadidx { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVHloadidx, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) - return true - } - // match: (MOVDnop x:(MOVWZloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVWZloadidx [off] {sym} ptr idx mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVWZloadidx { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVWZloadidx, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) - return true - } - // match: (MOVDnop x:(MOVWloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVWloadidx [off] {sym} ptr idx mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVWloadidx { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVWloadidx, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) - return true - } - // match: (MOVDnop x:(MOVDloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVDloadidx [off] {sym} ptr idx mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVDloadidx { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVDloadidx, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) - return true - } - return false -} -func rewriteValueS390X_OpS390XMOVDreg_0(v *Value) bool { - b := v.Block - // match: (MOVDreg x) - // cond: t.Compare(x.Type) == types.CMPeq - // result: x - for { - t := v.Type - x := v.Args[0] - if !(t.Compare(x.Type) == types.CMPeq) { - break - } - v.reset(OpCopy) - v.Type = x.Type - v.AddArg(x) - return true - } - // match: (MOVDreg (MOVDconst [c])) - // cond: - // result: (MOVDconst [c]) - for { - v_0 := v.Args[0] - if v_0.Op != OpS390XMOVDconst { - break - } - c := v_0.AuxInt - v.reset(OpS390XMOVDconst) - v.AuxInt = c - return true - } - // match: (MOVDreg x) - // cond: x.Uses == 1 - // result: (MOVDnop x) - for { - x := v.Args[0] - if !(x.Uses == 1) { - break - } - v.reset(OpS390XMOVDnop) - v.AddArg(x) - return true - } - // match: (MOVDreg x:(MOVBZload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVBZload [off] {sym} ptr mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVBZload { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[1] - ptr := x.Args[0] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVBZload, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - // match: (MOVDreg x:(MOVBload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVBload [off] {sym} ptr mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVBload { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[1] - ptr := x.Args[0] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVBload, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - // match: (MOVDreg x:(MOVHZload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVHZload [off] {sym} ptr mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVHZload { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[1] - ptr := x.Args[0] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVHZload, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - // match: (MOVDreg x:(MOVHload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVHload [off] {sym} ptr mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVHload { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[1] - ptr := x.Args[0] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVHload, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - // match: (MOVDreg x:(MOVWZload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVWZload [off] {sym} ptr mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVWZload { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[1] - ptr := x.Args[0] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVWZload, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - // match: (MOVDreg x:(MOVWload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVWload [off] {sym} ptr mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVWload { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[1] - ptr := x.Args[0] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVWload, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - // match: (MOVDreg x:(MOVDload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVDload [off] {sym} ptr mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVDload { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[1] - ptr := x.Args[0] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVDload, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - return false -} -func rewriteValueS390X_OpS390XMOVDreg_10(v *Value) bool { - b := v.Block - // match: (MOVDreg x:(MOVBZloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVBZloadidx [off] {sym} ptr idx mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVBZloadidx { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVBZloadidx, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) - return true - } - // match: (MOVDreg x:(MOVBloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVBloadidx [off] {sym} ptr idx mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVBloadidx { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVBloadidx, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) - return true - } - // match: (MOVDreg x:(MOVHZloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVHZloadidx [off] {sym} ptr idx mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVHZloadidx { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVHZloadidx, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) - return true - } - // match: (MOVDreg x:(MOVHloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVHloadidx [off] {sym} ptr idx mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVHloadidx { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVHloadidx, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) - return true - } - // match: (MOVDreg x:(MOVWZloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVWZloadidx [off] {sym} ptr idx mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVWZloadidx { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVWZloadidx, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) - return true - } - // match: (MOVDreg x:(MOVWloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVWloadidx [off] {sym} ptr idx mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVWloadidx { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVWloadidx, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) - return true - } - // match: (MOVDreg x:(MOVDloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVDloadidx [off] {sym} ptr idx mem) - for { - t := v.Type - x := v.Args[0] - if x.Op != OpS390XMOVDloadidx { - break - } - off := x.AuxInt - sym := x.Aux - mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] - if !(x.Uses == 1 && clobber(x)) { - break - } - b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVDloadidx, t) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) - return true - } - return false -} func rewriteValueS390X_OpS390XMOVDstore_0(v *Value) bool { // match: (MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) // cond: is20Bit(off1+off2) @@ -17431,206 +16728,275 @@ func rewriteValueS390X_OpS390XMOVHZloadidx_0(v *Value) bool { return false } func rewriteValueS390X_OpS390XMOVHZreg_0(v *Value) bool { - b := v.Block - // match: (MOVHZreg x:(MOVBZload _ _)) - // cond: - // result: (MOVDreg x) + // match: (MOVHZreg e:(MOVBZreg x)) + // cond: clobberIfDead(e) + // result: (MOVBZreg x) for { - x := v.Args[0] - if x.Op != OpS390XMOVBZload { + e := v.Args[0] + if e.Op != OpS390XMOVBZreg { break } - _ = x.Args[1] - v.reset(OpS390XMOVDreg) + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVBZreg) v.AddArg(x) return true } - // match: (MOVHZreg x:(MOVHZload _ _)) - // cond: - // result: (MOVDreg x) + // match: (MOVHZreg e:(MOVHreg x)) + // cond: clobberIfDead(e) + // result: (MOVHZreg x) for { - x := v.Args[0] - if x.Op != OpS390XMOVHZload { + e := v.Args[0] + if e.Op != OpS390XMOVHreg { break } - _ = x.Args[1] - v.reset(OpS390XMOVDreg) + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVHZreg) v.AddArg(x) return true } - // match: (MOVHZreg x:(Arg )) - // cond: (is8BitInt(t) || is16BitInt(t)) && !isSigned(t) - // result: (MOVDreg x) + // match: (MOVHZreg e:(MOVWreg x)) + // cond: clobberIfDead(e) + // result: (MOVHZreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVWreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVHZreg) + v.AddArg(x) + return true + } + // match: (MOVHZreg e:(MOVHZreg x)) + // cond: clobberIfDead(e) + // result: (MOVHZreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVHZreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVHZreg) + v.AddArg(x) + return true + } + // match: (MOVHZreg e:(MOVWZreg x)) + // cond: clobberIfDead(e) + // result: (MOVHZreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVWZreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVHZreg) + v.AddArg(x) + return true + } + // match: (MOVHZreg x:(MOVBZload _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x for { x := v.Args[0] - if x.Op != OpArg { + if x.Op != OpS390XMOVBZload { break } - t := x.Type - if !((is8BitInt(t) || is16BitInt(t)) && !isSigned(t)) { + _ = x.Args[1] + if !(!x.Type.IsSigned() || x.Type.Size() > 1) { break } - v.reset(OpS390XMOVDreg) + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVHZreg x:(MOVBZreg _)) - // cond: - // result: (MOVDreg x) + // match: (MOVHZreg x:(MOVBZloadidx _ _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVBZreg { + if x.Op != OpS390XMOVBZloadidx { + break + } + _ = x.Args[2] + if !(!x.Type.IsSigned() || x.Type.Size() > 1) { break } - v.reset(OpS390XMOVDreg) + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVHZreg x:(MOVHZreg _)) - // cond: - // result: (MOVDreg x) + // match: (MOVHZreg x:(MOVBZloadidx _ _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVHZreg { + if x.Op != OpS390XMOVBZloadidx { + break + } + _ = x.Args[2] + if !(!x.Type.IsSigned() || x.Type.Size() > 1) { break } - v.reset(OpS390XMOVDreg) + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVHZreg (MOVHreg x)) - // cond: - // result: (MOVHZreg x) + // match: (MOVHZreg x:(MOVHZload _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 2) + // result: x for { - v_0 := v.Args[0] - if v_0.Op != OpS390XMOVHreg { + x := v.Args[0] + if x.Op != OpS390XMOVHZload { break } - x := v_0.Args[0] - v.reset(OpS390XMOVHZreg) + _ = x.Args[1] + if !(!x.Type.IsSigned() || x.Type.Size() > 2) { + break + } + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVHZreg (MOVDconst [c])) - // cond: - // result: (MOVDconst [int64(uint16(c))]) + // match: (MOVHZreg x:(MOVHZloadidx _ _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 2) + // result: x for { - v_0 := v.Args[0] - if v_0.Op != OpS390XMOVDconst { + x := v.Args[0] + if x.Op != OpS390XMOVHZloadidx { break } - c := v_0.AuxInt - v.reset(OpS390XMOVDconst) - v.AuxInt = int64(uint16(c)) + _ = x.Args[2] + if !(!x.Type.IsSigned() || x.Type.Size() > 2) { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) return true } - // match: (MOVHZreg x:(MOVHZload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVHZload [off] {sym} ptr mem) + return false +} +func rewriteValueS390X_OpS390XMOVHZreg_10(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // match: (MOVHZreg x:(MOVHZloadidx _ _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 2) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVHZload { + if x.Op != OpS390XMOVHZloadidx { break } - off := x.AuxInt - sym := x.Aux - mem := x.Args[1] - ptr := x.Args[0] - if !(x.Uses == 1 && clobber(x)) { + _ = x.Args[2] + if !(!x.Type.IsSigned() || x.Type.Size() > 2) { break } - b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVHZload, v.Type) v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) + v.Type = x.Type + v.AddArg(x) return true } - // match: (MOVHZreg x:(MOVHload [off] {sym} ptr mem)) + // match: (MOVHZreg x:(MOVHload [o] {s} p mem)) // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVHZload [off] {sym} ptr mem) + // result: @x.Block (MOVHZload [o] {s} p mem) for { + t := v.Type x := v.Args[0] if x.Op != OpS390XMOVHload { break } - off := x.AuxInt - sym := x.Aux + o := x.AuxInt + s := x.Aux mem := x.Args[1] - ptr := x.Args[0] + p := x.Args[0] if !(x.Uses == 1 && clobber(x)) { break } b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVHZload, v.Type) + v0 := b.NewValue0(x.Pos, OpS390XMOVHZload, t) v.reset(OpCopy) v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) + v0.AuxInt = o + v0.Aux = s + v0.AddArg(p) v0.AddArg(mem) return true } - // match: (MOVHZreg x:(MOVHZloadidx [off] {sym} ptr idx mem)) + // match: (MOVHZreg x:(MOVHloadidx [o] {s} p i mem)) // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVHZloadidx [off] {sym} ptr idx mem) + // result: @x.Block (MOVHZloadidx [o] {s} p i mem) for { + t := v.Type x := v.Args[0] - if x.Op != OpS390XMOVHZloadidx { + if x.Op != OpS390XMOVHloadidx { break } - off := x.AuxInt - sym := x.Aux + o := x.AuxInt + s := x.Aux mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] + p := x.Args[0] + i := x.Args[1] if !(x.Uses == 1 && clobber(x)) { break } b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVHZloadidx, v.Type) + v0 := b.NewValue0(v.Pos, OpS390XMOVHZloadidx, t) v.reset(OpCopy) v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) + v0.AuxInt = o + v0.Aux = s + v0.AddArg(p) + v0.AddArg(i) v0.AddArg(mem) return true } - return false -} -func rewriteValueS390X_OpS390XMOVHZreg_10(v *Value) bool { - b := v.Block - typ := &b.Func.Config.Types - // match: (MOVHZreg x:(MOVHloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVHZloadidx [off] {sym} ptr idx mem) + // match: (MOVHZreg x:(Arg )) + // cond: !t.IsSigned() && t.Size() <= 2 + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVHloadidx { + if x.Op != OpArg { break } - off := x.AuxInt - sym := x.Aux - mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] - if !(x.Uses == 1 && clobber(x)) { + t := x.Type + if !(!t.IsSigned() && t.Size() <= 2) { break } - b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVHZloadidx, v.Type) v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVHZreg (MOVDconst [c])) + // cond: + // result: (MOVDconst [int64(uint16(c))]) + for { + v_0 := v.Args[0] + if v_0.Op != OpS390XMOVDconst { + break + } + c := v_0.AuxInt + v.reset(OpS390XMOVDconst) + v.AuxInt = int64(uint16(c)) return true } // match: (MOVHZreg (ANDWconst [m] x)) @@ -17885,147 +17251,169 @@ func rewriteValueS390X_OpS390XMOVHloadidx_0(v *Value) bool { return false } func rewriteValueS390X_OpS390XMOVHreg_0(v *Value) bool { - b := v.Block - // match: (MOVHreg x:(MOVBload _ _)) - // cond: - // result: (MOVDreg x) + // match: (MOVHreg e:(MOVBreg x)) + // cond: clobberIfDead(e) + // result: (MOVBreg x) for { - x := v.Args[0] - if x.Op != OpS390XMOVBload { + e := v.Args[0] + if e.Op != OpS390XMOVBreg { break } - _ = x.Args[1] - v.reset(OpS390XMOVDreg) + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVBreg) v.AddArg(x) return true } - // match: (MOVHreg x:(MOVBZload _ _)) - // cond: - // result: (MOVDreg x) + // match: (MOVHreg e:(MOVHreg x)) + // cond: clobberIfDead(e) + // result: (MOVHreg x) for { - x := v.Args[0] - if x.Op != OpS390XMOVBZload { + e := v.Args[0] + if e.Op != OpS390XMOVHreg { break } - _ = x.Args[1] - v.reset(OpS390XMOVDreg) + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVHreg) v.AddArg(x) return true } - // match: (MOVHreg x:(MOVHload _ _)) - // cond: - // result: (MOVDreg x) + // match: (MOVHreg e:(MOVWreg x)) + // cond: clobberIfDead(e) + // result: (MOVHreg x) for { - x := v.Args[0] - if x.Op != OpS390XMOVHload { + e := v.Args[0] + if e.Op != OpS390XMOVWreg { break } - _ = x.Args[1] - v.reset(OpS390XMOVDreg) + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVHreg) v.AddArg(x) return true } - // match: (MOVHreg x:(Arg )) - // cond: (is8BitInt(t) || is16BitInt(t)) && isSigned(t) - // result: (MOVDreg x) + // match: (MOVHreg e:(MOVHZreg x)) + // cond: clobberIfDead(e) + // result: (MOVHreg x) for { - x := v.Args[0] - if x.Op != OpArg { + e := v.Args[0] + if e.Op != OpS390XMOVHZreg { break } - t := x.Type - if !((is8BitInt(t) || is16BitInt(t)) && isSigned(t)) { + x := e.Args[0] + if !(clobberIfDead(e)) { break } - v.reset(OpS390XMOVDreg) + v.reset(OpS390XMOVHreg) v.AddArg(x) return true } - // match: (MOVHreg x:(MOVBreg _)) - // cond: - // result: (MOVDreg x) + // match: (MOVHreg e:(MOVWZreg x)) + // cond: clobberIfDead(e) + // result: (MOVHreg x) for { - x := v.Args[0] - if x.Op != OpS390XMOVBreg { + e := v.Args[0] + if e.Op != OpS390XMOVWZreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { break } - v.reset(OpS390XMOVDreg) + v.reset(OpS390XMOVHreg) v.AddArg(x) return true } - // match: (MOVHreg x:(MOVBZreg _)) - // cond: - // result: (MOVDreg x) + // match: (MOVHreg x:(MOVBload _ _)) + // cond: (x.Type.IsSigned() || x.Type.Size() == 8) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVBZreg { + if x.Op != OpS390XMOVBload { break } - v.reset(OpS390XMOVDreg) + _ = x.Args[1] + if !(x.Type.IsSigned() || x.Type.Size() == 8) { + break + } + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVHreg x:(MOVHreg _)) - // cond: - // result: (MOVDreg x) + // match: (MOVHreg x:(MOVBloadidx _ _ _)) + // cond: (x.Type.IsSigned() || x.Type.Size() == 8) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVHreg { + if x.Op != OpS390XMOVBloadidx { break } - v.reset(OpS390XMOVDreg) + _ = x.Args[2] + if !(x.Type.IsSigned() || x.Type.Size() == 8) { + break + } + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVHreg (MOVHZreg x)) - // cond: - // result: (MOVHreg x) + // match: (MOVHreg x:(MOVBloadidx _ _ _)) + // cond: (x.Type.IsSigned() || x.Type.Size() == 8) + // result: x for { - v_0 := v.Args[0] - if v_0.Op != OpS390XMOVHZreg { + x := v.Args[0] + if x.Op != OpS390XMOVBloadidx { break } - x := v_0.Args[0] - v.reset(OpS390XMOVHreg) + _ = x.Args[2] + if !(x.Type.IsSigned() || x.Type.Size() == 8) { + break + } + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVHreg (MOVDconst [c])) - // cond: - // result: (MOVDconst [int64(int16(c))]) + // match: (MOVHreg x:(MOVHload _ _)) + // cond: (x.Type.IsSigned() || x.Type.Size() == 8) + // result: x for { - v_0 := v.Args[0] - if v_0.Op != OpS390XMOVDconst { + x := v.Args[0] + if x.Op != OpS390XMOVHload { break } - c := v_0.AuxInt - v.reset(OpS390XMOVDconst) - v.AuxInt = int64(int16(c)) + _ = x.Args[1] + if !(x.Type.IsSigned() || x.Type.Size() == 8) { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) return true } - // match: (MOVHreg x:(MOVHZload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVHload [off] {sym} ptr mem) + // match: (MOVHreg x:(MOVHloadidx _ _ _)) + // cond: (x.Type.IsSigned() || x.Type.Size() == 8) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVHZload { + if x.Op != OpS390XMOVHloadidx { break } - off := x.AuxInt - sym := x.Aux - mem := x.Args[1] - ptr := x.Args[0] - if !(x.Uses == 1 && clobber(x)) { + _ = x.Args[2] + if !(x.Type.IsSigned() || x.Type.Size() == 8) { break } - b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVHload, v.Type) v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) + v.Type = x.Type + v.AddArg(x) return true } return false @@ -18033,83 +17421,156 @@ func rewriteValueS390X_OpS390XMOVHreg_0(v *Value) bool { func rewriteValueS390X_OpS390XMOVHreg_10(v *Value) bool { b := v.Block typ := &b.Func.Config.Types - // match: (MOVHreg x:(MOVHload [off] {sym} ptr mem)) + // match: (MOVHreg x:(MOVHloadidx _ _ _)) + // cond: (x.Type.IsSigned() || x.Type.Size() == 8) + // result: x + for { + x := v.Args[0] + if x.Op != OpS390XMOVHloadidx { + break + } + _ = x.Args[2] + if !(x.Type.IsSigned() || x.Type.Size() == 8) { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVHreg x:(MOVBZload _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x + for { + x := v.Args[0] + if x.Op != OpS390XMOVBZload { + break + } + _ = x.Args[1] + if !(!x.Type.IsSigned() || x.Type.Size() > 1) { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVHreg x:(MOVBZloadidx _ _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x + for { + x := v.Args[0] + if x.Op != OpS390XMOVBZloadidx { + break + } + _ = x.Args[2] + if !(!x.Type.IsSigned() || x.Type.Size() > 1) { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVHreg x:(MOVBZloadidx _ _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x + for { + x := v.Args[0] + if x.Op != OpS390XMOVBZloadidx { + break + } + _ = x.Args[2] + if !(!x.Type.IsSigned() || x.Type.Size() > 1) { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVHreg x:(MOVHZload [o] {s} p mem)) // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVHload [off] {sym} ptr mem) + // result: @x.Block (MOVHload [o] {s} p mem) for { + t := v.Type x := v.Args[0] - if x.Op != OpS390XMOVHload { + if x.Op != OpS390XMOVHZload { break } - off := x.AuxInt - sym := x.Aux + o := x.AuxInt + s := x.Aux mem := x.Args[1] - ptr := x.Args[0] + p := x.Args[0] if !(x.Uses == 1 && clobber(x)) { break } b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVHload, v.Type) + v0 := b.NewValue0(x.Pos, OpS390XMOVHload, t) v.reset(OpCopy) v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) + v0.AuxInt = o + v0.Aux = s + v0.AddArg(p) v0.AddArg(mem) return true } - // match: (MOVHreg x:(MOVHZloadidx [off] {sym} ptr idx mem)) + // match: (MOVHreg x:(MOVHZloadidx [o] {s} p i mem)) // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVHloadidx [off] {sym} ptr idx mem) + // result: @x.Block (MOVHloadidx [o] {s} p i mem) for { + t := v.Type x := v.Args[0] if x.Op != OpS390XMOVHZloadidx { break } - off := x.AuxInt - sym := x.Aux + o := x.AuxInt + s := x.Aux mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] + p := x.Args[0] + i := x.Args[1] if !(x.Uses == 1 && clobber(x)) { break } b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVHloadidx, v.Type) + v0 := b.NewValue0(v.Pos, OpS390XMOVHloadidx, t) v.reset(OpCopy) v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) + v0.AuxInt = o + v0.Aux = s + v0.AddArg(p) + v0.AddArg(i) v0.AddArg(mem) return true } - // match: (MOVHreg x:(MOVHloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVHloadidx [off] {sym} ptr idx mem) + // match: (MOVHreg x:(Arg )) + // cond: t.IsSigned() && t.Size() <= 2 + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVHloadidx { + if x.Op != OpArg { break } - off := x.AuxInt - sym := x.Aux - mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] - if !(x.Uses == 1 && clobber(x)) { + t := x.Type + if !(t.IsSigned() && t.Size() <= 2) { break } - b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVHloadidx, v.Type) v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVHreg (MOVDconst [c])) + // cond: + // result: (MOVDconst [int64(int16(c))]) + for { + v_0 := v.Args[0] + if v_0.Op != OpS390XMOVDconst { + break + } + c := v_0.AuxInt + v.reset(OpS390XMOVDconst) + v.AuxInt = int64(int16(c)) return true } // match: (MOVHreg (ANDWconst [m] x)) @@ -20264,230 +19725,309 @@ func rewriteValueS390X_OpS390XMOVWZloadidx_0(v *Value) bool { return false } func rewriteValueS390X_OpS390XMOVWZreg_0(v *Value) bool { - b := v.Block - // match: (MOVWZreg x:(MOVBZload _ _)) - // cond: - // result: (MOVDreg x) + // match: (MOVWZreg e:(MOVBZreg x)) + // cond: clobberIfDead(e) + // result: (MOVBZreg x) for { - x := v.Args[0] - if x.Op != OpS390XMOVBZload { + e := v.Args[0] + if e.Op != OpS390XMOVBZreg { break } - _ = x.Args[1] - v.reset(OpS390XMOVDreg) + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVBZreg) v.AddArg(x) return true } - // match: (MOVWZreg x:(MOVHZload _ _)) - // cond: - // result: (MOVDreg x) + // match: (MOVWZreg e:(MOVHZreg x)) + // cond: clobberIfDead(e) + // result: (MOVHZreg x) for { - x := v.Args[0] - if x.Op != OpS390XMOVHZload { + e := v.Args[0] + if e.Op != OpS390XMOVHZreg { break } - _ = x.Args[1] - v.reset(OpS390XMOVDreg) + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVHZreg) v.AddArg(x) return true } - // match: (MOVWZreg x:(MOVWZload _ _)) - // cond: - // result: (MOVDreg x) + // match: (MOVWZreg e:(MOVWreg x)) + // cond: clobberIfDead(e) + // result: (MOVWZreg x) for { - x := v.Args[0] - if x.Op != OpS390XMOVWZload { + e := v.Args[0] + if e.Op != OpS390XMOVWreg { break } - _ = x.Args[1] - v.reset(OpS390XMOVDreg) + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVWZreg) v.AddArg(x) return true } - // match: (MOVWZreg x:(Arg )) - // cond: (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && !isSigned(t) - // result: (MOVDreg x) + // match: (MOVWZreg e:(MOVWZreg x)) + // cond: clobberIfDead(e) + // result: (MOVWZreg x) for { - x := v.Args[0] - if x.Op != OpArg { + e := v.Args[0] + if e.Op != OpS390XMOVWZreg { break } - t := x.Type - if !((is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && !isSigned(t)) { + x := e.Args[0] + if !(clobberIfDead(e)) { break } - v.reset(OpS390XMOVDreg) + v.reset(OpS390XMOVWZreg) v.AddArg(x) return true } - // match: (MOVWZreg x:(MOVBZreg _)) - // cond: - // result: (MOVDreg x) + // match: (MOVWZreg x:(MOVBZload _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVBZreg { + if x.Op != OpS390XMOVBZload { break } - v.reset(OpS390XMOVDreg) + _ = x.Args[1] + if !(!x.Type.IsSigned() || x.Type.Size() > 1) { + break + } + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVWZreg x:(MOVHZreg _)) - // cond: - // result: (MOVDreg x) + // match: (MOVWZreg x:(MOVBZloadidx _ _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVHZreg { + if x.Op != OpS390XMOVBZloadidx { break } - v.reset(OpS390XMOVDreg) + _ = x.Args[2] + if !(!x.Type.IsSigned() || x.Type.Size() > 1) { + break + } + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVWZreg x:(MOVWZreg _)) - // cond: - // result: (MOVDreg x) + // match: (MOVWZreg x:(MOVBZloadidx _ _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVWZreg { + if x.Op != OpS390XMOVBZloadidx { + break + } + _ = x.Args[2] + if !(!x.Type.IsSigned() || x.Type.Size() > 1) { break } - v.reset(OpS390XMOVDreg) + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVWZreg (MOVWreg x)) - // cond: - // result: (MOVWZreg x) + // match: (MOVWZreg x:(MOVHZload _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 2) + // result: x for { - v_0 := v.Args[0] - if v_0.Op != OpS390XMOVWreg { + x := v.Args[0] + if x.Op != OpS390XMOVHZload { break } - x := v_0.Args[0] - v.reset(OpS390XMOVWZreg) + _ = x.Args[1] + if !(!x.Type.IsSigned() || x.Type.Size() > 2) { + break + } + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVWZreg (MOVDconst [c])) - // cond: - // result: (MOVDconst [int64(uint32(c))]) + // match: (MOVWZreg x:(MOVHZloadidx _ _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 2) + // result: x for { - v_0 := v.Args[0] - if v_0.Op != OpS390XMOVDconst { + x := v.Args[0] + if x.Op != OpS390XMOVHZloadidx { break } - c := v_0.AuxInt - v.reset(OpS390XMOVDconst) - v.AuxInt = int64(uint32(c)) + _ = x.Args[2] + if !(!x.Type.IsSigned() || x.Type.Size() > 2) { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) return true } - // match: (MOVWZreg x:(MOVWZload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVWZload [off] {sym} ptr mem) + // match: (MOVWZreg x:(MOVHZloadidx _ _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 2) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVWZload { + if x.Op != OpS390XMOVHZloadidx { break } - off := x.AuxInt - sym := x.Aux - mem := x.Args[1] - ptr := x.Args[0] - if !(x.Uses == 1 && clobber(x)) { + _ = x.Args[2] + if !(!x.Type.IsSigned() || x.Type.Size() > 2) { break } - b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVWZload, v.Type) v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) + v.Type = x.Type + v.AddArg(x) return true } return false } func rewriteValueS390X_OpS390XMOVWZreg_10(v *Value) bool { b := v.Block - // match: (MOVWZreg x:(MOVWload [off] {sym} ptr mem)) + // match: (MOVWZreg x:(MOVWZload _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 4) + // result: x + for { + x := v.Args[0] + if x.Op != OpS390XMOVWZload { + break + } + _ = x.Args[1] + if !(!x.Type.IsSigned() || x.Type.Size() > 4) { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVWZreg x:(MOVWZloadidx _ _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 4) + // result: x + for { + x := v.Args[0] + if x.Op != OpS390XMOVWZloadidx { + break + } + _ = x.Args[2] + if !(!x.Type.IsSigned() || x.Type.Size() > 4) { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVWZreg x:(MOVWZloadidx _ _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 4) + // result: x + for { + x := v.Args[0] + if x.Op != OpS390XMOVWZloadidx { + break + } + _ = x.Args[2] + if !(!x.Type.IsSigned() || x.Type.Size() > 4) { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVWZreg x:(MOVWload [o] {s} p mem)) // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVWZload [off] {sym} ptr mem) + // result: @x.Block (MOVWZload [o] {s} p mem) for { + t := v.Type x := v.Args[0] if x.Op != OpS390XMOVWload { break } - off := x.AuxInt - sym := x.Aux + o := x.AuxInt + s := x.Aux mem := x.Args[1] - ptr := x.Args[0] + p := x.Args[0] if !(x.Uses == 1 && clobber(x)) { break } b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVWZload, v.Type) + v0 := b.NewValue0(x.Pos, OpS390XMOVWZload, t) v.reset(OpCopy) v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) + v0.AuxInt = o + v0.Aux = s + v0.AddArg(p) v0.AddArg(mem) return true } - // match: (MOVWZreg x:(MOVWZloadidx [off] {sym} ptr idx mem)) + // match: (MOVWZreg x:(MOVWloadidx [o] {s} p i mem)) // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVWZloadidx [off] {sym} ptr idx mem) + // result: @x.Block (MOVWZloadidx [o] {s} p i mem) for { + t := v.Type x := v.Args[0] - if x.Op != OpS390XMOVWZloadidx { + if x.Op != OpS390XMOVWloadidx { break } - off := x.AuxInt - sym := x.Aux + o := x.AuxInt + s := x.Aux mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] + p := x.Args[0] + i := x.Args[1] if !(x.Uses == 1 && clobber(x)) { break } b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVWZloadidx, v.Type) + v0 := b.NewValue0(v.Pos, OpS390XMOVWZloadidx, t) v.reset(OpCopy) v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) + v0.AuxInt = o + v0.Aux = s + v0.AddArg(p) + v0.AddArg(i) v0.AddArg(mem) return true } - // match: (MOVWZreg x:(MOVWloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVWZloadidx [off] {sym} ptr idx mem) + // match: (MOVWZreg x:(Arg )) + // cond: !t.IsSigned() && t.Size() <= 4 + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVWloadidx { + if x.Op != OpArg { break } - off := x.AuxInt - sym := x.Aux - mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] - if !(x.Uses == 1 && clobber(x)) { + t := x.Type + if !(!t.IsSigned() && t.Size() <= 4) { break } - b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVWZloadidx, v.Type) v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVWZreg (MOVDconst [c])) + // cond: + // result: (MOVDconst [int64(uint32(c))]) + for { + v_0 := v.Args[0] + if v_0.Op != OpS390XMOVDconst { + break + } + c := v_0.AuxInt + v.reset(OpS390XMOVDconst) + v.AuxInt = int64(uint32(c)) return true } return false @@ -20725,279 +20265,415 @@ func rewriteValueS390X_OpS390XMOVWloadidx_0(v *Value) bool { return false } func rewriteValueS390X_OpS390XMOVWreg_0(v *Value) bool { + // match: (MOVWreg e:(MOVBreg x)) + // cond: clobberIfDead(e) + // result: (MOVBreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVBreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVBreg) + v.AddArg(x) + return true + } + // match: (MOVWreg e:(MOVHreg x)) + // cond: clobberIfDead(e) + // result: (MOVHreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVHreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVHreg) + v.AddArg(x) + return true + } + // match: (MOVWreg e:(MOVWreg x)) + // cond: clobberIfDead(e) + // result: (MOVWreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVWreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVWreg) + v.AddArg(x) + return true + } + // match: (MOVWreg e:(MOVWZreg x)) + // cond: clobberIfDead(e) + // result: (MOVWreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVWZreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVWreg) + v.AddArg(x) + return true + } // match: (MOVWreg x:(MOVBload _ _)) - // cond: - // result: (MOVDreg x) + // cond: (x.Type.IsSigned() || x.Type.Size() == 8) + // result: x for { x := v.Args[0] if x.Op != OpS390XMOVBload { break } _ = x.Args[1] - v.reset(OpS390XMOVDreg) + if !(x.Type.IsSigned() || x.Type.Size() == 8) { + break + } + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVWreg x:(MOVBZload _ _)) - // cond: - // result: (MOVDreg x) + // match: (MOVWreg x:(MOVBloadidx _ _ _)) + // cond: (x.Type.IsSigned() || x.Type.Size() == 8) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVBZload { + if x.Op != OpS390XMOVBloadidx { break } - _ = x.Args[1] - v.reset(OpS390XMOVDreg) + _ = x.Args[2] + if !(x.Type.IsSigned() || x.Type.Size() == 8) { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVWreg x:(MOVBloadidx _ _ _)) + // cond: (x.Type.IsSigned() || x.Type.Size() == 8) + // result: x + for { + x := v.Args[0] + if x.Op != OpS390XMOVBloadidx { + break + } + _ = x.Args[2] + if !(x.Type.IsSigned() || x.Type.Size() == 8) { + break + } + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } // match: (MOVWreg x:(MOVHload _ _)) - // cond: - // result: (MOVDreg x) + // cond: (x.Type.IsSigned() || x.Type.Size() == 8) + // result: x for { x := v.Args[0] if x.Op != OpS390XMOVHload { break } _ = x.Args[1] - v.reset(OpS390XMOVDreg) + if !(x.Type.IsSigned() || x.Type.Size() == 8) { + break + } + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVWreg x:(MOVHZload _ _)) - // cond: - // result: (MOVDreg x) + // match: (MOVWreg x:(MOVHloadidx _ _ _)) + // cond: (x.Type.IsSigned() || x.Type.Size() == 8) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVHZload { + if x.Op != OpS390XMOVHloadidx { break } - _ = x.Args[1] - v.reset(OpS390XMOVDreg) + _ = x.Args[2] + if !(x.Type.IsSigned() || x.Type.Size() == 8) { + break + } + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVWreg x:(MOVWload _ _)) - // cond: - // result: (MOVDreg x) + // match: (MOVWreg x:(MOVHloadidx _ _ _)) + // cond: (x.Type.IsSigned() || x.Type.Size() == 8) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVWload { + if x.Op != OpS390XMOVHloadidx { break } - _ = x.Args[1] - v.reset(OpS390XMOVDreg) + _ = x.Args[2] + if !(x.Type.IsSigned() || x.Type.Size() == 8) { + break + } + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVWreg x:(Arg )) - // cond: (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && isSigned(t) - // result: (MOVDreg x) + return false +} +func rewriteValueS390X_OpS390XMOVWreg_10(v *Value) bool { + b := v.Block + // match: (MOVWreg x:(MOVWload _ _)) + // cond: (x.Type.IsSigned() || x.Type.Size() == 8) + // result: x for { x := v.Args[0] - if x.Op != OpArg { + if x.Op != OpS390XMOVWload { break } - t := x.Type - if !((is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && isSigned(t)) { + _ = x.Args[1] + if !(x.Type.IsSigned() || x.Type.Size() == 8) { break } - v.reset(OpS390XMOVDreg) + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVWreg x:(MOVBreg _)) - // cond: - // result: (MOVDreg x) + // match: (MOVWreg x:(MOVWloadidx _ _ _)) + // cond: (x.Type.IsSigned() || x.Type.Size() == 8) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVBreg { + if x.Op != OpS390XMOVWloadidx { + break + } + _ = x.Args[2] + if !(x.Type.IsSigned() || x.Type.Size() == 8) { break } - v.reset(OpS390XMOVDreg) + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVWreg x:(MOVBZreg _)) - // cond: - // result: (MOVDreg x) + // match: (MOVWreg x:(MOVWloadidx _ _ _)) + // cond: (x.Type.IsSigned() || x.Type.Size() == 8) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVBZreg { + if x.Op != OpS390XMOVWloadidx { + break + } + _ = x.Args[2] + if !(x.Type.IsSigned() || x.Type.Size() == 8) { break } - v.reset(OpS390XMOVDreg) + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVWreg x:(MOVHreg _)) - // cond: - // result: (MOVDreg x) + // match: (MOVWreg x:(MOVBZload _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVHreg { + if x.Op != OpS390XMOVBZload { break } - v.reset(OpS390XMOVDreg) + _ = x.Args[1] + if !(!x.Type.IsSigned() || x.Type.Size() > 1) { + break + } + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVWreg x:(MOVHZreg _)) - // cond: - // result: (MOVDreg x) + // match: (MOVWreg x:(MOVBZloadidx _ _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVHZreg { + if x.Op != OpS390XMOVBZloadidx { + break + } + _ = x.Args[2] + if !(!x.Type.IsSigned() || x.Type.Size() > 1) { break } - v.reset(OpS390XMOVDreg) + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - return false -} -func rewriteValueS390X_OpS390XMOVWreg_10(v *Value) bool { - b := v.Block - // match: (MOVWreg x:(MOVWreg _)) - // cond: - // result: (MOVDreg x) + // match: (MOVWreg x:(MOVBZloadidx _ _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVWreg { + if x.Op != OpS390XMOVBZloadidx { + break + } + _ = x.Args[2] + if !(!x.Type.IsSigned() || x.Type.Size() > 1) { break } - v.reset(OpS390XMOVDreg) + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVWreg (MOVWZreg x)) - // cond: - // result: (MOVWreg x) + // match: (MOVWreg x:(MOVHZload _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 2) + // result: x for { - v_0 := v.Args[0] - if v_0.Op != OpS390XMOVWZreg { + x := v.Args[0] + if x.Op != OpS390XMOVHZload { break } - x := v_0.Args[0] - v.reset(OpS390XMOVWreg) + _ = x.Args[1] + if !(!x.Type.IsSigned() || x.Type.Size() > 2) { + break + } + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } - // match: (MOVWreg (MOVDconst [c])) - // cond: - // result: (MOVDconst [int64(int32(c))]) + // match: (MOVWreg x:(MOVHZloadidx _ _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 2) + // result: x for { - v_0 := v.Args[0] - if v_0.Op != OpS390XMOVDconst { + x := v.Args[0] + if x.Op != OpS390XMOVHZloadidx { break } - c := v_0.AuxInt - v.reset(OpS390XMOVDconst) - v.AuxInt = int64(int32(c)) + _ = x.Args[2] + if !(!x.Type.IsSigned() || x.Type.Size() > 2) { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) return true } - // match: (MOVWreg x:(MOVWZload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVWload [off] {sym} ptr mem) + // match: (MOVWreg x:(MOVHZloadidx _ _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 2) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVWZload { + if x.Op != OpS390XMOVHZloadidx { break } - off := x.AuxInt - sym := x.Aux - mem := x.Args[1] - ptr := x.Args[0] - if !(x.Uses == 1 && clobber(x)) { + _ = x.Args[2] + if !(!x.Type.IsSigned() || x.Type.Size() > 2) { break } - b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVWload, v.Type) v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) + v.Type = x.Type + v.AddArg(x) return true } - // match: (MOVWreg x:(MOVWload [off] {sym} ptr mem)) + // match: (MOVWreg x:(MOVWZload [o] {s} p mem)) // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVWload [off] {sym} ptr mem) + // result: @x.Block (MOVWload [o] {s} p mem) for { + t := v.Type x := v.Args[0] - if x.Op != OpS390XMOVWload { + if x.Op != OpS390XMOVWZload { break } - off := x.AuxInt - sym := x.Aux + o := x.AuxInt + s := x.Aux mem := x.Args[1] - ptr := x.Args[0] + p := x.Args[0] if !(x.Uses == 1 && clobber(x)) { break } b = x.Block - v0 := b.NewValue0(x.Pos, OpS390XMOVWload, v.Type) + v0 := b.NewValue0(x.Pos, OpS390XMOVWload, t) v.reset(OpCopy) v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) + v0.AuxInt = o + v0.Aux = s + v0.AddArg(p) v0.AddArg(mem) return true } - // match: (MOVWreg x:(MOVWZloadidx [off] {sym} ptr idx mem)) + return false +} +func rewriteValueS390X_OpS390XMOVWreg_20(v *Value) bool { + b := v.Block + // match: (MOVWreg x:(MOVWZloadidx [o] {s} p i mem)) // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVWloadidx [off] {sym} ptr idx mem) + // result: @x.Block (MOVWloadidx [o] {s} p i mem) for { + t := v.Type x := v.Args[0] if x.Op != OpS390XMOVWZloadidx { break } - off := x.AuxInt - sym := x.Aux + o := x.AuxInt + s := x.Aux mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] + p := x.Args[0] + i := x.Args[1] if !(x.Uses == 1 && clobber(x)) { break } b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVWloadidx, v.Type) + v0 := b.NewValue0(v.Pos, OpS390XMOVWloadidx, t) v.reset(OpCopy) v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) + v0.AuxInt = o + v0.Aux = s + v0.AddArg(p) + v0.AddArg(i) v0.AddArg(mem) return true } - // match: (MOVWreg x:(MOVWloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVWloadidx [off] {sym} ptr idx mem) + // match: (MOVWreg x:(Arg )) + // cond: t.IsSigned() && t.Size() <= 4 + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVWloadidx { + if x.Op != OpArg { break } - off := x.AuxInt - sym := x.Aux - mem := x.Args[2] - ptr := x.Args[0] - idx := x.Args[1] - if !(x.Uses == 1 && clobber(x)) { + t := x.Type + if !(t.IsSigned() && t.Size() <= 4) { break } - b = x.Block - v0 := b.NewValue0(v.Pos, OpS390XMOVWloadidx, v.Type) v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVWreg (MOVDconst [c])) + // cond: + // result: (MOVDconst [int64(int32(c))]) + for { + v_0 := v.Args[0] + if v_0.Op != OpS390XMOVDconst { + break + } + c := v_0.AuxInt + v.reset(OpS390XMOVDconst) + v.AuxInt = int64(int32(c)) return true } return false @@ -37836,22 +37512,6 @@ func rewriteValueS390X_OpS390XSLD_0(v *Value) bool { v.AddArg(y) return true } - // match: (SLD x (MOVDreg y)) - // cond: - // result: (SLD x y) - for { - _ = v.Args[1] - x := v.Args[0] - v_1 := v.Args[1] - if v_1.Op != OpS390XMOVDreg { - break - } - y := v_1.Args[0] - v.reset(OpS390XSLD) - v.AddArg(x) - v.AddArg(y) - return true - } // match: (SLD x (MOVWreg y)) // cond: // result: (SLD x y) @@ -37932,9 +37592,6 @@ func rewriteValueS390X_OpS390XSLD_0(v *Value) bool { v.AddArg(y) return true } - return false -} -func rewriteValueS390X_OpS390XSLD_10(v *Value) bool { // match: (SLD x (MOVBZreg y)) // cond: // result: (SLD x y) @@ -38041,22 +37698,6 @@ func rewriteValueS390X_OpS390XSLW_0(v *Value) bool { v.AddArg(y) return true } - // match: (SLW x (MOVDreg y)) - // cond: - // result: (SLW x y) - for { - _ = v.Args[1] - x := v.Args[0] - v_1 := v.Args[1] - if v_1.Op != OpS390XMOVDreg { - break - } - y := v_1.Args[0] - v.reset(OpS390XSLW) - v.AddArg(x) - v.AddArg(y) - return true - } // match: (SLW x (MOVWreg y)) // cond: // result: (SLW x y) @@ -38137,9 +37778,6 @@ func rewriteValueS390X_OpS390XSLW_0(v *Value) bool { v.AddArg(y) return true } - return false -} -func rewriteValueS390X_OpS390XSLW_10(v *Value) bool { // match: (SLW x (MOVBZreg y)) // cond: // result: (SLW x y) @@ -38246,22 +37884,6 @@ func rewriteValueS390X_OpS390XSRAD_0(v *Value) bool { v.AddArg(y) return true } - // match: (SRAD x (MOVDreg y)) - // cond: - // result: (SRAD x y) - for { - _ = v.Args[1] - x := v.Args[0] - v_1 := v.Args[1] - if v_1.Op != OpS390XMOVDreg { - break - } - y := v_1.Args[0] - v.reset(OpS390XSRAD) - v.AddArg(x) - v.AddArg(y) - return true - } // match: (SRAD x (MOVWreg y)) // cond: // result: (SRAD x y) @@ -38342,9 +37964,6 @@ func rewriteValueS390X_OpS390XSRAD_0(v *Value) bool { v.AddArg(y) return true } - return false -} -func rewriteValueS390X_OpS390XSRAD_10(v *Value) bool { // match: (SRAD x (MOVBZreg y)) // cond: // result: (SRAD x y) @@ -38468,22 +38087,6 @@ func rewriteValueS390X_OpS390XSRAW_0(v *Value) bool { v.AddArg(y) return true } - // match: (SRAW x (MOVDreg y)) - // cond: - // result: (SRAW x y) - for { - _ = v.Args[1] - x := v.Args[0] - v_1 := v.Args[1] - if v_1.Op != OpS390XMOVDreg { - break - } - y := v_1.Args[0] - v.reset(OpS390XSRAW) - v.AddArg(x) - v.AddArg(y) - return true - } // match: (SRAW x (MOVWreg y)) // cond: // result: (SRAW x y) @@ -38564,9 +38167,6 @@ func rewriteValueS390X_OpS390XSRAW_0(v *Value) bool { v.AddArg(y) return true } - return false -} -func rewriteValueS390X_OpS390XSRAW_10(v *Value) bool { // match: (SRAW x (MOVBZreg y)) // cond: // result: (SRAW x y) @@ -38690,22 +38290,6 @@ func rewriteValueS390X_OpS390XSRD_0(v *Value) bool { v.AddArg(y) return true } - // match: (SRD x (MOVDreg y)) - // cond: - // result: (SRD x y) - for { - _ = v.Args[1] - x := v.Args[0] - v_1 := v.Args[1] - if v_1.Op != OpS390XMOVDreg { - break - } - y := v_1.Args[0] - v.reset(OpS390XSRD) - v.AddArg(x) - v.AddArg(y) - return true - } // match: (SRD x (MOVWreg y)) // cond: // result: (SRD x y) @@ -38786,9 +38370,6 @@ func rewriteValueS390X_OpS390XSRD_0(v *Value) bool { v.AddArg(y) return true } - return false -} -func rewriteValueS390X_OpS390XSRD_10(v *Value) bool { // match: (SRD x (MOVBZreg y)) // cond: // result: (SRD x y) @@ -38926,22 +38507,6 @@ func rewriteValueS390X_OpS390XSRW_0(v *Value) bool { v.AddArg(y) return true } - // match: (SRW x (MOVDreg y)) - // cond: - // result: (SRW x y) - for { - _ = v.Args[1] - x := v.Args[0] - v_1 := v.Args[1] - if v_1.Op != OpS390XMOVDreg { - break - } - y := v_1.Args[0] - v.reset(OpS390XSRW) - v.AddArg(x) - v.AddArg(y) - return true - } // match: (SRW x (MOVWreg y)) // cond: // result: (SRW x y) @@ -39022,9 +38587,6 @@ func rewriteValueS390X_OpS390XSRW_0(v *Value) bool { v.AddArg(y) return true } - return false -} -func rewriteValueS390X_OpS390XSRW_10(v *Value) bool { // match: (SRW x (MOVBZreg y)) // cond: // result: (SRW x y) diff --git a/test/codegen/memcombine.go b/test/codegen/memcombine.go index 747e23001d..d5f3af7692 100644 --- a/test/codegen/memcombine.go +++ b/test/codegen/memcombine.go @@ -57,6 +57,7 @@ func load_le16(b []byte) { // amd64:`MOVWLZX\s\(.*\),`,-`MOVB`,-`OR` // ppc64le:`MOVHZ\s`,-`MOVBZ` // arm64:`MOVHU\s\(R[0-9]+\),`,-`MOVB` + // s390x:`MOVHBR\s\(.*\),` sink16 = binary.LittleEndian.Uint16(b) } @@ -64,6 +65,7 @@ func load_le16_idx(b []byte, idx int) { // amd64:`MOVWLZX\s\(.*\),`,-`MOVB`,-`OR` // ppc64le:`MOVHZ\s`,-`MOVBZ` // arm64:`MOVHU\s\(R[0-9]+\)\(R[0-9]+\),`,-`MOVB` + // s390x:`MOVHBR\s\(.*\)\(.*\*1\),` sink16 = binary.LittleEndian.Uint16(b[idx:]) } @@ -103,6 +105,7 @@ func load_be16(b []byte) { // amd64:`ROLW\s\$8`,-`MOVB`,-`OR` // arm64:`REV16W`,`MOVHU\s\(R[0-9]+\),`,-`MOVB` // ppc64le:`MOVHBR` + // s390x:`MOVHZ\s\(.*\),`,-`OR`,-`ORW`,-`SLD`,-`SLW` sink16 = binary.BigEndian.Uint16(b) } @@ -110,6 +113,7 @@ func load_be16_idx(b []byte, idx int) { // amd64:`ROLW\s\$8`,-`MOVB`,-`OR` // arm64:`REV16W`,`MOVHU\s\(R[0-9]+\)\(R[0-9]+\),`,-`MOVB` // ppc64le:`MOVHBR` + // s390x:`MOVHZ\s\(.*\)\(.*\*1\),`,-`OR`,-`ORW`,-`SLD`,-`SLW` sink16 = binary.BigEndian.Uint16(b[idx:]) } @@ -351,6 +355,7 @@ func store_le64(b []byte) { // amd64:`MOVQ\s.*\(.*\)$`,-`SHR.` // arm64:`MOVD`,-`MOV[WBH]` // ppc64le:`MOVD\s`,-`MOV[BHW]\s` + // s390x:`MOVDBR\s.*\(.*\)$` binary.LittleEndian.PutUint64(b, sink64) } @@ -358,6 +363,7 @@ func store_le64_idx(b []byte, idx int) { // amd64:`MOVQ\s.*\(.*\)\(.*\*1\)$`,-`SHR.` // arm64:`MOVD\sR[0-9]+,\s\(R[0-9]+\)\(R[0-9]+\)`,-`MOV[BHW]` // ppc64le:`MOVD\s`,-`MOV[BHW]\s` + // s390x:`MOVDBR\s.*\(.*\)\(.*\*1\)$` binary.LittleEndian.PutUint64(b[idx:], sink64) } @@ -365,6 +371,7 @@ func store_le32(b []byte) { // amd64:`MOVL\s` // arm64:`MOVW`,-`MOV[BH]` // ppc64le:`MOVW\s` + // s390x:`MOVWBR\s.*\(.*\)$` binary.LittleEndian.PutUint32(b, sink32) } @@ -372,6 +379,7 @@ func store_le32_idx(b []byte, idx int) { // amd64:`MOVL\s` // arm64:`MOVW\sR[0-9]+,\s\(R[0-9]+\)\(R[0-9]+\)`,-`MOV[BH]` // ppc64le:`MOVW\s` + // s390x:`MOVWBR\s.*\(.*\)\(.*\*1\)$` binary.LittleEndian.PutUint32(b[idx:], sink32) } @@ -379,6 +387,7 @@ func store_le16(b []byte) { // amd64:`MOVW\s` // arm64:`MOVH`,-`MOVB` // ppc64le:`MOVH\s` + // s390x:`MOVHBR\s.*\(.*\)$` binary.LittleEndian.PutUint16(b, sink16) } @@ -386,6 +395,7 @@ func store_le16_idx(b []byte, idx int) { // amd64:`MOVW\s` // arm64:`MOVH\sR[0-9]+,\s\(R[0-9]+\)\(R[0-9]+\)`,-`MOVB` // ppc64le:`MOVH\s` + // s390x:`MOVHBR\s.*\(.*\)\(.*\*1\)$` binary.LittleEndian.PutUint16(b[idx:], sink16) } @@ -393,6 +403,7 @@ func store_be64(b []byte) { // amd64:`BSWAPQ`,-`SHR.` // arm64:`MOVD`,`REV`,-`MOV[WBH]`,-`REVW`,-`REV16W` // ppc64le:`MOVDBR` + // s390x:`MOVD\s.*\(.*\)$`,-`SRW\s`,-`SRD\s` binary.BigEndian.PutUint64(b, sink64) } @@ -400,6 +411,7 @@ func store_be64_idx(b []byte, idx int) { // amd64:`BSWAPQ`,-`SHR.` // arm64:`REV`,`MOVD\sR[0-9]+,\s\(R[0-9]+\)\(R[0-9]+\)`,-`MOV[BHW]`,-`REV16W`,-`REVW` // ppc64le:`MOVDBR` + // s390x:`MOVD\s.*\(.*\)\(.*\*1\)$`,-`SRW\s`,-`SRD\s` binary.BigEndian.PutUint64(b[idx:], sink64) } @@ -407,6 +419,7 @@ func store_be32(b []byte) { // amd64:`BSWAPL`,-`SHR.` // arm64:`MOVW`,`REVW`,-`MOV[BH]`,-`REV16W` // ppc64le:`MOVWBR` + // s390x:`MOVW\s.*\(.*\)$`,-`SRW\s`,-`SRD\s` binary.BigEndian.PutUint32(b, sink32) } @@ -414,6 +427,7 @@ func store_be32_idx(b []byte, idx int) { // amd64:`BSWAPL`,-`SHR.` // arm64:`REVW`,`MOVW\sR[0-9]+,\s\(R[0-9]+\)\(R[0-9]+\)`,-`MOV[BH]`,-`REV16W` // ppc64le:`MOVWBR` + // s390x:`MOVW\s.*\(.*\)\(.*\*1\)$`,-`SRW\s`,-`SRD\s` binary.BigEndian.PutUint32(b[idx:], sink32) } @@ -421,6 +435,7 @@ func store_be16(b []byte) { // amd64:`ROLW\s\$8`,-`SHR.` // arm64:`MOVH`,`REV16W`,-`MOVB` // ppc64le:`MOVHBR` + // s390x:`MOVH\s.*\(.*\)$`,-`SRW\s`,-`SRD\s` binary.BigEndian.PutUint16(b, sink16) } @@ -428,6 +443,7 @@ func store_be16_idx(b []byte, idx int) { // amd64:`ROLW\s\$8`,-`SHR.` // arm64:`MOVH\sR[0-9]+,\s\(R[0-9]+\)\(R[0-9]+\)`,`REV16W`,-`MOVB` // ppc64le:`MOVHBR` + // s390x:`MOVH\s.*\(.*\)\(.*\*1\)$`,-`SRW\s`,-`SRD\s` binary.BigEndian.PutUint16(b[idx:], sink16) } -- 2.50.0