Techincally, yes, the compiler could do this but ideally, it wouldn't.
The reason is that you would run into issues with determining if there is anything else holding onto the reference. The compiler cannot infer who holds the reference at compile time (maybe through static analysis it could, but still, it's not guaranteed).
Now, it may be possible to do this at runtime, but that's still not ideal. It would require the equivalent of a GC every time a reference is set to null (a mark and sweep). Then for anything that is GCed, if there is an IDisposable implementation on it, call Dispose. This would drag the CLR into the mud, and make it perform horribly.
Of course, there's always reference counting (as nonnb mentioned in his comment on the question), but that's just going back to COM, and not ideal either. The complexities of reference counting are what gave birth to the GC aspect of the CLR in the first place.
Something to consider: If you have a situation where you don't know who actually has ownership of your IDisposable implementation, then it represents a design flaw in your system. If you have a function that works on such instances, it should either make the explicit declaration that it will Dispose of such instances, or it will leave that to the discretion of the caller (the latter being the preferred method).