From fd788a86b6427ef7ec1f25d4d4f0412bc883ccaf Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Mon, 22 Apr 2019 18:21:37 -0700 Subject: [PATCH] cmd/compile: always mark atColumn1 results as statements In 31618, we end up comparing the is-stmt-ness of positions to repurpose real instructions as inline marks. If the is-stmt-ness doesn't match, we end up not being able to remove the inline mark. Always use statement-full positions to do the matching, so we always find a match if there is one. Also always use positions that are statements for inline marks. Fixes #31618 Change-Id: Idaf39bdb32fa45238d5cd52973cadf4504f947d5 Reviewed-on: https://go-review.googlesource.com/c/go/+/173324 Run-TryBot: Keith Randall Reviewed-by: David Chase --- src/cmd/compile/internal/gc/inl.go | 2 +- src/cmd/compile/internal/gc/ssa.go | 1 + src/cmd/internal/src/pos.go | 2 +- test/codegen/issue31618.go | 22 ++++++++++++++++++++++ 4 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 test/codegen/issue31618.go diff --git a/src/cmd/compile/internal/gc/inl.go b/src/cmd/compile/internal/gc/inl.go index 35cbadafd73..5013c556631 100644 --- a/src/cmd/compile/internal/gc/inl.go +++ b/src/cmd/compile/internal/gc/inl.go @@ -1055,7 +1055,7 @@ func mkinlcall(n, fn *Node, maxCost int32) *Node { // to put a breakpoint. Not sure if that's really necessary or not // (in which case it could go at the end of the function instead). inlMark := nod(OINLMARK, nil, nil) - inlMark.Pos = n.Pos.WithDefaultStmt() + inlMark.Pos = n.Pos.WithIsStmt() inlMark.Xoffset = int64(newIndex) ninit.Append(inlMark) diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go index 930779045ab..0f043d8b5e2 100644 --- a/src/cmd/compile/internal/gc/ssa.go +++ b/src/cmd/compile/internal/gc/ssa.go @@ -5369,6 +5369,7 @@ func genssa(f *ssa.Func, pp *Progs) { // We found an instruction with the same source position as // some of the inline marks. // Use this instruction instead. + p.Pos = p.Pos.WithIsStmt() // promote position to a statement pp.curfn.Func.lsym.Func.AddInlMark(p, inlMarks[m]) // Make the inline mark a real nop, so it doesn't generate any code. m.As = obj.ANOP diff --git a/src/cmd/internal/src/pos.go b/src/cmd/internal/src/pos.go index 0e8973fe905..c9d3d347dbd 100644 --- a/src/cmd/internal/src/pos.go +++ b/src/cmd/internal/src/pos.go @@ -445,5 +445,5 @@ func (x lico) lineNumberHTML() string { } func (x lico) atColumn1() lico { - return makeLico(x.Line(), 1) | (x & (isStmtMask | xlogueMask)) + return makeLico(x.Line(), 1).withIsStmt() } diff --git a/test/codegen/issue31618.go b/test/codegen/issue31618.go new file mode 100644 index 00000000000..8effe2995b8 --- /dev/null +++ b/test/codegen/issue31618.go @@ -0,0 +1,22 @@ +// asmcheck + +// 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. + +package codegen + +// Make sure we remove both inline marks in the following code. +// Both +5 and +6 should map to real instructions, which can +// be used as inline marks instead of explicit nops. +func f(x int) int { + // amd64:-"XCHGL" + x = g(x) + 5 + // amd64:-"XCHGL" + x = g(x) + 6 + return x +} + +func g(x int) int { + return x >> 3 +}