From: Keith Randall Date: Fri, 9 Dec 2022 18:55:28 +0000 (-0800) Subject: [release-branch.go1.19] cmd/compile: fix conditional select rule X-Git-Tag: go1.19.5~11 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=7683c71ae1cfe016cc283d630460395a61174ad1;p=gostls13.git [release-branch.go1.19] cmd/compile: fix conditional select rule ARM64 maintains booleans in the low byte of registers. Upper parts of that register are junk. This rule is using all 32 bits of a boolean-containing register, which is wrong. Change the rule to only look at the low bit. Fixes #57212 Change-Id: Ibbef86b2be859df3d06d993db00e1231c481c428 Reviewed-on: https://go-review.googlesource.com/c/go/+/456556 Auto-Submit: Keith Randall TryBot-Result: Gopher Robot Reviewed-by: Cherry Mui Reviewed-by: Keith Randall Run-TryBot: Keith Randall Reviewed-on: https://go-review.googlesource.com/c/go/+/456559 Reviewed-by: Than McIntosh --- diff --git a/src/cmd/compile/internal/ssa/gen/ARM64.rules b/src/cmd/compile/internal/ssa/gen/ARM64.rules index 3776b3ca02..b5df4cf47b 100644 --- a/src/cmd/compile/internal/ssa/gen/ARM64.rules +++ b/src/cmd/compile/internal/ssa/gen/ARM64.rules @@ -316,9 +316,9 @@ (FCMPD x (FMOVDconst [0])) => (FCMPD0 x) (FCMPD (FMOVDconst [0]) x) => (InvertFlags (FCMPD0 x)) -// CSEL needs a flag-generating argument. Synthesize a CMPW if necessary. +// CSEL needs a flag-generating argument. Synthesize a TSTW if necessary. (CondSelect x y boolval) && flagArg(boolval) != nil => (CSEL [boolval.Op] x y flagArg(boolval)) -(CondSelect x y boolval) && flagArg(boolval) == nil => (CSEL [OpARM64NotEqual] x y (CMPWconst [0] boolval)) +(CondSelect x y boolval) && flagArg(boolval) == nil => (CSEL [OpARM64NotEqual] x y (TSTWconst [1] boolval)) (OffPtr [off] ptr:(SP)) && is32Bit(off) => (MOVDaddr [int32(off)] ptr) (OffPtr [off] ptr) => (ADDconst [off] ptr) diff --git a/src/cmd/compile/internal/ssa/rewriteARM64.go b/src/cmd/compile/internal/ssa/rewriteARM64.go index efeadf64cc..cd6ffa726f 100644 --- a/src/cmd/compile/internal/ssa/rewriteARM64.go +++ b/src/cmd/compile/internal/ssa/rewriteARM64.go @@ -23445,7 +23445,7 @@ func rewriteValueARM64_OpCondSelect(v *Value) bool { } // match: (CondSelect x y boolval) // cond: flagArg(boolval) == nil - // result: (CSEL [OpARM64NotEqual] x y (CMPWconst [0] boolval)) + // result: (CSEL [OpARM64NotEqual] x y (TSTWconst [1] boolval)) for { x := v_0 y := v_1 @@ -23455,8 +23455,8 @@ func rewriteValueARM64_OpCondSelect(v *Value) bool { } v.reset(OpARM64CSEL) v.AuxInt = opToAuxInt(OpARM64NotEqual) - v0 := b.NewValue0(v.Pos, OpARM64CMPWconst, types.TypeFlags) - v0.AuxInt = int32ToAuxInt(0) + v0 := b.NewValue0(v.Pos, OpARM64TSTWconst, types.TypeFlags) + v0.AuxInt = int32ToAuxInt(1) v0.AddArg(boolval) v.AddArg3(x, y, v0) return true diff --git a/test/fixedbugs/issue57184.go b/test/fixedbugs/issue57184.go new file mode 100644 index 0000000000..1384b50be8 --- /dev/null +++ b/test/fixedbugs/issue57184.go @@ -0,0 +1,40 @@ +// run + +// Copyright 2022 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 + +import ( + "log" + "reflect" + "sort" +) + +func main() { + const length = 257 + x := make([]int64, length) + for i := 0; i < length; i++ { + x[i] = int64(i) * 27644437 % int64(length) + } + + isLessStatic := func(i, j int) bool { + return x[i] < x[j] + } + + isLessReflect := reflect.MakeFunc(reflect.TypeOf(isLessStatic), func(args []reflect.Value) []reflect.Value { + i := args[0].Int() + j := args[1].Int() + b := x[i] < x[j] + return []reflect.Value{reflect.ValueOf(b)} + }).Interface().(func(i, j int) bool) + + sort.SliceStable(x, isLessReflect) + + for i := 0; i < length-1; i++ { + if x[i] >= x[i+1] { + log.Fatalf("not sorted! (length=%v, idx=%v)\n%v\n", length, i, x) + } + } +}