]> Cypherpunks.ru repositories - gostls13.git/commitdiff
gc: fix order of operations for f() < g().
authorRuss Cox <rsc@golang.org>
Tue, 26 Apr 2011 04:57:03 +0000 (00:57 -0400)
committerRuss Cox <rsc@golang.org>
Tue, 26 Apr 2011 04:57:03 +0000 (00:57 -0400)
Also, 6g was passing uninitialized
Node &n2 to regalloc, causing non-deterministic
register collisions (but only when both left and
right hand side of comparison had function calls).

Fixes #1728.

R=ken2
CC=golang-dev
https://golang.org/cl/4425070

src/cmd/5g/cgen.c
src/cmd/6g/cgen.c
src/cmd/8g/cgen.c
test/func7.go [new file with mode: 0644]

index e0fc7682151b8c3292e6fa818db31e9ff1f09129..4e5f7ebcdcd75f3efd09e8a1391825d582c1fc7e 100644 (file)
@@ -962,7 +962,7 @@ bgen(Node *n, int true, Prog *to)
                }
 
                // make simplest on right
-               if(nl->op == OLITERAL || nl->ullman < nr->ullman) {
+               if(nl->op == OLITERAL || (nl->ullman < UINF && nl->ullman < nr->ullman)) {
                        a = brrev(a);
                        r = nl;
                        nl = nr;
@@ -1073,18 +1073,18 @@ bgen(Node *n, int true, Prog *to)
                a = optoas(a, nr->type);
 
                if(nr->ullman >= UINF) {
-                       regalloc(&n1, nr->type, N);
-                       cgen(nr, &n1);
+                       regalloc(&n1, nl->type, N);
+                       cgen(nl, &n1);
 
-                       tempname(&tmp, nr->type);
+                       tempname(&tmp, nl->type);
                        gmove(&n1, &tmp);
                        regfree(&n1);
 
-                       regalloc(&n1, nl->type, N);
-                       cgen(nl, &n1);
-
                        regalloc(&n2, nr->type, N);
-                       cgen(&tmp, &n2);
+                       cgen(nr, &n2);
+
+                       regalloc(&n1, nl->type, N);
+                       cgen(&tmp, &n1);
 
                        gcmp(optoas(OCMP, nr->type), &n1, &n2);
                        patch(gbranch(a, nr->type), to);
index 048174e0869efc10c6038dd4576fd24f50f7d38c..75dc4fe13427edb5039823cf67a72ea770023c08 100644 (file)
@@ -829,7 +829,7 @@ bgen(Node *n, int true, Prog *to)
                }
 
                // make simplest on right
-               if(nl->op == OLITERAL || nl->ullman < nr->ullman) {
+               if(nl->op == OLITERAL || (nl->ullman < nr->ullman && nl->ullman < UINF)) {
                        a = brrev(a);
                        r = nl;
                        nl = nr;
@@ -879,18 +879,18 @@ bgen(Node *n, int true, Prog *to)
                }
 
                if(nr->ullman >= UINF) {
-                       regalloc(&n1, nr->type, N);
-                       cgen(nr, &n1);
+                       regalloc(&n1, nl->type, N);
+                       cgen(nl, &n1);
 
-                       tempname(&tmp, nr->type);
+                       tempname(&tmp, nl->type);
                        gmove(&n1, &tmp);
                        regfree(&n1);
 
-                       regalloc(&n1, nl->type, N);
-                       cgen(nl, &n1);
+                       regalloc(&n2, nr->type, N);
+                       cgen(nr, &n2);
 
-                       regalloc(&n2, nr->type, &n2);
-                       cgen(&tmp, &n2);
+                       regalloc(&n1, nl->type, N);
+                       cgen(&tmp, &n1);
 
                        goto cmp;
                }
index 036188fec4a7085253ae1e34771dcfaf75ef204f..596824a6ccb04b88fbc9e0f7569a367bf97b648b 100644 (file)
@@ -900,7 +900,7 @@ bgen(Node *n, int true, Prog *to)
                }
 
                // make simplest on right
-               if(nl->op == OLITERAL || nl->ullman < nr->ullman) {
+               if(nl->op == OLITERAL || (nl->ullman < nr->ullman && nl->ullman < UINF)) {
                        a = brrev(a);
                        r = nl;
                        nl = nr;
@@ -1025,8 +1025,8 @@ bgen(Node *n, int true, Prog *to)
                if(nr->ullman >= UINF) {
                        tempname(&n1, nl->type);
                        tempname(&tmp, nr->type);
-                       cgen(nr, &tmp);
                        cgen(nl, &n1);
+                       cgen(nr, &tmp);
                        regalloc(&n2, nr->type, N);
                        cgen(&tmp, &n2);
                        goto cmp;
diff --git a/test/func7.go b/test/func7.go
new file mode 100644 (file)
index 0000000..e38b008
--- /dev/null
@@ -0,0 +1,29 @@
+// $G $D/$F.go && $L $F.$A && ./$A.out
+
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+var calledf = false
+
+func f() int {
+       calledf = true
+       return 1
+}
+
+func g() int {
+       if !calledf {
+               println("BUG: func7 - called g before f")
+       }
+       return 0
+}
+
+func main() {
+       // 6g, 8g, 5g all used to evaluate g() before f().
+       if f() < g() {
+               panic("wrong answer")
+       }
+}
+