]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.11] cmd/compile: fix MIPS SGTconst-with-shift rules
authorCherry Zhang <cherryyz@google.com>
Wed, 26 Dec 2018 00:36:25 +0000 (19:36 -0500)
committerKatie Hockman <katie@golang.org>
Fri, 4 Jan 2019 20:43:18 +0000 (20:43 +0000)
(SGTconst [c] (SRLconst _ [d])) && 0 <= int32(c) && uint32(d) <= 31 && 1<<(32-uint32(d)) <= int32(c) -> (MOVWconst [1])

This rule is problematic. 1<<(32-uint32(d)) <= int32(c) meant to
say that it is true if c is greater than the largest possible
value of the right shift. But when d==1, 1<<(32-1) is negative
and results in the wrong comparison.

Rewrite the rules in a more direct way.

Updates #29402.
Fixes #29442.

Change-Id: I5940fc9538d9bc3a4bcae8aa34672867540dc60e
Reviewed-on: https://go-review.googlesource.com/c/155798
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
(cherry picked from commit 6a64efc25004175e198e75191e215a7b1a08a2fa)
Reviewed-on: https://go-review.googlesource.com/c/155799
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/internal/ssa/gen/MIPS.rules
src/cmd/compile/internal/ssa/gen/MIPS64.rules
src/cmd/compile/internal/ssa/rewriteMIPS.go
src/cmd/compile/internal/ssa/rewriteMIPS64.go
test/fixedbugs/issue29402.go [new file with mode: 0644]

index 098e19c8a82642d2fab9dae369949c96d49d4553..db9c5bc63878b1e786854fd3161496cceb951910 100644 (file)
 (SGTUconst [c] (MOVHUreg _)) && 0xffff < uint32(c) -> (MOVWconst [1])
 (SGTconst [c] (ANDconst [m] _)) && 0 <= int32(m) && int32(m) < int32(c) -> (MOVWconst [1])
 (SGTUconst [c] (ANDconst [m] _)) && uint32(m) < uint32(c) -> (MOVWconst [1])
-(SGTconst [c] (SRLconst _ [d])) && 0 <= int32(c) && uint32(d) <= 31 && 1<<(32-uint32(d)) <= int32(c) -> (MOVWconst [1])
-(SGTUconst [c] (SRLconst _ [d])) && uint32(d) <= 31 && 1<<(32-uint32(d)) <= uint32(c) -> (MOVWconst [1])
+(SGTconst [c] (SRLconst _ [d])) && 0 <= int32(c) && uint32(d) <= 31 && 0xffffffff>>uint32(d) < uint32(c) -> (MOVWconst [1])
+(SGTUconst [c] (SRLconst _ [d])) && uint32(d) <= 31 && 0xffffffff>>uint32(d) < uint32(c) -> (MOVWconst [1])
 
 // absorb constants into branches
 (EQ  (MOVWconst [0]) yes no) -> (First nil yes no)
index 70f4f0d616f75ae701bb18a9afe41e64bfc5bdf5..9c16c3543847feed48a33aa8e008137595bc5234 100644 (file)
 (SGTconst [c] (MOVWUreg _)) && c < 0 -> (MOVVconst [0])
 (SGTconst [c] (ANDconst [m] _)) && 0 <= m && m < c -> (MOVVconst [1])
 (SGTUconst [c] (ANDconst [m] _)) && uint64(m) < uint64(c) -> (MOVVconst [1])
-(SGTconst [c] (SRLVconst _ [d])) && 0 <= c && 0 < d && d <= 63 && 1<<uint64(64-d) <= c -> (MOVVconst [1])
-(SGTUconst [c] (SRLVconst _ [d])) && 0 < d && d <= 63 && 1<<uint64(64-d) <= uint64(c) -> (MOVVconst [1])
+(SGTconst [c] (SRLVconst _ [d])) && 0 <= c && 0 < d && d <= 63 && 0xffffffffffffffff>>uint64(d) < uint64(c) -> (MOVVconst [1])
+(SGTUconst [c] (SRLVconst _ [d])) && 0 < d && d <= 63 && 0xffffffffffffffff>>uint64(d) < uint64(c) -> (MOVVconst [1])
 
 // absorb constants into branches
 (EQ  (MOVVconst [0]) yes no) -> (First nil yes no)
index 231949644ee8dcbe565983705216e41a81495c33..85ec732623c89e1db687224ce6ac452a37cb3a47 100644 (file)
@@ -5623,7 +5623,7 @@ func rewriteValueMIPS_OpMIPSSGTUconst_0(v *Value) bool {
                return true
        }
        // match: (SGTUconst [c] (SRLconst _ [d]))
