(EQ (CMPconst [0] z:(AND x y)) yes no) && z.Uses == 1 -> (EQ (TST x y) yes no)
(NE (CMPconst [0] z:(AND x y)) yes no) && z.Uses == 1 -> (NE (TST x y) yes no)
-(EQ (CMPWconst [0] z:(AND x y)) yes no) && z.Uses == 1 -> (EQ (TST x y) yes no)
-(NE (CMPWconst [0] z:(AND x y)) yes no) && z.Uses == 1 -> (NE (TST x y) yes no)
+(EQ (CMPWconst [0] z:(AND x y)) yes no) && z.Uses == 1 -> (EQ (TSTW x y) yes no)
+(NE (CMPWconst [0] z:(AND x y)) yes no) && z.Uses == 1 -> (NE (TSTW x y) yes no)
(EQ (CMPconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 -> (EQ (TSTconst [c] y) yes no)
(NE (CMPconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 -> (NE (TSTconst [c] y) yes no)
}
// match: (EQ (CMPWconst [0] z:(AND x y)) yes no)
// cond: z.Uses == 1
- // result: (EQ (TST x y) yes no)
+ // result: (EQ (TSTW x y) yes no)
for {
v := b.Control
if v.Op != OpARM64CMPWconst {
break
}
b.Kind = BlockARM64EQ
- v0 := b.NewValue0(v.Pos, OpARM64TST, types.TypeFlags)
+ v0 := b.NewValue0(v.Pos, OpARM64TSTW, types.TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
b.SetControl(v0)
}
// match: (NE (CMPWconst [0] z:(AND x y)) yes no)
// cond: z.Uses == 1
- // result: (NE (TST x y) yes no)
+ // result: (NE (TSTW x y) yes no)
for {
v := b.Control
if v.Op != OpARM64CMPWconst {
break
}
b.Kind = BlockARM64NE
- v0 := b.NewValue0(v.Pos, OpARM64TST, types.TypeFlags)
+ v0 := b.NewValue0(v.Pos, OpARM64TSTW, types.TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
b.SetControl(v0)
--- /dev/null
+// 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 26438: arm64 backend may use 64-bit TST for
+// "if uint32(a)&uint32(b) == 0", which should be
+// 32-bit TSTW
+
+package main
+
+//go:noinline
+func tstw(a, b uint64) uint64 {
+ if uint32(a)&uint32(b) == 0 {
+ return 100
+ } else {
+ return 200
+ }
+}
+
+func main() {
+ if tstw(0xff00000000, 0xaa00000000) == 200 {
+ panic("impossible")
+ }
+}