]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix 4-byte unaligned load rules
authorKeith Randall <khr@golang.org>
Mon, 19 Sep 2016 21:35:41 +0000 (14:35 -0700)
committerKeith Randall <khr@golang.org>
Fri, 23 Sep 2016 19:32:37 +0000 (19:32 +0000)
The 2-byte rule was firing before the 4-byte rule, preventing
the 4-byte rule from firing.  Update the 4-byte rule to use
the results of the 2-byte rule instead.

Add some tests to make sure we don't regress again.

Fixes #17147

Change-Id: Icfeccd9f2b96450981086a52edd76afb3191410a
Reviewed-on: https://go-review.googlesource.com/29382
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/compile/internal/gc/asm_test.go
src/cmd/compile/internal/ssa/gen/386.rules
src/cmd/compile/internal/ssa/gen/AMD64.rules
src/cmd/compile/internal/ssa/rewrite386.go
src/cmd/compile/internal/ssa/rewriteAMD64.go

index 54cc9319db6eb32fdf320a707e32230b91e808e0..b0635cd308b95b5e7e47f844e2a21a60b037e615 100644 (file)
@@ -20,7 +20,6 @@ import (
 
 // TestAssembly checks to make sure the assembly generated for
 // functions contains certain expected instructions.
-// Note: this test will fail if -ssa=0.
 func TestAssembly(t *testing.T) {
        testenv.MustHaveGoBuild(t)
        if runtime.GOOS == "windows" {
@@ -34,7 +33,7 @@ func TestAssembly(t *testing.T) {
        defer os.RemoveAll(dir)
 
        for _, test := range asmTests {
-               asm := compileToAsm(t, dir, test.arch, fmt.Sprintf(template, test.function))
+               asm := compileToAsm(t, dir, test.arch, test.os, fmt.Sprintf(template, test.function))
                // Get rid of code for "".init. Also gets rid of type algorithms & other junk.
                if i := strings.Index(asm, "\n\"\".init "); i >= 0 {
                        asm = asm[:i+1]
@@ -49,7 +48,7 @@ func TestAssembly(t *testing.T) {
 
 // compile compiles the package pkg for architecture arch and
 // returns the generated assembly.  dir is a scratch directory.
-func compileToAsm(t *testing.T, dir, arch, pkg string) string {
+func compileToAsm(t *testing.T, dir, goarch, goos, pkg string) string {
        // Create source.
        src := filepath.Join(dir, "test.go")
        f, err := os.Create(src)
@@ -59,9 +58,27 @@ func compileToAsm(t *testing.T, dir, arch, pkg string) string {
        f.Write([]byte(pkg))
        f.Close()
 
+       // First, install any dependencies we need.  This builds the required export data
+       // for any packages that are imported.
+       // TODO: extract dependencies automatically?
        var stdout, stderr bytes.Buffer
-       cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-S", "-o", filepath.Join(dir, "out.o"), src)
-       cmd.Env = mergeEnvLists([]string{"GOARCH=" + arch}, os.Environ())
+       cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", filepath.Join(dir, "encoding/binary.a"), "encoding/binary")
+       cmd.Env = mergeEnvLists([]string{"GOARCH=" + goarch, "GOOS=" + goos}, os.Environ())
+       cmd.Stdout = &stdout
+       cmd.Stderr = &stderr
+       if err := cmd.Run(); err != nil {
+               panic(err)
+       }
+       if s := stdout.String(); s != "" {
+               panic(fmt.Errorf("Stdout = %s\nWant empty", s))
+       }
+       if s := stderr.String(); s != "" {
+               panic(fmt.Errorf("Stderr = %s\nWant empty", s))
+       }
+
+       // Now, compile the individual file for which we want to see the generated assembly.
+       cmd = exec.Command(testenv.GoToolPath(t), "tool", "compile", "-I", dir, "-S", "-o", filepath.Join(dir, "out.o"), src)
+       cmd.Env = mergeEnvLists([]string{"GOARCH=" + goarch, "GOOS=" + goos}, os.Environ())
        cmd.Stdout = &stdout
        cmd.Stderr = &stderr
        if err := cmd.Run(); err != nil {
@@ -82,6 +99,8 @@ package main
 type asmTest struct {
        // architecture to compile to
        arch string
+       // os to compile to
+       os string
        // function to compile
        function string
        // regexps that must match the generated assembly
@@ -89,19 +108,68 @@ type asmTest struct {
 }
 
 var asmTests = [...]asmTest{
-       {"amd64", `
+       {"amd64", "linux", `
 func f(x int) int {
        return x * 64
 }
 `,
                []string{"\tSHLQ\t\\$6,"},
        },
-       {"amd64", `
+       {"amd64", "linux", `
 func f(x int) int {
        return x * 96
 }`,
                []string{"\tSHLQ\t\\$5,", "\tLEAQ\t\\(.*\\)\\(.*\\*2\\),"},
        },
+       // Load-combining tests.
+       {"amd64", "linux", `
+import "encoding/binary"
+func f(b []byte) uint64 {
+       return binary.LittleEndian.Uint64(b)
+}
+`,
+               []string{"\tMOVQ\t\\(.*\\),"},
+       },
+       {"amd64", "linux", `
+import "encoding/binary"
+func f(b []byte, i int) uint64 {
+       return binary.LittleEndian.Uint64(b[i:])
+}
+`,
+               []string{"\tMOVQ\t\\(.*\\)\\(.*\\*1\\),"},
+       },
+       {"amd64", "linux", `
+import "encoding/binary"
+func f(b []byte) uint32 {
+       return binary.LittleEndian.Uint32(b)
+}
+`,
+               []string{"\tMOVL\t\\(.*\\),"},
+       },
+       {"amd64", "linux", `
+import "encoding/binary"
+func f(b []byte, i int) uint32 {
+       return binary.LittleEndian.Uint32(b[i:])
+}
+`,
+               []string{"\tMOVL\t\\(.*\\)\\(.*\\*1\\),"},
+       },
+       {"386", "linux", `
+import "encoding/binary"
+func f(b []byte) uint32 {
+       return binary.LittleEndian.Uint32(b)
+}
+`,
+               []string{"\tMOVL\t\\(.*\\),"},
+       },
+       {"386", "linux", `
+import "encoding/binary"
+func f(b []byte, i int) uint32 {
+       return binary.LittleEndian.Uint32(b[i:])
+}
+`,
+               []string{"\tMOVL\t\\(.*\\)\\(.*\\*1\\),"},
+       },
 }
 
 // mergeEnvLists merges the two environment lists such that
index 6a0990da47899f19b8d6d714cc07fde6c9dac42d..214d34a0c1db1bbe3415062641c0afe891f78fda 100644 (file)
   && clobber(s0)
   -> @mergePoint(b,x0,x1) (MOVWload [i] {s} p mem)
 
-(ORL o0:(ORL o1:(ORL
-                       x0:(MOVBload [i]   {s} p mem)
-    s0:(SHLLconst [8]  x1:(MOVBload [i+1] {s} p mem)))
-    s1:(SHLLconst [16] x2:(MOVBload [i+2] {s} p mem)))
-    s2:(SHLLconst [24] x3:(MOVBload [i+3] {s} p mem)))
+(ORL o0:(ORL
+                       x0:(MOVWload [i]   {s} p mem)
+    s0:(SHLLconst [16] x1:(MOVBload [i+2] {s} p mem)))
+    s1:(SHLLconst [24] x2:(MOVBload [i+3] {s} p mem)))
   && x0.Uses == 1
   && x1.Uses == 1
   && x2.Uses == 1
-  && x3.Uses == 1
   && s0.Uses == 1
   && s1.Uses == 1
-  && s2.Uses == 1
   && o0.Uses == 1
-  && o1.Uses == 1
-  && mergePoint(b,x0,x1,x2,x3) != nil
+  && mergePoint(b,x0,x1,x2) != nil
   && clobber(x0)
   && clobber(x1)
   && clobber(x2)
-  && clobber(x3)
   && clobber(s0)
   && clobber(s1)
-  && clobber(s2)
   && clobber(o0)
-  && clobber(o1)
-  -> @mergePoint(b,x0,x1,x2,x3) (MOVLload [i] {s} p mem)
+  -> @mergePoint(b,x0,x1,x2) (MOVLload [i] {s} p mem)
 
 (ORL                  x0:(MOVBloadidx1 [i]   {s} p idx mem)
     s0:(SHLLconst [8] x1:(MOVBloadidx1 [i+1] {s} p idx mem)))
   && clobber(s0)
   -> @mergePoint(b,x0,x1) (MOVWloadidx1 <v.Type> [i] {s} p idx mem)
 
-(ORL o0:(ORL o1:(ORL
-                       x0:(MOVBloadidx1 [i]   {s} p idx mem)
-    s0:(SHLLconst [8]  x1:(MOVBloadidx1 [i+1] {s} p idx mem)))
-    s1:(SHLLconst [16] x2:(MOVBloadidx1 [i+2] {s} p idx mem)))
-    s2:(SHLLconst [24] x3:(MOVBloadidx1 [i+3] {s} p idx mem)))
+(ORL o0:(ORL
+                       x0:(MOVWloadidx1 [i]   {s} p idx mem)
+    s0:(SHLLconst [16] x1:(MOVBloadidx1 [i+2] {s} p idx mem)))
+    s1:(SHLLconst [24] x2:(MOVBloadidx1 [i+3] {s} p idx mem)))
   && x0.Uses == 1
   && x1.Uses == 1
   && x2.Uses == 1
-  && x3.Uses == 1
   && s0.Uses == 1
   && s1.Uses == 1
-  && s2.Uses == 1
   && o0.Uses == 1
-  && o1.Uses == 1
-  && mergePoint(b,x0,x1,x2,x3) != nil
+  && mergePoint(b,x0,x1,x2) != nil
   && clobber(x0)
   && clobber(x1)
   && clobber(x2)
-  && clobber(x3)
   && clobber(s0)
   && clobber(s1)
-  && clobber(s2)
   && clobber(o0)
-  && clobber(o1)
-  -> @mergePoint(b,x0,x1,x2,x3) (MOVLloadidx1 <v.Type> [i] {s} p idx mem)
+  -> @mergePoint(b,x0,x1,x2) (MOVLloadidx1 <v.Type> [i] {s} p idx mem)
 
 // Combine constant stores into larger (unaligned) stores.
 (MOVBstoreconst [c] {s} p x:(MOVBstoreconst [a] {s} p mem))
index bac3d70513cc6a7f60c93b509b14bd1b82b7b7f9..175c899ff6c472e695fe48882626b54ba1d7ce30 100644 (file)
   && clobber(s0)
   -> @mergePoint(b,x0,x1) (MOVWload [i] {s} p mem)
 
-(ORL o0:(ORL o1:(ORL
-                       x0:(MOVBload [i]   {s} p mem)
-    s0:(SHLLconst [8]  x1:(MOVBload [i+1] {s} p mem)))
-    s1:(SHLLconst [16] x2:(MOVBload [i+2] {s} p mem)))
-    s2:(SHLLconst [24] x3:(MOVBload [i+3] {s} p mem)))
+(ORL o0:(ORL
+                       x0:(MOVWload [i]   {s} p mem)
+    s0:(SHLLconst [16] x1:(MOVBload [i+2] {s} p mem)))
+    s1:(SHLLconst [24] x2:(MOVBload [i+3] {s} p mem)))
   && x0.Uses == 1
   && x1.Uses == 1
   && x2.Uses == 1
-  && x3.Uses == 1
   && s0.Uses == 1
   && s1.Uses == 1
-  && s2.Uses == 1
   && o0.Uses == 1
-  && o1.Uses == 1
-  && mergePoint(b,x0,x1,x2,x3) != nil
+  && mergePoint(b,x0,x1,x2) != nil
   && clobber(x0)
   && clobber(x1)
   && clobber(x2)
-  && clobber(x3)
   && clobber(s0)
   && clobber(s1)
-  && clobber(s2)
   && clobber(o0)
-  && clobber(o1)
-  -> @mergePoint(b,x0,x1,x2,x3) (MOVLload [i] {s} p mem)
+  -> @mergePoint(b,x0,x1,x2) (MOVLload [i] {s} p mem)
 
 (ORQ o0:(ORQ o1:(ORQ o2:(ORQ o3:(ORQ o4:(ORQ o5:(ORQ
                        x0:(MOVBload [i]   {s} p mem)
   && clobber(s0)
   -> @mergePoint(b,x0,x1) (MOVWloadidx1 <v.Type> [i] {s} p idx mem)
 
-(ORL o0:(ORL o1:(ORL
-                       x0:(MOVBloadidx1 [i]   {s} p idx mem)
-    s0:(SHLLconst [8]  x1:(MOVBloadidx1 [i+1] {s} p idx mem)))
-    s1:(SHLLconst [16] x2:(MOVBloadidx1 [i+2] {s} p idx mem)))
-    s2:(SHLLconst [24] x3:(MOVBloadidx1 [i+3] {s} p idx mem)))
+(ORL o0:(ORL
+                       x0:(MOVWloadidx1 [i]   {s} p idx mem)
+    s0:(SHLLconst [16] x1:(MOVBloadidx1 [i+2] {s} p idx mem)))
+    s1:(SHLLconst [24] x2:(MOVBloadidx1 [i+3] {s} p idx mem)))
   && x0.Uses == 1
   && x1.Uses == 1
   && x2.Uses == 1
-  && x3.Uses == 1
   && s0.Uses == 1
   && s1.Uses == 1
-  && s2.Uses == 1
   && o0.Uses == 1
-  && o1.Uses == 1
-  && mergePoint(b,x0,x1,x2,x3) != nil
+  && mergePoint(b,x0,x1,x2) != nil
   && clobber(x0)
   && clobber(x1)
   && clobber(x2)
-  && clobber(x3)
   && clobber(s0)
   && clobber(s1)
-  && clobber(s2)
   && clobber(o0)
-  && clobber(o1)
-  -> @mergePoint(b,x0,x1,x2,x3) (MOVLloadidx1 <v.Type> [i] {s} p idx mem)
+  -> @mergePoint(b,x0,x1,x2) (MOVLloadidx1 <v.Type> [i] {s} p idx mem)
 
 (ORQ o0:(ORQ o1:(ORQ o2:(ORQ o3:(ORQ o4:(ORQ o5:(ORQ
                        x0:(MOVBloadidx1 [i]   {s} p idx mem)
index 04932be887fc7534c03d873fc4cdeab9e54b72e0..fa7b7c17bd93f59d4a4be1400d6ffd216c47df31 100644 (file)
@@ -7177,38 +7177,34 @@ func rewriteValue386_Op386ORL(v *Value, config *Config) bool {
                v0.AddArg(mem)
                return true
        }
-       // match: (ORL o0:(ORL o1:(ORL                        x0:(MOVBload [i]   {s} p mem)     s0:(SHLLconst [8]  x1:(MOVBload [i+1] {s} p mem)))     s1:(SHLLconst [16] x2:(MOVBload [i+2] {s} p mem)))     s2:(SHLLconst [24] x3:(MOVBload [i+3] {s} p mem)))
-       // cond: x0.Uses == 1   && x1.Uses == 1   && x2.Uses == 1   && x3.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && s2.Uses == 1   && o0.Uses == 1   && o1.Uses == 1   && mergePoint(b,x0,x1,x2,x3) != nil   && clobber(x0)   && clobber(x1)   && clobber(x2)   && clobber(x3)   && clobber(s0)   && clobber(s1)   && clobber(s2)   && clobber(o0)   && clobber(o1)
-       // result: @mergePoint(b,x0,x1,x2,x3) (MOVLload [i] {s} p mem)
+       // match: (ORL o0:(ORL                        x0:(MOVWload [i]   {s} p mem)     s0:(SHLLconst [16] x1:(MOVBload [i+2] {s} p mem)))     s1:(SHLLconst [24] x2:(MOVBload [i+3] {s} p mem)))
+       // cond: x0.Uses == 1   && x1.Uses == 1   && x2.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && o0.Uses == 1   && mergePoint(b,x0,x1,x2) != nil   && clobber(x0)   && clobber(x1)   && clobber(x2)   && clobber(s0)   && clobber(s1)   && clobber(o0)
+       // result: @mergePoint(b,x0,x1,x2) (MOVLload [i] {s} p mem)
        for {
                o0 := v.Args[0]
                if o0.Op != Op386ORL {
                        break
                }
-               o1 := o0.Args[0]
-               if o1.Op != Op386ORL {
-                       break
-               }
-               x0 := o1.Args[0]
-               if x0.Op != Op386MOVBload {
+               x0 := o0.Args[0]
+               if x0.Op != Op386MOVWload {
                        break
                }
                i := x0.AuxInt
                s := x0.Aux
                p := x0.Args[0]
                mem := x0.Args[1]
-               s0 := o1.Args[1]
+               s0 := o0.Args[1]
                if s0.Op != Op386SHLLconst {
                        break
                }
-               if s0.AuxInt != 8 {
+               if s0.AuxInt != 16 {
                        break
                }
                x1 := s0.Args[0]
                if x1.Op != Op386MOVBload {
                        break
                }
-               if x1.AuxInt != i+1 {
+               if x1.AuxInt != i+2 {
                        break
                }
                if x1.Aux != s {
@@ -7220,18 +7216,18 @@ func rewriteValue386_Op386ORL(v *Value, config *Config) bool {
                if mem != x1.Args[1] {
                        break
                }
-               s1 := o0.Args[1]
+               s1 := v.Args[1]
                if s1.Op != Op386SHLLconst {
                        break
                }
-               if s1.AuxInt != 16 {
+               if s1.AuxInt != 24 {
                        break
                }
                x2 := s1.Args[0]
                if x2.Op != Op386MOVBload {
                        break
                }
-               if x2.AuxInt != i+2 {
+               if x2.AuxInt != i+3 {
                        break
                }
                if x2.Aux != s {
@@ -7243,33 +7239,10 @@ func rewriteValue386_Op386ORL(v *Value, config *Config) bool {
                if mem != x2.Args[1] {
                        break
                }
-               s2 := v.Args[1]
-               if s2.Op != Op386SHLLconst {
-                       break
-               }
-               if s2.AuxInt != 24 {
-                       break
-               }
-               x3 := s2.Args[0]
-               if x3.Op != Op386MOVBload {
-                       break
-               }
-               if x3.AuxInt != i+3 {
-                       break
-               }
-               if x3.Aux != s {
-                       break
-               }
-               if p != x3.Args[0] {
+               if !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && o0.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(s0) && clobber(s1) && clobber(o0)) {
                        break
                }
-               if mem != x3.Args[1] {
-                       break
-               }
-               if !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && mergePoint(b, x0, x1, x2, x3) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(o0) && clobber(o1)) {
-                       break
-               }
-               b = mergePoint(b, x0, x1, x2, x3)
+               b = mergePoint(b, x0, x1, x2)
                v0 := b.NewValue0(v.Line, Op386MOVLload, config.fe.TypeUInt32())
                v.reset(OpCopy)
                v.AddArg(v0)
@@ -7332,20 +7305,16 @@ func rewriteValue386_Op386ORL(v *Value, config *Config) bool {
                v0.AddArg(mem)
                return true
        }
-       // match: (ORL o0:(ORL o1:(ORL                        x0:(MOVBloadidx1 [i]   {s} p idx mem)     s0:(SHLLconst [8]  x1:(MOVBloadidx1 [i+1] {s} p idx mem)))     s1:(SHLLconst [16] x2:(MOVBloadidx1 [i+2] {s} p idx mem)))     s2:(SHLLconst [24] x3:(MOVBloadidx1 [i+3] {s} p idx mem)))
-       // cond: x0.Uses == 1   && x1.Uses == 1   && x2.Uses == 1   && x3.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && s2.Uses == 1   && o0.Uses == 1   && o1.Uses == 1   && mergePoint(b,x0,x1,x2,x3) != nil   && clobber(x0)   && clobber(x1)   && clobber(x2)   && clobber(x3)   && clobber(s0)   && clobber(s1)   && clobber(s2)   && clobber(o0)   && clobber(o1)
-       // result: @mergePoint(b,x0,x1,x2,x3) (MOVLloadidx1 <v.Type> [i] {s} p idx mem)
+       // match: (ORL o0:(ORL                        x0:(MOVWloadidx1 [i]   {s} p idx mem)     s0:(SHLLconst [16] x1:(MOVBloadidx1 [i+2] {s} p idx mem)))     s1:(SHLLconst [24] x2:(MOVBloadidx1 [i+3] {s} p idx mem)))
+       // cond: x0.Uses == 1   && x1.Uses == 1   && x2.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && o0.Uses == 1   && mergePoint(b,x0,x1,x2) != nil   && clobber(x0)   && clobber(x1)   && clobber(x2)   && clobber(s0)   && clobber(s1)   && clobber(o0)
+       // result: @mergePoint(b,x0,x1,x2) (MOVLloadidx1 <v.Type> [i] {s} p idx mem)
        for {
                o0 := v.Args[0]
                if o0.Op != Op386ORL {
                        break
                }
-               o1 := o0.Args[0]
-               if o1.Op != Op386ORL {
-                       break
-               }
-               x0 := o1.Args[0]
-               if x0.Op != Op386MOVBloadidx1 {
+               x0 := o0.Args[0]
+               if x0.Op != Op386MOVWloadidx1 {
                        break
                }
                i := x0.AuxInt
@@ -7353,18 +7322,18 @@ func rewriteValue386_Op386ORL(v *Value, config *Config) bool {
                p := x0.Args[0]
                idx := x0.Args[1]
                mem := x0.Args[2]
-               s0 := o1.Args[1]
+               s0 := o0.Args[1]
                if s0.Op != Op386SHLLconst {
                        break
                }
-               if s0.AuxInt != 8 {
+               if s0.AuxInt != 16 {
                        break
                }
                x1 := s0.Args[0]
                if x1.Op != Op386MOVBloadidx1 {
                        break
                }
-               if x1.AuxInt != i+1 {
+               if x1.AuxInt != i+2 {
                        break
                }
                if x1.Aux != s {
@@ -7379,18 +7348,18 @@ func rewriteValue386_Op386ORL(v *Value, config *Config) bool {
                if mem != x1.Args[2] {
                        break
                }
-               s1 := o0.Args[1]
+               s1 := v.Args[1]
                if s1.Op != Op386SHLLconst {
                        break
                }
-               if s1.AuxInt != 16 {
+               if s1.AuxInt != 24 {
                        break
                }
                x2 := s1.Args[0]
                if x2.Op != Op386MOVBloadidx1 {
                        break
                }
-               if x2.AuxInt != i+2 {
+               if x2.AuxInt != i+3 {
                        break
                }
                if x2.Aux != s {
@@ -7405,36 +7374,10 @@ func rewriteValue386_Op386ORL(v *Value, config *Config) bool {
                if mem != x2.Args[2] {
                        break
                }
-               s2 := v.Args[1]
-               if s2.Op != Op386SHLLconst {
-                       break
-               }
-               if s2.AuxInt != 24 {
-                       break
-               }
-               x3 := s2.Args[0]
-               if x3.Op != Op386MOVBloadidx1 {
-                       break
-               }
-               if x3.AuxInt != i+3 {
-                       break
-               }
-               if x3.Aux != s {
-                       break
-               }
-               if p != x3.Args[0] {
-                       break
-               }
-               if idx != x3.Args[1] {
-                       break
-               }
-               if mem != x3.Args[2] {
-                       break
-               }
-               if !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && mergePoint(b, x0, x1, x2, x3) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(o0) && clobber(o1)) {
+               if !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && o0.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(s0) && clobber(s1) && clobber(o0)) {
                        break
                }
-               b = mergePoint(b, x0, x1, x2, x3)
+               b = mergePoint(b, x0, x1, x2)
                v0 := b.NewValue0(v.Line, Op386MOVLloadidx1, v.Type)
                v.reset(OpCopy)
                v.AddArg(v0)
index fcc2f37ff3f37ece6c3f4446e97552bd4d85cc7f..a55b7ff6fb4a825aadd16cd726c17818cde114af 100644 (file)
@@ -10340,38 +10340,34 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value, config *Config) bool {
                v0.AddArg(mem)
                return true
        }
-       // match: (ORL o0:(ORL o1:(ORL                        x0:(MOVBload [i]   {s} p mem)     s0:(SHLLconst [8]  x1:(MOVBload [i+1] {s} p mem)))     s1:(SHLLconst [16] x2:(MOVBload [i+2] {s} p mem)))     s2:(SHLLconst [24] x3:(MOVBload [i+3] {s} p mem)))
-       // cond: x0.Uses == 1   && x1.Uses == 1   && x2.Uses == 1   && x3.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && s2.Uses == 1   && o0.Uses == 1   && o1.Uses == 1   && mergePoint(b,x0,x1,x2,x3) != nil   && clobber(x0)   && clobber(x1)   && clobber(x2)   && clobber(x3)   && clobber(s0)   && clobber(s1)   && clobber(s2)   && clobber(o0)   && clobber(o1)
-       // result: @mergePoint(b,x0,x1,x2,x3) (MOVLload [i] {s} p mem)
+       // match: (ORL o0:(ORL                        x0:(MOVWload [i]   {s} p mem)     s0:(SHLLconst [16] x1:(MOVBload [i+2] {s} p mem)))     s1:(SHLLconst [24] x2:(MOVBload [i+3] {s} p mem)))
+       // cond: x0.Uses == 1   && x1.Uses == 1   && x2.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && o0.Uses == 1   && mergePoint(b,x0,x1,x2) != nil   && clobber(x0)   && clobber(x1)   && clobber(x2)   && clobber(s0)   && clobber(s1)   && clobber(o0)
+       // result: @mergePoint(b,x0,x1,x2) (MOVLload [i] {s} p mem)
        for {
                o0 := v.Args[0]
                if o0.Op != OpAMD64ORL {
                        break
                }
-               o1 := o0.Args[0]
-               if o1.Op != OpAMD64ORL {
-                       break
-               }
-               x0 := o1.Args[0]
-               if x0.Op != OpAMD64MOVBload {
+               x0 := o0.Args[0]
+               if x0.Op != OpAMD64MOVWload {
                        break
                }
                i := x0.AuxInt
                s := x0.Aux
                p := x0.Args[0]
                mem := x0.Args[1]
-               s0 := o1.Args[1]
+               s0 := o0.Args[1]
                if s0.Op != OpAMD64SHLLconst {
                        break
                }
-               if s0.AuxInt != 8 {
+               if s0.AuxInt != 16 {
                        break
                }
                x1 := s0.Args[0]
                if x1.Op != OpAMD64MOVBload {
                        break
                }
-               if x1.AuxInt != i+1 {
+               if x1.AuxInt != i+2 {
                        break
                }
                if x1.Aux != s {
@@ -10383,18 +10379,18 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value, config *Config) bool {
                if mem != x1.Args[1] {
                        break
                }
-               s1 := o0.Args[1]
+               s1 := v.Args[1]
                if s1.Op != OpAMD64SHLLconst {
                        break
                }
-               if s1.AuxInt != 16 {
+               if s1.AuxInt != 24 {
                        break
                }
                x2 := s1.Args[0]
                if x2.Op != OpAMD64MOVBload {
                        break
                }
-               if x2.AuxInt != i+2 {
+               if x2.AuxInt != i+3 {
                        break
                }
                if x2.Aux != s {
@@ -10406,33 +10402,10 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value, config *Config) bool {
                if mem != x2.Args[1] {
                        break
                }
-               s2 := v.Args[1]
-               if s2.Op != OpAMD64SHLLconst {
+               if !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && o0.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(s0) && clobber(s1) && clobber(o0)) {
                        break
                }
-               if s2.AuxInt != 24 {
-                       break
-               }
-               x3 := s2.Args[0]
-               if x3.Op != OpAMD64MOVBload {
-                       break
-               }
-               if x3.AuxInt != i+3 {
-                       break
-               }
-               if x3.Aux != s {
-                       break
-               }
-               if p != x3.Args[0] {
-                       break
-               }
-               if mem != x3.Args[1] {
-                       break
-               }
-               if !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && mergePoint(b, x0, x1, x2, x3) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(o0) && clobber(o1)) {
-                       break
-               }
-               b = mergePoint(b, x0, x1, x2, x3)
+               b = mergePoint(b, x0, x1, x2)
                v0 := b.NewValue0(v.Line, OpAMD64MOVLload, config.fe.TypeUInt32())
                v.reset(OpCopy)
                v.AddArg(v0)
@@ -10495,20 +10468,16 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value, config *Config) bool {
                v0.AddArg(mem)
                return true
        }
-       // match: (ORL o0:(ORL o1:(ORL                        x0:(MOVBloadidx1 [i]   {s} p idx mem)     s0:(SHLLconst [8]  x1:(MOVBloadidx1 [i+1] {s} p idx mem)))     s1:(SHLLconst [16] x2:(MOVBloadidx1 [i+2] {s} p idx mem)))     s2:(SHLLconst [24] x3:(MOVBloadidx1 [i+3] {s} p idx mem)))
-       // cond: x0.Uses == 1   && x1.Uses == 1   && x2.Uses == 1   && x3.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && s2.Uses == 1   && o0.Uses == 1   && o1.Uses == 1   && mergePoint(b,x0,x1,x2,x3) != nil   && clobber(x0)   && clobber(x1)   && clobber(x2)   && clobber(x3)   && clobber(s0)   && clobber(s1)   && clobber(s2)   && clobber(o0)   && clobber(o1)
-       // result: @mergePoint(b,x0,x1,x2,x3) (MOVLloadidx1 <v.Type> [i] {s} p idx mem)
+       // match: (ORL o0:(ORL                        x0:(MOVWloadidx1 [i]   {s} p idx mem)     s0:(SHLLconst [16] x1:(MOVBloadidx1 [i+2] {s} p idx mem)))     s1:(SHLLconst [24] x2:(MOVBloadidx1 [i+3] {s} p idx mem)))
+       // cond: x0.Uses == 1   && x1.Uses == 1   && x2.Uses == 1   && s0.Uses == 1   && s1.Uses == 1   && o0.Uses == 1   && mergePoint(b,x0,x1,x2) != nil   && clobber(x0)   && clobber(x1)   && clobber(x2)   && clobber(s0)   && clobber(s1)   && clobber(o0)
+       // result: @mergePoint(b,x0,x1,x2) (MOVLloadidx1 <v.Type> [i] {s} p idx mem)
        for {
                o0 := v.Args[0]
                if o0.Op != OpAMD64ORL {
                        break
                }
-               o1 := o0.Args[0]
-               if o1.Op != OpAMD64ORL {
-                       break
-               }
-               x0 := o1.Args[0]
-               if x0.Op != OpAMD64MOVBloadidx1 {
+               x0 := o0.Args[0]
+               if x0.Op != OpAMD64MOVWloadidx1 {
                        break
                }
                i := x0.AuxInt
@@ -10516,18 +10485,18 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value, config *Config) bool {
                p := x0.Args[0]
                idx := x0.Args[1]
                mem := x0.Args[2]
-               s0 := o1.Args[1]
+               s0 := o0.Args[1]
                if s0.Op != OpAMD64SHLLconst {
                        break
                }
-               if s0.AuxInt != 8 {
+               if s0.AuxInt != 16 {
                        break
                }
                x1 := s0.Args[0]
                if x1.Op != OpAMD64MOVBloadidx1 {
                        break
                }
-               if x1.AuxInt != i+1 {
+               if x1.AuxInt != i+2 {
                        break
                }
                if x1.Aux != s {
@@ -10542,18 +10511,18 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value, config *Config) bool {
                if mem != x1.Args[2] {
                        break
                }
-               s1 := o0.Args[1]
+               s1 := v.Args[1]
                if s1.Op != OpAMD64SHLLconst {
                        break
                }
-               if s1.AuxInt != 16 {
+               if s1.AuxInt != 24 {
                        break
                }
                x2 := s1.Args[0]
                if x2.Op != OpAMD64MOVBloadidx1 {
                        break
                }
-               if x2.AuxInt != i+2 {
+               if x2.AuxInt != i+3 {
                        break
                }
                if x2.Aux != s {
@@ -10568,36 +10537,10 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value, config *Config) bool {
                if mem != x2.Args[2] {
                        break
                }
-               s2 := v.Args[1]
-               if s2.Op != OpAMD64SHLLconst {
-                       break
-               }
-               if s2.AuxInt != 24 {
-                       break
-               }
-               x3 := s2.Args[0]
-               if x3.Op != OpAMD64MOVBloadidx1 {
-                       break
-               }
-               if x3.AuxInt != i+3 {
-                       break
-               }
-               if x3.Aux != s {
-                       break
-               }
-               if p != x3.Args[0] {
-                       break
-               }
-               if idx != x3.Args[1] {
-                       break
-               }
-               if mem != x3.Args[2] {
-                       break
-               }
-               if !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && mergePoint(b, x0, x1, x2, x3) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(s0) && clobber(s1) && clobber(s2) && clobber(o0) && clobber(o1)) {
+               if !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && o0.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(s0) && clobber(s1) && clobber(o0)) {
                        break
                }
-               b = mergePoint(b, x0, x1, x2, x3)
+               b = mergePoint(b, x0, x1, x2)
                v0 := b.NewValue0(v.Line, OpAMD64MOVLloadidx1, v.Type)
                v.reset(OpCopy)
                v.AddArg(v0)