-       // cond: uint32(d) <= 31 && 1<<(32-uint32(d)) <= uint32(c)
+       // cond: uint32(d) <= 31 && 0xffffffff>>uint32(d) < uint32(c)
        // result: (MOVWconst [1])
        for {
                c := v.AuxInt
@@ -5632,7 +5632,7 @@ func rewriteValueMIPS_OpMIPSSGTUconst_0(v *Value) bool {
                        break
                }
                d := v_0.AuxInt
-               if !(uint32(d) <= 31 && 1<<(32-uint32(d)) <= uint32(c)) {
+               if !(uint32(d) <= 31 && 0xffffffff>>uint32(d) < uint32(c)) {
                        break
                }
                v.reset(OpMIPSMOVWconst)
@@ -5860,7 +5860,7 @@ func rewriteValueMIPS_OpMIPSSGTconst_10(v *Value) bool {
                return true
        }
        // match: (SGTconst [c] (SRLconst _ [d]))
-       // cond: 0 <= int32(c) && uint32(d) <= 31 && 1<<(32-uint32(d)) <= int32(c)
+       // cond: 0 <= int32(c) && uint32(d) <= 31 && 0xffffffff>>uint32(d) < uint32(c)
        // result: (MOVWconst [1])
        for {
                c := v.AuxInt
@@ -5869,7 +5869,7 @@ func rewriteValueMIPS_OpMIPSSGTconst_10(v *Value) bool {
                        break
                }
                d := v_0.AuxInt
-               if !(0 <= int32(c) && uint32(d) <= 31 && 1<<(32-uint32(d)) <= int32(c)) {
+               if !(0 <= int32(c) && uint32(d) <= 31 && 0xffffffff>>uint32(d) < uint32(c)) {
                        break
                }
                v.reset(OpMIPSMOVWconst)
index 9cd0050e26d1a2c5e4c974130f02a7c731a9f07f..d123652c7bb8817107e79a578fa079e5f33b1f88 100644 (file)
@@ -6003,7 +6003,7 @@ func rewriteValueMIPS64_OpMIPS64SGTUconst_0(v *Value) bool {
                return true
        }
        // match: (SGTUconst [c] (SRLVconst _ [d]))
-       // cond: 0 < d && d <= 63 && 1<<uint64(64-d) <= uint64(c)
+       // cond: 0 < d && d <= 63 && 0xffffffffffffffff>>uint64(d) < uint64(c)
        // result: (MOVVconst [1])
        for {
                c := v.AuxInt
@@ -6012,7 +6012,7 @@ func rewriteValueMIPS64_OpMIPS64SGTUconst_0(v *Value) bool {
                        break
                }
                d := v_0.AuxInt
-               if !(0 < d && d <= 63 && 1<<uint64(64-d) <= uint64(c)) {
+               if !(0 < d && d <= 63 && 0xffffffffffffffff>>uint64(d) < uint64(c)) {
                        break
                }
                v.reset(OpMIPS64MOVVconst)
@@ -6221,7 +6221,7 @@ func rewriteValueMIPS64_OpMIPS64SGTconst_10(v *Value) bool {
                return true
        }
        // match: (SGTconst [c] (SRLVconst _ [d]))
-       // cond: 0 <= c && 0 < d && d <= 63 && 1<<uint64(64-d) <= c
+       // cond: 0 <= c && 0 < d && d <= 63 && 0xffffffffffffffff>>uint64(d) < uint64(c)
        // result: (MOVVconst [1])
        for {
                c := v.AuxInt
@@ -6230,7 +6230,7 @@ func rewriteValueMIPS64_OpMIPS64SGTconst_10(v *Value) bool {
                        break
                }
                d := v_0.AuxInt
-               if !(0 <= c && 0 < d && d <= 63 && 1<<uint64(64-d) <= c) {
+               if !(0 <= c && 0 < d && d <= 63 && 0xffffffffffffffff>>uint64(d) < uint64(c)) {
                        break
                }
                v.reset(OpMIPS64MOVVconst)
diff --git a/test/fixedbugs/issue29402.go b/test/fixedbugs/issue29402.go
new file mode 100644 (file)
index 0000000..8a1f959
--- /dev/null
@@ -0,0 +1,23 @@
+// run
+  
+// Copyright 2018 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.
+
+// Issue 29402: wrong optimization of comparison of
+// constant and shift on MIPS.
+
+package main
+
+//go:noinline
+func F(s []int) bool {
+       half := len(s) / 2
+       return half >= 0
+}
+
+func main() {
+       b := F([]int{1, 2, 3, 4})
+       if !b {
+               panic("FAIL")
+       }
+}