]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: eliminate successive swaps
authorAlejandro García Montoro <alejandro.garciamontoro@gmail.com>
Fri, 14 May 2021 16:42:16 +0000 (18:42 +0200)
committerKeith Randall <khr@golang.org>
Sat, 9 Oct 2021 01:04:29 +0000 (01:04 +0000)
The code generated when storing eight bytes loaded from memory in big
endian introduced two successive byte swaps that did not actually
modified the data.

The new rules match this specific pattern both for amd64 and for arm64,
eliminating the double swap.

Fixes #41684

Change-Id: Icb6dc20b68e4393cef4fe6a07b33aba0d18c3ff3
Reviewed-on: https://go-review.googlesource.com/c/go/+/320073
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Daniel Martí <mvdan@mvdan.cc>
Trust: Dmitri Shuralyov <dmitshur@golang.org>

src/cmd/compile/internal/ssa/gen/AMD64.rules
src/cmd/compile/internal/ssa/gen/ARM64.rules
src/cmd/compile/internal/ssa/rewriteAMD64.go
src/cmd/compile/internal/ssa/rewriteARM64.go
test/codegen/memcombine.go

index 1c63a3f70c867d9b1d77ba1dc5f4136fbadc09d3..9c476d885a07c865b0fa785ff0ca53a243156d0b 100644 (file)
 (AND(Q|L) x (NEG(Q|L) x))           && buildcfg.GOAMD64 >= 3 => (BLSI(Q|L) x)
 (XOR(Q|L) x (ADD(Q|L)const [-1] x)) && buildcfg.GOAMD64 >= 3 => (BLSMSK(Q|L) x)
 (AND(Q|L) x (ADD(Q|L)const [-1] x)) && buildcfg.GOAMD64 >= 3 => (BLSR(Q|L) x)
+
+(BSWAP(Q|L) (BSWAP(Q|L) p)) => p
index 02fb4e19905cb5b0416b2386756f216b97dd5a5c..d34e1899db50909a1e0cabd212840c36400bef88 100644 (file)
        && isInlinableMemmove(dst, src, sz, config)
        && clobber(call)
        => (Move [sz] dst src mem)
+
+((REV|REVW) ((REV|REVW) p)) => p
index 10d3afbc7dd1c546c287dd8769a7132be1badf78..88c76dd1693eb92753937d6529aa94cb1f946243 100644 (file)
@@ -70,6 +70,10 @@ func rewriteValueAMD64(v *Value) bool {
                return rewriteValueAMD64_OpAMD64ANDQmodify(v)
        case OpAMD64BSFQ:
                return rewriteValueAMD64_OpAMD64BSFQ(v)
+       case OpAMD64BSWAPL:
+               return rewriteValueAMD64_OpAMD64BSWAPL(v)
+       case OpAMD64BSWAPQ:
+               return rewriteValueAMD64_OpAMD64BSWAPQ(v)
        case OpAMD64BTCLconst:
                return rewriteValueAMD64_OpAMD64BTCLconst(v)
        case OpAMD64BTCQconst:
@@ -3607,6 +3611,34 @@ func rewriteValueAMD64_OpAMD64BSFQ(v *Value) bool {
        }
        return false
 }
+func rewriteValueAMD64_OpAMD64BSWAPL(v *Value) bool {
+       v_0 := v.Args[0]
+       // match: (BSWAPL (BSWAPL p))
+       // result: p
+       for {
+               if v_0.Op != OpAMD64BSWAPL {
+                       break
+               }
+               p := v_0.Args[0]
+               v.copyOf(p)
+               return true
+       }
+       return false
+}
+func rewriteValueAMD64_OpAMD64BSWAPQ(v *Value) bool {
+       v_0 := v.Args[0]
+       // match: (BSWAPQ (BSWAPQ p))
+       // result: p
+       for {
+               if v_0.Op != OpAMD64BSWAPQ {
+                       break
+               }
+               p := v_0.Args[0]
+               v.copyOf(p)
+               return true
+       }
+       return false
+}
 func rewriteValueAMD64_OpAMD64BTCLconst(v *Value) bool {
        v_0 := v.Args[0]
        // match: (BTCLconst [c] (XORLconst [d] x))
index 8ad9e400eb056b1462936708551b30d41e708a25..ad34855c30f6be4e70f6c4af52e5104c1f54abf8 100644 (file)
@@ -335,6 +335,10 @@ func rewriteValueARM64(v *Value) bool {
                return rewriteValueARM64_OpARM64ORshiftRL(v)
        case OpARM64ORshiftRO:
                return rewriteValueARM64_OpARM64ORshiftRO(v)
+       case OpARM64REV:
+               return rewriteValueARM64_OpARM64REV(v)
+       case OpARM64REVW:
+               return rewriteValueARM64_OpARM64REVW(v)
        case OpARM64ROR:
                return rewriteValueARM64_OpARM64ROR(v)
        case OpARM64RORW:
@@ -20299,6 +20303,34 @@ func rewriteValueARM64_OpARM64ORshiftRO(v *Value) bool {
        }
        return false
 }
+func rewriteValueARM64_OpARM64REV(v *Value) bool {
+       v_0 := v.Args[0]
+       // match: (REV (REV p))
+       // result: p
+       for {
+               if v_0.Op != OpARM64REV {
+                       break
+               }
+               p := v_0.Args[0]
+               v.copyOf(p)
+               return true
+       }
+       return false
+}
+func rewriteValueARM64_OpARM64REVW(v *Value) bool {
+       v_0 := v.Args[0]
+       // match: (REVW (REVW p))
+       // result: p
+       for {
+               if v_0.Op != OpARM64REVW {
+                       break
+               }
+               p := v_0.Args[0]
+               v.copyOf(p)
+               return true
+       }
+       return false
+}
 func rewriteValueARM64_OpARM64ROR(v *Value) bool {
        v_1 := v.Args[1]
        v_0 := v.Args[0]
index d74dae07f5b5481379a03524dc1250528999c060..2a0c534df0d06d3c75d6536e80a620ddfbaca259 100644 (file)
@@ -432,6 +432,18 @@ func store_be32(b []byte) {
        binary.BigEndian.PutUint32(b, sink32)
 }
 
+func store_be64_load(b, x *[8]byte) {
+       // arm64:-`REV`
+       // amd64:-`BSWAPQ`
+       binary.BigEndian.PutUint64(b[:], binary.BigEndian.Uint64(x[:]))
+}
+
+func store_be32_load(b, x *[8]byte) {
+       // arm64:-`REVW`
+       // amd64:-`BSWAPL`
+       binary.BigEndian.PutUint32(b[:], binary.BigEndian.Uint32(x[:]))
+}
+
 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`