(ZeroExt16to(32|64) x) -> (MOVHZreg x)
(ZeroExt32to64 x) -> (MOVWZreg x)
-(Trunc(16|32|64)to8 x) && isSigned(x.Type) -> (MOVBreg x)
+(Trunc(16|32|64)to8 <t> x) && isSigned(t) -> (MOVBreg x)
(Trunc(16|32|64)to8 x) -> (MOVBZreg x)
-(Trunc(32|64)to16 x) && isSigned(x.Type) -> (MOVHreg x)
+(Trunc(32|64)to16 <t> x) && isSigned(t) -> (MOVHreg x)
(Trunc(32|64)to16 x) -> (MOVHZreg x)
-(Trunc64to32 x) && isSigned(x.Type) -> (MOVWreg x)
+(Trunc64to32 <t> x) && isSigned(t) -> (MOVWreg x)
(Trunc64to32 x) -> (MOVWZreg x)
(Slicemask <t> x) -> (SRADconst (NEG <t> x) [63])
}
}
func rewriteValuePPC64_OpTrunc16to8_0(v *Value) bool {
- // match: (Trunc16to8 x)
- // cond: isSigned(x.Type)
+ // match: (Trunc16to8 <t> x)
+ // cond: isSigned(t)
// result: (MOVBreg x)
for {
+ t := v.Type
x := v.Args[0]
- if !(isSigned(x.Type)) {
+ if !(isSigned(t)) {
break
}
v.reset(OpPPC64MOVBreg)
}
}
func rewriteValuePPC64_OpTrunc32to16_0(v *Value) bool {
- // match: (Trunc32to16 x)
- // cond: isSigned(x.Type)
+ // match: (Trunc32to16 <t> x)
+ // cond: isSigned(t)
// result: (MOVHreg x)
for {
+ t := v.Type
x := v.Args[0]
- if !(isSigned(x.Type)) {
+ if !(isSigned(t)) {
break
}
v.reset(OpPPC64MOVHreg)
}
}
func rewriteValuePPC64_OpTrunc32to8_0(v *Value) bool {
- // match: (Trunc32to8 x)
- // cond: isSigned(x.Type)
+ // match: (Trunc32to8 <t> x)
+ // cond: isSigned(t)
// result: (MOVBreg x)
for {
+ t := v.Type
x := v.Args[0]
- if !(isSigned(x.Type)) {
+ if !(isSigned(t)) {
break
}
v.reset(OpPPC64MOVBreg)
}
}
func rewriteValuePPC64_OpTrunc64to16_0(v *Value) bool {
- // match: (Trunc64to16 x)
- // cond: isSigned(x.Type)
+ // match: (Trunc64to16 <t> x)
+ // cond: isSigned(t)
// result: (MOVHreg x)
for {
+ t := v.Type
x := v.Args[0]
- if !(isSigned(x.Type)) {
+ if !(isSigned(t)) {
break
}
v.reset(OpPPC64MOVHreg)
}
}
func rewriteValuePPC64_OpTrunc64to32_0(v *Value) bool {
- // match: (Trunc64to32 x)
- // cond: isSigned(x.Type)
+ // match: (Trunc64to32 <t> x)
+ // cond: isSigned(t)
// result: (MOVWreg x)
for {
+ t := v.Type
x := v.Args[0]
- if !(isSigned(x.Type)) {
+ if !(isSigned(t)) {
break
}
v.reset(OpPPC64MOVWreg)
}
}
func rewriteValuePPC64_OpTrunc64to8_0(v *Value) bool {
- // match: (Trunc64to8 x)
- // cond: isSigned(x.Type)
+ // match: (Trunc64to8 <t> x)
+ // cond: isSigned(t)
// result: (MOVBreg x)
for {
+ t := v.Type
x := v.Args[0]
- if !(isSigned(x.Type)) {
+ if !(isSigned(t)) {
break
}
v.reset(OpPPC64MOVBreg)
--- /dev/null
+// run
+
+// Copyright 2019 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.
+
+// Code was miscompiled on ppc64le due to incorrect zero-extension
+// that was CSE'd.
+
+package main
+
+//go:noinline
+func g(i uint64) uint64 {
+ return uint64(uint32(i))
+}
+
+var sink uint64
+
+func main() {
+ for i := uint64(0); i < 1; i++ {
+ i32 := int32(i - 1)
+ sink = uint64((uint32(i32) << 1) ^ uint32((i32 >> 31)))
+ x := g(uint64(i32))
+ if x != uint64(uint32(i32)) {
+ panic(x)
+ }
+ }
+}