]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/5g: make sure we normalize after unary ops on small types
authorKeith Randall <khr@golang.org>
Thu, 15 Jan 2015 22:39:58 +0000 (14:39 -0800)
committerKeith Randall <khr@golang.org>
Thu, 15 Jan 2015 23:50:01 +0000 (23:50 +0000)
We were failing ^uint16(0xffff) == 0, as we computed 0xffff0000 instead.

I could only trigger a failure for the above case, the other two tests
^uint16(0xfffe) == 1 and -uint16(0xffff) == 1 didn't seem to fail
previously.  Somehow they get MOVHUs inserted for other reasons (used
by CMP instead of TST?).  I fixed OMINUS anyway, better safe than
sorry.

Fixes #9604

Change-Id: I4c2d5bdc667742873ac029fdbe3db0cf12893c27
Reviewed-on: https://go-review.googlesource.com/2940
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Minux Ma <minux@golang.org>
src/cmd/5g/cgen.c
test/fixedbugs/issue9604.go [new file with mode: 0644]

index c535cfbefbe412439595c3cd13771a516f5011dd..87c64f6e8126147d2134e7eb449d5897e10c25ea 100644 (file)
@@ -236,18 +236,14 @@ cgen(Node *n, Node *res)
                cgen(nl, &n1);
                nodconst(&n2, nl->type, -1);
                gins(a, &n2, &n1);
-               gmove(&n1, res);
-               regfree(&n1);
-               goto ret;
+               goto norm;
 
        case OMINUS:
                regalloc(&n1, nl->type, N);
                cgen(nl, &n1);
                nodconst(&n2, nl->type, 0);
                gins(optoas(OMINUS, nl->type), &n2, &n1);
-               gmove(&n1, res);
-               regfree(&n1);
-               goto ret;
+               goto norm;
 
        // symmetric binary
        case OAND:
@@ -483,12 +479,15 @@ abop:     // asymmetric binary
                cgen(nl, &n1);
        }
        gins(a, &n2, &n1);
+norm:
        // Normalize result for types smaller than word.
        if(n->type->width < widthptr) {
                switch(n->op) {
                case OADD:
                case OSUB:
                case OMUL:
+               case OCOM:
+               case OMINUS:
                        gins(optoas(OAS, n->type), &n1, &n1);
                        break;
                }
diff --git a/test/fixedbugs/issue9604.go b/test/fixedbugs/issue9604.go
new file mode 100644 (file)
index 0000000..cd9e9e4
--- /dev/null
@@ -0,0 +1,29 @@
+// run
+
+// Copyright 2015 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 x uint16 = 0xffff
+var y uint16 = 0xfffe
+var a uint16 = 0x7000
+var b uint16 = 0x9000
+
+func main() {
+       // Make sure we truncate to smaller-width types after evaluating expressions.
+       // This is a problem for arm where there is no 16-bit comparison op.
+       if ^x != 0 {
+               panic("^uint16(0xffff) != 0")
+       }
+       if ^y != 1 {
+               panic("^uint16(0xfffe) != 1")
+       }
+       if -x != 1 {
+               panic("-uint16(0xffff) != 1")
+       }
+       if a+b != 0 {
+               panic("0x7000+0x9000 != 0")
+       }
+}