Skip to content

Commit a4b95cd

Browse files
committed
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 <[email protected]> Run-TryBot: Keith Randall <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Alberto Donizetti <[email protected]>
1 parent 46ab0c0 commit a4b95cd

File tree

3 files changed

+32
-6
lines changed

3 files changed

+32
-6
lines changed

src/cmd/compile/internal/ssa/gen/AMD64.rules

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,8 +1274,8 @@
12741274
(CMPQconst (ANDQconst _ [m]) [n]) && 0 <= m && m < n => (FlagLT_ULT)
12751275
(CMPQconst (ANDLconst _ [m]) [n]) && 0 <= m && m < n => (FlagLT_ULT)
12761276
(CMPLconst (ANDLconst _ [m]) [n]) && 0 <= m && m < n => (FlagLT_ULT)
1277-
(CMPWconst (ANDLconst _ [m]) [n]) && 0 <= m && int16(m) < n => (FlagLT_ULT)
1278-
(CMPBconst (ANDLconst _ [m]) [n]) && 0 <= m && int8(m) < n => (FlagLT_ULT)
1277+
(CMPWconst (ANDLconst _ [m]) [n]) && 0 <= int16(m) && int16(m) < n => (FlagLT_ULT)
1278+
(CMPBconst (ANDLconst _ [m]) [n]) && 0 <= int8(m) && int8(m) < n => (FlagLT_ULT)
12791279

12801280
// TESTQ c c sets flags like CMPQ c 0.
12811281
(TESTQconst [c] (MOVQconst [d])) && int64(c) == d && c == 0 => (FlagEQ)

src/cmd/compile/internal/ssa/rewriteAMD64.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/fixedbugs/issue41872.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// run
2+
3+
// Copyright 2020 The Go Authors. All rights reserved. Use of this
4+
// source code is governed by a BSD-style license that can be found in
5+
// the LICENSE file.
6+
7+
package main
8+
9+
//go:noinline
10+
func f8(x int32) bool {
11+
return byte(x&0xc0) == 64
12+
}
13+
14+
//go:noinline
15+
func f16(x int32) bool {
16+
return uint16(x&0x8040) == 64
17+
}
18+
19+
func main() {
20+
if !f8(64) {
21+
panic("wanted true, got false")
22+
}
23+
if !f16(64) {
24+
panic("wanted true, got false")
25+
}
26+
}

0 commit comments

Comments
 (0)