From c920fa537f1b1b10d27067224bdbe64f7bc68d51 Mon Sep 17 00:00:00 2001 From: Cherry Zhang Date: Tue, 27 Jun 2017 16:34:06 -0400 Subject: [PATCH] cmd/compile: fix slice-in-bound check on amd64p32 Should use CMPL instead of CMPQ. Fixes #20811. Change-Id: I610d487949c2c8a08b3743656149069d931a51bb Reviewed-on: https://go-review.googlesource.com/46870 Reviewed-by: Matthew Dempsky Run-TryBot: Cherry Zhang TryBot-Result: Gobot Gobot --- src/cmd/compile/internal/ssa/gen/AMD64.rules | 6 ++- src/cmd/compile/internal/ssa/rewriteAMD64.go | 50 +++++++++++++++++++- test/fixedbugs/issue20811.go | 23 +++++++++ 3 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 test/fixedbugs/issue20811.go diff --git a/src/cmd/compile/internal/ssa/gen/AMD64.rules b/src/cmd/compile/internal/ssa/gen/AMD64.rules index 5887a9454c..1900f5e794 100644 --- a/src/cmd/compile/internal/ssa/gen/AMD64.rules +++ b/src/cmd/compile/internal/ssa/gen/AMD64.rules @@ -441,8 +441,10 @@ (Convert x mem) && config.PtrSize == 4 -> (MOVLconvert x mem) (IsNonNil p) && config.PtrSize == 8 -> (SETNE (TESTQ p p)) (IsNonNil p) && config.PtrSize == 4 -> (SETNE (TESTL p p)) -(IsInBounds idx len) -> (SETB (CMPQ idx len)) -(IsSliceInBounds idx len) -> (SETBE (CMPQ idx len)) +(IsInBounds idx len) && config.PtrSize == 8 -> (SETB (CMPQ idx len)) +(IsInBounds idx len) && config.PtrSize == 4 -> (SETB (CMPL idx len)) +(IsSliceInBounds idx len) && config.PtrSize == 8 -> (SETBE (CMPQ idx len)) +(IsSliceInBounds idx len) && config.PtrSize == 4 -> (SETBE (CMPL idx len)) (NilCheck ptr mem) -> (LoweredNilCheck ptr mem) (GetG mem) -> (LoweredGetG mem) (GetClosurePtr) -> (LoweredGetClosurePtr) diff --git a/src/cmd/compile/internal/ssa/rewriteAMD64.go b/src/cmd/compile/internal/ssa/rewriteAMD64.go index 641dc11a17..f9a94cac36 100644 --- a/src/cmd/compile/internal/ssa/rewriteAMD64.go +++ b/src/cmd/compile/internal/ssa/rewriteAMD64.go @@ -39253,13 +39253,18 @@ func rewriteValueAMD64_OpInterCall_0(v *Value) bool { func rewriteValueAMD64_OpIsInBounds_0(v *Value) bool { b := v.Block _ = b + config := b.Func.Config + _ = config // match: (IsInBounds idx len) - // cond: + // cond: config.PtrSize == 8 // result: (SETB (CMPQ idx len)) for { _ = v.Args[1] idx := v.Args[0] len := v.Args[1] + if !(config.PtrSize == 8) { + break + } v.reset(OpAMD64SETB) v0 := b.NewValue0(v.Pos, OpAMD64CMPQ, types.TypeFlags) v0.AddArg(idx) @@ -39267,6 +39272,24 @@ func rewriteValueAMD64_OpIsInBounds_0(v *Value) bool { v.AddArg(v0) return true } + // match: (IsInBounds idx len) + // cond: config.PtrSize == 4 + // result: (SETB (CMPL idx len)) + for { + _ = v.Args[1] + idx := v.Args[0] + len := v.Args[1] + if !(config.PtrSize == 4) { + break + } + v.reset(OpAMD64SETB) + v0 := b.NewValue0(v.Pos, OpAMD64CMPL, types.TypeFlags) + v0.AddArg(idx) + v0.AddArg(len) + v.AddArg(v0) + return true + } + return false } func rewriteValueAMD64_OpIsNonNil_0(v *Value) bool { b := v.Block @@ -39308,13 +39331,18 @@ func rewriteValueAMD64_OpIsNonNil_0(v *Value) bool { func rewriteValueAMD64_OpIsSliceInBounds_0(v *Value) bool { b := v.Block _ = b + config := b.Func.Config + _ = config // match: (IsSliceInBounds idx len) - // cond: + // cond: config.PtrSize == 8 // result: (SETBE (CMPQ idx len)) for { _ = v.Args[1] idx := v.Args[0] len := v.Args[1] + if !(config.PtrSize == 8) { + break + } v.reset(OpAMD64SETBE) v0 := b.NewValue0(v.Pos, OpAMD64CMPQ, types.TypeFlags) v0.AddArg(idx) @@ -39322,6 +39350,24 @@ func rewriteValueAMD64_OpIsSliceInBounds_0(v *Value) bool { v.AddArg(v0) return true } + // match: (IsSliceInBounds idx len) + // cond: config.PtrSize == 4 + // result: (SETBE (CMPL idx len)) + for { + _ = v.Args[1] + idx := v.Args[0] + len := v.Args[1] + if !(config.PtrSize == 4) { + break + } + v.reset(OpAMD64SETBE) + v0 := b.NewValue0(v.Pos, OpAMD64CMPL, types.TypeFlags) + v0.AddArg(idx) + v0.AddArg(len) + v.AddArg(v0) + return true + } + return false } func rewriteValueAMD64_OpLeq16_0(v *Value) bool { b := v.Block diff --git a/test/fixedbugs/issue20811.go b/test/fixedbugs/issue20811.go new file mode 100644 index 0000000000..96b61ec728 --- /dev/null +++ b/test/fixedbugs/issue20811.go @@ -0,0 +1,23 @@ +// run + +// Copyright 2017 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 20811: slice-in-bound check is lowered incorrectly on +// amd64p32. + +package main + +func main() { + i := g() + _ = "x"[int32(i)] + j := g() + _ = "x"[:int32(j)] +} + +//go:noinline +func g() int64 { + return 4398046511104 +} + -- 2.50.0