Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile: shouldn't nil check newobject return value #15390

Closed
randall77 opened this issue Apr 20, 2016 · 13 comments
Closed

cmd/compile: shouldn't nil check newobject return value #15390

randall77 opened this issue Apr 20, 2016 · 13 comments

Comments

@randall77
Copy link
Contributor

type T struct {
    a, b, c, d, e, f int
}
var x T
func f() *T {
    t := new(T)
    *t = x
    return t
}

There is a nil check of t in the generated code for f. We don't need one, newobject always returns a non-nil value.

@randall77 randall77 added this to the Go1.8 milestone Apr 20, 2016
@randall77 randall77 changed the title shouldn't nil check newobject return value cmd/compile: shouldn't nil check newobject return value Apr 20, 2016
@josharian
Copy link
Contributor

There's also a todo in a comment in nilcheckelim for this. The right fix is probably a one liner in the front end, though, marking the return value of the runtime call as Bounded.

@randall77
Copy link
Contributor Author

randall77 commented Apr 21, 2016

Yes. We have to be a bit careful, though. I think there is some confusion (in my head, at least) if Bounded marks a pointer that is non-nil, or a dereference which will not fault. The former could be on any op that generates a pointer, the latter would only be on OIND or ODOTPTR (any others?). The tricky part is we need to pick one or the other, a mix won't work.
Bounded for bounds checks uses the latter meaning, as there is no way for it to mean the former (it would have to be on a pair of slice+index somehow). So Bounded for pointer nilness should probably work the same way.
But that means just marking the return value of newobject isn't the right thing. You must mark all the OIND that use newobject. That isn't as easy.
Or we add a new mark to nodes for the non-nil attribute.

@josharian
Copy link
Contributor

You're right. I think we should add a new non-nil attribute to nodes. We might also want to add a unique/bespoke attribute as well, which would be a cleaner and cheaper way to accomplish CL 21937. We'll probably need to give Node a bitmap and get rid of some of its bools in the process, but that's desirable anyway.

@randall77
Copy link
Contributor Author

randall77 commented Apr 21, 2016

I have a CL which already does this for map return values in an ad-hoc fashion: https://go-review.googlesource.com/c/22291/
Let me know if someone picks this up and we can adjust that CL appropriately.

@gopherbot
Copy link

CL https://golang.org/cl/22291 mentions this issue.

@josharian
Copy link
Contributor

We can do the Node bitmask and Bespoke thing later.

@randall77
Copy link
Contributor Author

Actually, this isn't fixed. There's nothing propagating the NonNil flag I added. So when you do:

p := new(T)
x := *p

It compiles to OAS(p, OCALL(...)). The OCALL has the NonNil flag, but it never gets copied to p, so the indirection *p still has a nil check.
It's tricky to copy it to p during walk, because p may be redefined later.
Maybe SSA could pick up this flag and propagate it. Have to think about it.

@randall77 randall77 reopened this Apr 22, 2016
@josharian
Copy link
Contributor

Propagating this is exactly the sort of thing that nilcheckelim does. Maybe instead of eliminating the nilcheck at ssa construction time, we add a hint that the nilcheck can be eliminated, and pick up that hint at the beginning of nilcheckelim? It's slightly wasteful, but avoids a bunch of new mechanism.

@gopherbot
Copy link

CL https://golang.org/cl/27930 mentions this issue.

gopherbot pushed a commit that referenced this issue Aug 30, 2016
Recognize runtime.newobject and don't Zero or NilCheck it.

Fixes #15914 (?)
Updates #15390.

TBD: add test

Change-Id: Ia3bfa5c2ddbe2c27c92d9f68534a713b5ce95934
Reviewed-on: https://go-review.googlesource.com/27930
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
@randall77
Copy link
Contributor Author

@cherrymui , why doesn't your CL 27930 fix this?

@cherrymui
Copy link
Member

I think it does. I wasn't sure whether it covers all the cases, letting you and Josh to decide.

@cherrymui
Copy link
Member

@randall77 The rules are commented out in the new nilcheck mechanism. I couldn't find a problem if I re-enable them. Is there a reason?

@randall77
Copy link
Contributor Author

Ah, yes, that was me. If re-enabling doesn't cause a problem, go ahead and do that.

@golang golang locked and limited conversation to collaborators Sep 28, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants