1
0
mirror of https://github.com/golang/go synced 2024-11-11 20:20:23 -07:00

cmd/compile: fix incorrect comparison folding

We lost a sign extension that was necessary. The nonnegative comparison
didn't have the correct extension on it. If the larger constant is
positive, but its shorter sign extension is negative, the rule breaks.

Fixes #41872

Change-Id: I6592ef103f840fbb786bf8cb94fd8804c760c976
Reviewed-on: https://go-review.googlesource.com/c/go/+/260701
Trust: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Alberto Donizetti <alb.donizetti@gmail.com>
This commit is contained in:
Keith Randall 2020-10-08 11:18:02 -07:00
parent 46ab0c0c04
commit a4b95cd092
3 changed files with 32 additions and 6 deletions

View File

@ -1274,8 +1274,8 @@
(CMPQconst (ANDQconst _ [m]) [n]) && 0 <= m && m < n => (FlagLT_ULT)
(CMPQconst (ANDLconst _ [m]) [n]) && 0 <= m && m < n => (FlagLT_ULT)
(CMPLconst (ANDLconst _ [m]) [n]) && 0 <= m && m < n => (FlagLT_ULT)
(CMPWconst (ANDLconst _ [m]) [n]) && 0 <= m && int16(m) < n => (FlagLT_ULT)
(CMPBconst (ANDLconst _ [m]) [n]) && 0 <= m && int8(m) < n => (FlagLT_ULT)
(CMPWconst (ANDLconst _ [m]) [n]) && 0 <= int16(m) && int16(m) < n => (FlagLT_ULT)
(CMPBconst (ANDLconst _ [m]) [n]) && 0 <= int8(m) && int8(m) < n => (FlagLT_ULT)
// TESTQ c c sets flags like CMPQ c 0.
(TESTQconst [c] (MOVQconst [d])) && int64(c) == d && c == 0 => (FlagEQ)

View File

@ -6886,7 +6886,7 @@ func rewriteValueAMD64_OpAMD64CMPBconst(v *Value) bool {
return true
}
// match: (CMPBconst (ANDLconst _ [m]) [n])
// cond: 0 <= m && int8(m) < n
// cond: 0 <= int8(m) && int8(m) < n
// result: (FlagLT_ULT)
for {
n := auxIntToInt8(v.AuxInt)
@ -6894,7 +6894,7 @@ func rewriteValueAMD64_OpAMD64CMPBconst(v *Value) bool {
break
}
m := auxIntToInt32(v_0.AuxInt)
if !(0 <= m && int8(m) < n) {
if !(0 <= int8(m) && int8(m) < n) {
break
}
v.reset(OpAMD64FlagLT_ULT)
@ -8243,7 +8243,7 @@ func rewriteValueAMD64_OpAMD64CMPWconst(v *Value) bool {
return true
}
// match: (CMPWconst (ANDLconst _ [m]) [n])
// cond: 0 <= m && int16(m) < n
// cond: 0 <= int16(m) && int16(m) < n
// result: (FlagLT_ULT)
for {
n := auxIntToInt16(v.AuxInt)
@ -8251,7 +8251,7 @@ func rewriteValueAMD64_OpAMD64CMPWconst(v *Value) bool {
break
}
m := auxIntToInt32(v_0.AuxInt)
if !(0 <= m && int16(m) < n) {
if !(0 <= int16(m) && int16(m) < n) {
break
}
v.reset(OpAMD64FlagLT_ULT)

View File

@ -0,0 +1,26 @@
// run
// Copyright 2020 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
//go:noinline
func f8(x int32) bool {
return byte(x&0xc0) == 64
}
//go:noinline
func f16(x int32) bool {
return uint16(x&0x8040) == 64
}
func main() {
if !f8(64) {
panic("wanted true, got false")
}
if !f16(64) {
panic("wanted true, got false")
}
}