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 +// 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"). -// Propagate constants through type conversions. -(MOVDreg (MOVDconst [c])) -> (MOVDconst [c]) -(MOVDnop (MOVDconst [c])) -> (MOVDconst [c]) +// 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) -// 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) +// 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) -// 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) +// 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) -(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) +// 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 -(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) +// 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 -(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) +// 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 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) +// 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,9 +10950,245 @@ func rewriteValueS390X_OpS390XMOVBZloadidx_0(v *Value) bool { return false } func rewriteValueS390X_OpS390XMOVBZreg_0(v *Value) bool { + b := v.Block + // match: (MOVBZreg e:(MOVBreg x)) + // cond: clobberIfDead(e) + // result: (MOVBZreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVBreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + 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 + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVBZreg) + v.AddArg(x) + return true + } + // match: (MOVBZreg e:(MOVWreg x)) + // cond: clobberIfDead(e) + // result: (MOVBZreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVWreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + 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 + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVBZreg) + v.AddArg(x) + return true + } + // 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 != 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: (MOVBZreg 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: (MOVBZreg 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: (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 + } + 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 + } + t := x.Type + if !(!t.IsSigned() && t.Size() == 1) { + break + } + v.reset(OpCopy) + v.Type = x.Type + 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 { + 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 - // result: (MOVDreg x) + // 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 != OpS390XMOVDLT { @@ -10972,16 +11205,17 @@ 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:(MOVDLE (MOVDconst [c]) (MOVDconst [d]) _)) - // cond: int64(uint8(c)) == c && int64(uint8(d)) == d - // result: (MOVDreg x) + // 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 != OpS390XMOVDLE { @@ -10998,16 +11232,17 @@ 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:(MOVDGT (MOVDconst [c]) (MOVDconst [d]) _)) - // cond: int64(uint8(c)) == c && int64(uint8(d)) == d - // result: (MOVDreg x) + // 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 != OpS390XMOVDGT { @@ -11024,16 +11259,17 @@ 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:(MOVDGE (MOVDconst [c]) (MOVDconst [d]) _)) - // cond: int64(uint8(c)) == c && int64(uint8(d)) == d - // result: (MOVDreg x) + // 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 != OpS390XMOVDGE { @@ -11050,16 +11286,17 @@ 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:(MOVDEQ (MOVDconst [c]) (MOVDconst [d]) _)) - // cond: int64(uint8(c)) == c && int64(uint8(d)) == d - // result: (MOVDreg x) + // 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 { @@ -11076,16 +11313,17 @@ 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) + // 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 { @@ -11102,16 +11340,17 @@ 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) + // 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 { @@ -11128,16 +11367,22 @@ 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 } + 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 - // result: (MOVDreg x) + // 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 { @@ -11154,187 +11399,12 @@ 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.AddArg(x) - return true - } - // match: (MOVBZreg x:(MOVBZload _ _)) - // cond: - // result: (MOVDreg x) - for { - x := v.Args[0] - if x.Op != OpS390XMOVBZload { - 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 { - break - } - t := x.Type - if !(is8BitInt(t) && !isSigned(t)) { - 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 { - break - } - v.reset(OpS390XMOVDreg) - v.AddArg(x) - return true - } - // match: (MOVBZreg (MOVBreg x)) - // cond: - // result: (MOVBZreg x) - for { - v_0 := v.Args[0] - if v_0.Op != OpS390XMOVBreg { - 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 { - 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 { - 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, 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:(MOVBload [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 != 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, 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 { - 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, v.Type) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) - 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) - for { - 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, 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,64 +11659,232 @@ func rewriteValueS390X_OpS390XMOVBloadidx_0(v *Value) bool { } func rewriteValueS390X_OpS390XMOVBreg_0(v *Value) bool { b := v.Block - typ := &b.Func.Config.Types + // match: (MOVBreg 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: (MOVBreg e:(MOVHreg x)) + // cond: clobberIfDead(e) + // result: (MOVBreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVHreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVBreg) + v.AddArg(x) + return true + } + // match: (MOVBreg e:(MOVWreg x)) + // cond: clobberIfDead(e) + // result: (MOVBreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVWreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVBreg) + v.AddArg(x) + return true + } + // match: (MOVBreg e:(MOVBZreg x)) + // cond: clobberIfDead(e) + // result: (MOVBreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVBZreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVBreg) + v.AddArg(x) + return true + } + // match: (MOVBreg e:(MOVHZreg x)) + // cond: clobberIfDead(e) + // result: (MOVBreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVHZreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVBreg) + v.AddArg(x) + return true + } + // 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: - // 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: (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:(MOVBZload [o] {s} p mem)) + // cond: x.Uses == 1 && clobber(x) + // result: @x.Block (MOVBload [o] {s} p mem) + for { + t := v.Type + x := v.Args[0] + if x.Op != OpS390XMOVBZload { + break + } + 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, OpS390XMOVBload, 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_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 [o] {s} p i mem) + for { + t := v.Type + x := v.Args[0] + if x.Op != OpS390XMOVBZloadidx { + 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, OpS390XMOVBloadidx, 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: (MOVBreg x:(Arg )) - // cond: is8BitInt(t) && isSigned(t) - // result: (MOVDreg x) + // cond: t.IsSigned() && t.Size() == 1 + // result: x for { x := v.Args[0] if x.Op != OpArg { break } t := x.Type - if !(is8BitInt(t) && isSigned(t)) { + if !(t.IsSigned() && t.Size() == 1) { break } - v.reset(OpS390XMOVDreg) - v.AddArg(x) - return true - } - // match: (MOVBreg x:(MOVBreg _)) - // cond: - // result: (MOVDreg x) - for { - x := v.Args[0] - if x.Op != OpS390XMOVBreg { - break - } - v.reset(OpS390XMOVDreg) - v.AddArg(x) - return true - } - // match: (MOVBreg (MOVBZreg x)) - // cond: - // result: (MOVBreg x) - for { - v_0 := v.Args[0] - if v_0.Op != OpS390XMOVBZreg { - break - } - x := v_0.Args[0] - v.reset(OpS390XMOVBreg) + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } // match: (MOVBreg (MOVDconst [c])) // cond: - // result: (MOVDconst [int64(int8(c))]) + // result: (MOVDconst [int64( int8(c))]) for { v_0 := v.Args[0] if v_0.Op != OpS390XMOVDconst { @@ -11657,110 +11895,6 @@ func rewriteValueS390X_OpS390XMOVBreg_0(v *Value) bool { v.AuxInt = int64(int8(c)) return true } - // match: (MOVBreg x:(MOVBZload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVBload [off] {sym} ptr mem) - for { - 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, OpS390XMOVBload, v.Type) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - // match: (MOVBreg x:(MOVBload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVBload [off] {sym} ptr mem) - for { - 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, v.Type) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - // match: (MOVBreg x:(MOVBZloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVBloadidx [off] {sym} ptr idx mem) - for { - 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, OpS390XMOVBloadidx, v.Type) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - 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) - for { - 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, v.Type) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) - return true - } // match: (MOVBreg (ANDWconst [m] x)) // cond: int8(m) >= 0 // result: (MOVWZreg (ANDWconst [int64( uint8(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,83 +16728,261 @@ func rewriteValueS390X_OpS390XMOVHZloadidx_0(v *Value) bool { return false } func rewriteValueS390X_OpS390XMOVHZreg_0(v *Value) bool { - b := v.Block + // match: (MOVHZreg e:(MOVBZreg x)) + // cond: clobberIfDead(e) + // result: (MOVBZreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVBZreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVBZreg) + v.AddArg(x) + return true + } + // match: (MOVHZreg e:(MOVHreg x)) + // cond: clobberIfDead(e) + // result: (MOVHZreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVHreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVHZreg) + v.AddArg(x) + return true + } + // 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: - // result: (MOVDreg x) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x for { x := v.Args[0] if x.Op != OpS390XMOVBZload { break } _ = x.Args[1] - v.reset(OpS390XMOVDreg) + if !(!x.Type.IsSigned() || x.Type.Size() > 1) { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVHZreg 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: (MOVHZreg 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: (MOVHZreg x:(MOVHZload _ _)) - // cond: - // result: (MOVDreg x) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 2) + // result: x for { x := v.Args[0] if x.Op != OpS390XMOVHZload { break } _ = x.Args[1] - v.reset(OpS390XMOVDreg) + if !(!x.Type.IsSigned() || x.Type.Size() > 2) { + break + } + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } + // match: (MOVHZreg x:(MOVHZloadidx _ _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 2) + // result: x + for { + x := v.Args[0] + if x.Op != OpS390XMOVHZloadidx { + break + } + _ = x.Args[2] + if !(!x.Type.IsSigned() || x.Type.Size() > 2) { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + 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 != OpS390XMOVHZloadidx { + break + } + _ = 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:(MOVHload [o] {s} p mem)) + // cond: x.Uses == 1 && clobber(x) + // result: @x.Block (MOVHZload [o] {s} p mem) + for { + t := v.Type + x := v.Args[0] + if x.Op != OpS390XMOVHload { + break + } + 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, OpS390XMOVHZload, t) + v.reset(OpCopy) + v.AddArg(v0) + v0.AuxInt = o + v0.Aux = s + v0.AddArg(p) + v0.AddArg(mem) + return true + } + // match: (MOVHZreg x:(MOVHloadidx [o] {s} p i mem)) + // cond: x.Uses == 1 && clobber(x) + // result: @x.Block (MOVHZloadidx [o] {s} p i mem) + for { + t := v.Type + x := v.Args[0] + if x.Op != OpS390XMOVHloadidx { + 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, OpS390XMOVHZloadidx, 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: (MOVHZreg x:(Arg )) - // cond: (is8BitInt(t) || is16BitInt(t)) && !isSigned(t) - // result: (MOVDreg x) + // cond: !t.IsSigned() && t.Size() <= 2 + // result: x for { x := v.Args[0] if x.Op != OpArg { break } t := x.Type - if !((is8BitInt(t) || is16BitInt(t)) && !isSigned(t)) { + if !(!t.IsSigned() && t.Size() <= 2) { break } - v.reset(OpS390XMOVDreg) - v.AddArg(x) - return true - } - // match: (MOVHZreg x:(MOVBZreg _)) - // cond: - // result: (MOVDreg x) - for { - x := v.Args[0] - if x.Op != OpS390XMOVBZreg { - break - } - v.reset(OpS390XMOVDreg) - v.AddArg(x) - return true - } - // match: (MOVHZreg x:(MOVHZreg _)) - // cond: - // result: (MOVDreg x) - for { - x := v.Args[0] - if x.Op != OpS390XMOVHZreg { - break - } - v.reset(OpS390XMOVDreg) - v.AddArg(x) - return true - } - // match: (MOVHZreg (MOVHreg x)) - // cond: - // result: (MOVHZreg x) - for { - v_0 := v.Args[0] - if v_0.Op != OpS390XMOVHreg { - break - } - x := v_0.Args[0] - v.reset(OpS390XMOVHZreg) + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } @@ -17524,115 +16999,6 @@ func rewriteValueS390X_OpS390XMOVHZreg_0(v *Value) bool { v.AuxInt = int64(uint16(c)) return true } - // match: (MOVHZreg x:(MOVHZload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVHZload [off] {sym} ptr mem) - for { - 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, v.Type) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - // match: (MOVHZreg x:(MOVHload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVHZload [off] {sym} ptr mem) - for { - 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, OpS390XMOVHZload, v.Type) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - // match: (MOVHZreg x:(MOVHZloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVHZloadidx [off] {sym} ptr idx mem) - for { - 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, v.Type) - 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_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) - for { - 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, OpS390XMOVHZloadidx, v.Type) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) - return true - } // match: (MOVHZreg (ANDWconst [m] x)) // cond: // result: (MOVWZreg (ANDWconst [int64(uint16(m))] x)) @@ -17885,108 +17251,312 @@ func rewriteValueS390X_OpS390XMOVHloadidx_0(v *Value) bool { return false } func rewriteValueS390X_OpS390XMOVHreg_0(v *Value) bool { - b := v.Block + // match: (MOVHreg 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: (MOVHreg 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: (MOVHreg e:(MOVWreg x)) + // cond: clobberIfDead(e) + // result: (MOVHreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVWreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVHreg) + v.AddArg(x) + return true + } + // match: (MOVHreg e:(MOVHZreg x)) + // cond: clobberIfDead(e) + // result: (MOVHreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVHZreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVHreg) + v.AddArg(x) + return true + } + // match: (MOVHreg e:(MOVWZreg x)) + // cond: clobberIfDead(e) + // result: (MOVHreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVWZreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVHreg) + v.AddArg(x) + return true + } // match: (MOVHreg 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: (MOVHreg x:(MOVBZload _ _)) - // 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 != 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: (MOVHreg 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: (MOVHreg 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: (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 + } + return false +} +func rewriteValueS390X_OpS390XMOVHreg_10(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // 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 [o] {s} p mem) + for { + t := v.Type + x := v.Args[0] + if x.Op != OpS390XMOVHZload { + break + } + 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, OpS390XMOVHload, t) + v.reset(OpCopy) + v.AddArg(v0) + v0.AuxInt = o + v0.Aux = s + v0.AddArg(p) + v0.AddArg(mem) + return true + } + // match: (MOVHreg x:(MOVHZloadidx [o] {s} p i mem)) + // cond: x.Uses == 1 && clobber(x) + // result: @x.Block (MOVHloadidx [o] {s} p i mem) + for { + t := v.Type + x := v.Args[0] + if x.Op != OpS390XMOVHZloadidx { + 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, OpS390XMOVHloadidx, 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: (MOVHreg x:(Arg )) - // cond: (is8BitInt(t) || is16BitInt(t)) && isSigned(t) - // result: (MOVDreg x) + // cond: t.IsSigned() && t.Size() <= 2 + // result: x for { x := v.Args[0] if x.Op != OpArg { break } t := x.Type - if !((is8BitInt(t) || is16BitInt(t)) && isSigned(t)) { + if !(t.IsSigned() && t.Size() <= 2) { break } - v.reset(OpS390XMOVDreg) - v.AddArg(x) - return true - } - // match: (MOVHreg x:(MOVBreg _)) - // cond: - // result: (MOVDreg x) - for { - x := v.Args[0] - if x.Op != OpS390XMOVBreg { - break - } - v.reset(OpS390XMOVDreg) - v.AddArg(x) - return true - } - // match: (MOVHreg x:(MOVBZreg _)) - // cond: - // result: (MOVDreg x) - for { - x := v.Args[0] - if x.Op != OpS390XMOVBZreg { - break - } - v.reset(OpS390XMOVDreg) - v.AddArg(x) - return true - } - // match: (MOVHreg x:(MOVHreg _)) - // cond: - // result: (MOVDreg x) - for { - x := v.Args[0] - if x.Op != OpS390XMOVHreg { - break - } - v.reset(OpS390XMOVDreg) - v.AddArg(x) - return true - } - // match: (MOVHreg (MOVHZreg x)) - // cond: - // result: (MOVHreg x) - for { - v_0 := v.Args[0] - if v_0.Op != OpS390XMOVHZreg { - break - } - x := v_0.Args[0] - v.reset(OpS390XMOVHreg) + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } @@ -18003,115 +17573,6 @@ func rewriteValueS390X_OpS390XMOVHreg_0(v *Value) bool { v.AuxInt = int64(int16(c)) return true } - // match: (MOVHreg x:(MOVHZload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVHload [off] {sym} ptr mem) - for { - 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, OpS390XMOVHload, v.Type) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - return false -} -func rewriteValueS390X_OpS390XMOVHreg_10(v *Value) bool { - b := v.Block - typ := &b.Func.Config.Types - // match: (MOVHreg x:(MOVHload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVHload [off] {sym} ptr mem) - for { - 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, v.Type) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - // match: (MOVHreg x:(MOVHZloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVHloadidx [off] {sym} ptr idx mem) - for { - 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, OpS390XMOVHloadidx, v.Type) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - 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) - for { - 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, v.Type) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - v0.AddArg(mem) - return true - } // match: (MOVHreg (ANDWconst [m] x)) // cond: int16(m) >= 0 // result: (MOVWZreg (ANDWconst [int64(uint16(m))] x)) @@ -20264,108 +19725,295 @@ func rewriteValueS390X_OpS390XMOVWZloadidx_0(v *Value) bool { return false } func rewriteValueS390X_OpS390XMOVWZreg_0(v *Value) bool { - b := v.Block + // match: (MOVWZreg e:(MOVBZreg x)) + // cond: clobberIfDead(e) + // result: (MOVBZreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVBZreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVBZreg) + v.AddArg(x) + return true + } + // match: (MOVWZreg 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: (MOVWZreg e:(MOVWreg x)) + // cond: clobberIfDead(e) + // result: (MOVWZreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVWreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVWZreg) + v.AddArg(x) + return true + } + // match: (MOVWZreg e:(MOVWZreg x)) + // cond: clobberIfDead(e) + // result: (MOVWZreg x) + for { + e := v.Args[0] + if e.Op != OpS390XMOVWZreg { + break + } + x := e.Args[0] + if !(clobberIfDead(e)) { + break + } + v.reset(OpS390XMOVWZreg) + v.AddArg(x) + return true + } // match: (MOVWZreg x:(MOVBZload _ _)) - // cond: - // result: (MOVDreg x) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 1) + // result: x for { x := v.Args[0] if x.Op != OpS390XMOVBZload { break } _ = x.Args[1] - v.reset(OpS390XMOVDreg) + if !(!x.Type.IsSigned() || x.Type.Size() > 1) { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVWZreg 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: (MOVWZreg 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: (MOVWZreg x:(MOVHZload _ _)) - // cond: - // result: (MOVDreg x) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 2) + // result: x for { x := v.Args[0] if x.Op != OpS390XMOVHZload { break } _ = x.Args[1] - v.reset(OpS390XMOVDreg) + if !(!x.Type.IsSigned() || x.Type.Size() > 2) { + break + } + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } + // match: (MOVWZreg x:(MOVHZloadidx _ _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 2) + // result: x + for { + x := v.Args[0] + if x.Op != OpS390XMOVHZloadidx { + break + } + _ = 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:(MOVHZloadidx _ _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 2) + // result: x + for { + x := v.Args[0] + if x.Op != OpS390XMOVHZloadidx { + break + } + _ = x.Args[2] + if !(!x.Type.IsSigned() || x.Type.Size() > 2) { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + return false +} +func rewriteValueS390X_OpS390XMOVWZreg_10(v *Value) bool { + b := v.Block // match: (MOVWZreg x:(MOVWZload _ _)) - // cond: - // result: (MOVDreg x) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 4) + // result: x for { x := v.Args[0] if x.Op != OpS390XMOVWZload { break } _ = x.Args[1] - v.reset(OpS390XMOVDreg) + 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 [o] {s} p mem) + for { + t := v.Type + x := v.Args[0] + if x.Op != OpS390XMOVWload { + break + } + 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, OpS390XMOVWZload, t) + v.reset(OpCopy) + v.AddArg(v0) + v0.AuxInt = o + v0.Aux = s + v0.AddArg(p) + v0.AddArg(mem) + return true + } + // match: (MOVWZreg x:(MOVWloadidx [o] {s} p i mem)) + // cond: x.Uses == 1 && clobber(x) + // result: @x.Block (MOVWZloadidx [o] {s} p i mem) + for { + t := v.Type + x := v.Args[0] + if x.Op != OpS390XMOVWloadidx { + 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, OpS390XMOVWZloadidx, 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: (MOVWZreg x:(Arg )) - // cond: (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && !isSigned(t) - // result: (MOVDreg x) + // cond: !t.IsSigned() && t.Size() <= 4 + // result: x for { x := v.Args[0] if x.Op != OpArg { break } t := x.Type - if !((is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && !isSigned(t)) { + if !(!t.IsSigned() && t.Size() <= 4) { break } - v.reset(OpS390XMOVDreg) - v.AddArg(x) - return true - } - // match: (MOVWZreg x:(MOVBZreg _)) - // cond: - // result: (MOVDreg x) - for { - x := v.Args[0] - if x.Op != OpS390XMOVBZreg { - break - } - v.reset(OpS390XMOVDreg) - v.AddArg(x) - return true - } - // match: (MOVWZreg x:(MOVHZreg _)) - // cond: - // result: (MOVDreg x) - for { - x := v.Args[0] - if x.Op != OpS390XMOVHZreg { - break - } - v.reset(OpS390XMOVDreg) - v.AddArg(x) - return true - } - // match: (MOVWZreg x:(MOVWZreg _)) - // cond: - // result: (MOVDreg x) - for { - x := v.Args[0] - if x.Op != OpS390XMOVWZreg { - break - } - v.reset(OpS390XMOVDreg) - v.AddArg(x) - return true - } - // match: (MOVWZreg (MOVWreg x)) - // cond: - // result: (MOVWZreg x) - for { - v_0 := v.Args[0] - if v_0.Op != OpS390XMOVWreg { - break - } - x := v_0.Args[0] - v.reset(OpS390XMOVWZreg) + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } @@ -20382,114 +20030,6 @@ func rewriteValueS390X_OpS390XMOVWZreg_0(v *Value) bool { v.AuxInt = int64(uint32(c)) return true } - // match: (MOVWZreg x:(MOVWZload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVWZload [off] {sym} ptr mem) - for { - 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, v.Type) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - return false -} -func rewriteValueS390X_OpS390XMOVWZreg_10(v *Value) bool { - b := v.Block - // match: (MOVWZreg x:(MOVWload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVWZload [off] {sym} ptr mem) - for { - 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, OpS390XMOVWZload, v.Type) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - // match: (MOVWZreg x:(MOVWZloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVWZloadidx [off] {sym} ptr idx mem) - for { - 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, v.Type) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - 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) - for { - 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, OpS390XMOVWZloadidx, v.Type) - 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_OpS390XMOVWload_0(v *Value) bool { @@ -20725,132 +20265,169 @@ 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) - v.AddArg(x) - return true - } - // match: (MOVWreg x:(Arg )) - // cond: (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && isSigned(t) - // result: (MOVDreg x) - for { - x := v.Args[0] - if x.Op != OpArg { + _ = x.Args[2] + if !(x.Type.IsSigned() || x.Type.Size() == 8) { break } - t := x.Type - if !((is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && isSigned(t)) { - break - } - v.reset(OpS390XMOVDreg) - v.AddArg(x) - return true - } - // match: (MOVWreg x:(MOVBreg _)) - // cond: - // result: (MOVDreg x) - for { - x := v.Args[0] - if x.Op != OpS390XMOVBreg { - break - } - v.reset(OpS390XMOVDreg) - v.AddArg(x) - return true - } - // match: (MOVWreg x:(MOVBZreg _)) - // cond: - // result: (MOVDreg x) - for { - x := v.Args[0] - if x.Op != OpS390XMOVBZreg { - break - } - v.reset(OpS390XMOVDreg) - v.AddArg(x) - return true - } - // match: (MOVWreg x:(MOVHreg _)) - // cond: - // result: (MOVDreg x) - for { - x := v.Args[0] - if x.Op != OpS390XMOVHreg { - break - } - v.reset(OpS390XMOVDreg) - v.AddArg(x) - return true - } - // match: (MOVWreg x:(MOVHZreg _)) - // cond: - // result: (MOVDreg x) - for { - x := v.Args[0] - if x.Op != OpS390XMOVHZreg { - break - } - v.reset(OpS390XMOVDreg) + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } @@ -20858,28 +20435,231 @@ func rewriteValueS390X_OpS390XMOVWreg_0(v *Value) bool { } func rewriteValueS390X_OpS390XMOVWreg_10(v *Value) bool { b := v.Block - // match: (MOVWreg x:(MOVWreg _)) - // cond: - // result: (MOVDreg x) + // match: (MOVWreg x:(MOVWload _ _)) + // cond: (x.Type.IsSigned() || x.Type.Size() == 8) + // result: x for { x := v.Args[0] - if x.Op != OpS390XMOVWreg { + if x.Op != OpS390XMOVWload { 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: (MOVWreg (MOVWZreg x)) - // cond: - // result: (MOVWreg x) + // match: (MOVWreg x:(MOVWloadidx _ _ _)) + // cond: (x.Type.IsSigned() || x.Type.Size() == 8) + // result: x for { - v_0 := v.Args[0] - if v_0.Op != OpS390XMOVWZreg { + x := v.Args[0] + if x.Op != OpS390XMOVWloadidx { break } - x := v_0.Args[0] - v.reset(OpS390XMOVWreg) + _ = 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:(MOVWloadidx _ _ _)) + // cond: (x.Type.IsSigned() || x.Type.Size() == 8) + // result: x + for { + x := v.Args[0] + if x.Op != OpS390XMOVWloadidx { + 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:(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: (MOVWreg 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: (MOVWreg 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: (MOVWreg x:(MOVHZload _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 2) + // result: x + for { + x := v.Args[0] + if x.Op != OpS390XMOVHZload { + break + } + _ = 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 x:(MOVHZloadidx _ _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 2) + // result: x + for { + x := v.Args[0] + if x.Op != OpS390XMOVHZloadidx { + break + } + _ = 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:(MOVHZloadidx _ _ _)) + // cond: (!x.Type.IsSigned() || x.Type.Size() > 2) + // result: x + for { + x := v.Args[0] + if x.Op != OpS390XMOVHZloadidx { + break + } + _ = 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 [o] {s} p mem)) + // cond: x.Uses == 1 && clobber(x) + // result: @x.Block (MOVWload [o] {s} p mem) + for { + t := v.Type + x := v.Args[0] + if x.Op != OpS390XMOVWZload { + break + } + 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, OpS390XMOVWload, 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_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 [o] {s} p i mem) + for { + t := v.Type + x := v.Args[0] + if x.Op != OpS390XMOVWZloadidx { + 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, OpS390XMOVWloadidx, 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: (MOVWreg x:(Arg )) + // cond: t.IsSigned() && t.Size() <= 4 + // result: x + for { + x := v.Args[0] + if x.Op != OpArg { + break + } + t := x.Type + if !(t.IsSigned() && t.Size() <= 4) { + break + } + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } @@ -20896,110 +20676,6 @@ func rewriteValueS390X_OpS390XMOVWreg_10(v *Value) bool { v.AuxInt = int64(int32(c)) return true } - // match: (MOVWreg x:(MOVWZload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVWload [off] {sym} ptr mem) - for { - 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, OpS390XMOVWload, v.Type) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - // match: (MOVWreg x:(MOVWload [off] {sym} ptr mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVWload [off] {sym} ptr mem) - for { - 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, v.Type) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(mem) - return true - } - // match: (MOVWreg x:(MOVWZloadidx [off] {sym} ptr idx mem)) - // cond: x.Uses == 1 && clobber(x) - // result: @x.Block (MOVWloadidx [off] {sym} ptr idx mem) - for { - 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, OpS390XMOVWloadidx, v.Type) - v.reset(OpCopy) - v.AddArg(v0) - v0.AuxInt = off - v0.Aux = sym - v0.AddArg(ptr) - v0.AddArg(idx) - 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) - for { - 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, v.Type) - 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_OpS390XMOVWstore_0(v *Value) bool { @@ -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) }