1
0
mirror of https://github.com/golang/go synced 2024-11-17 15:44:40 -07:00

cmd/compile: fix buggy AMD64 rewrite from CL 213058

CL 213058's "bonus optimization I noticed while working on this"
turns out to be buggy. It would be correct for CMP, but not TEST.
Fix it to use TEST semantics instead.

This was breaking compilation with the upcoming Spectre mode.

Change-Id: If2d4c3798ed182f35f0244febe74e68c61e4c61b
Reviewed-on: https://go-review.googlesource.com/c/go/+/222853
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Russ Cox 2020-03-11 00:02:04 -04:00
parent 96dc04412d
commit b136f0c17b
2 changed files with 52 additions and 3 deletions

View File

@ -1254,7 +1254,10 @@
(CMPWconst (ANDLconst _ [m]) [n]) && 0 <= int16(m) && int16(m) < int16(n) -> (FlagLT_ULT)
(CMPBconst (ANDLconst _ [m]) [n]) && 0 <= int8(m) && int8(m) < int8(n) -> (FlagLT_ULT)
(TEST(Q|L)const [c] (MOV(Q|L)const [c])) -> (FlagEQ)
// TESTQ c c sets flags like CMPQ c 0.
(TEST(Q|L)const [c] (MOV(Q|L)const [c])) && c == 0 -> (FlagEQ)
(TEST(Q|L)const [c] (MOV(Q|L)const [c])) && c < 0 -> (FlagLT_UGT)
(TEST(Q|L)const [c] (MOV(Q|L)const [c])) && c > 0 -> (FlagGT_UGT)
// TODO: DIVxU also.

View File

@ -26562,15 +26562,38 @@ func rewriteValueAMD64_OpAMD64TESTL(v *Value) bool {
func rewriteValueAMD64_OpAMD64TESTLconst(v *Value) bool {
v_0 := v.Args[0]
// match: (TESTLconst [c] (MOVLconst [c]))
// cond: c == 0
// result: (FlagEQ)
for {
c := v.AuxInt
if v_0.Op != OpAMD64MOVLconst || v_0.AuxInt != c {
if v_0.Op != OpAMD64MOVLconst || v_0.AuxInt != c || !(c == 0) {
break
}
v.reset(OpAMD64FlagEQ)
return true
}
// match: (TESTLconst [c] (MOVLconst [c]))
// cond: c < 0
// result: (FlagLT_UGT)
for {
c := v.AuxInt
if v_0.Op != OpAMD64MOVLconst || v_0.AuxInt != c || !(c < 0) {
break
}
v.reset(OpAMD64FlagLT_UGT)
return true
}
// match: (TESTLconst [c] (MOVLconst [c]))
// cond: c > 0
// result: (FlagGT_UGT)
for {
c := v.AuxInt
if v_0.Op != OpAMD64MOVLconst || v_0.AuxInt != c || !(c > 0) {
break
}
v.reset(OpAMD64FlagGT_UGT)
return true
}
// match: (TESTLconst [-1] x)
// cond: x.Op != OpAMD64MOVLconst
// result: (TESTL x x)
@ -26644,15 +26667,38 @@ func rewriteValueAMD64_OpAMD64TESTQ(v *Value) bool {
func rewriteValueAMD64_OpAMD64TESTQconst(v *Value) bool {
v_0 := v.Args[0]
// match: (TESTQconst [c] (MOVQconst [c]))
// cond: c == 0
// result: (FlagEQ)
for {
c := v.AuxInt
if v_0.Op != OpAMD64MOVQconst || v_0.AuxInt != c {
if v_0.Op != OpAMD64MOVQconst || v_0.AuxInt != c || !(c == 0) {
break
}
v.reset(OpAMD64FlagEQ)
return true
}
// match: (TESTQconst [c] (MOVQconst [c]))
// cond: c < 0
// result: (FlagLT_UGT)
for {
c := v.AuxInt
if v_0.Op != OpAMD64MOVQconst || v_0.AuxInt != c || !(c < 0) {
break
}
v.reset(OpAMD64FlagLT_UGT)
return true
}
// match: (TESTQconst [c] (MOVQconst [c]))
// cond: c > 0
// result: (FlagGT_UGT)
for {
c := v.AuxInt
if v_0.Op != OpAMD64MOVQconst || v_0.AuxInt != c || !(c > 0) {
break
}
v.reset(OpAMD64FlagGT_UGT)
return true
}
// match: (TESTQconst [-1] x)
// cond: x.Op != OpAMD64MOVQconst
// result: (TESTQ x x)