Many "simple" hard-forks are transparent to SPV, such as the BIP50 bug fix and increasing MAX_BLOCK_SIZE.
For your example of moving the coinbase transaction to the top of the tree, new full nodes need to somehow cheat the old SPV nodes to make it works.
More complicated changes, e.g. merkle sum tree, will break SPV nodes
You're not thinking deviously enough.
Lets suppose I define a new merkle-sum-product-christmas-tree which sums all the transaction values up and even distributes presents to the homeless; we'll call the top level digest of that tree D2, and the top level digest of the old merkle tree D1.
Now ask yourself, can a SPV node know if rather than setting hashMerkleRoot to D1 as before, we've set it to Hash(D1 | D2)? A full node certainly can - they have a full list of transactions and will immediately see that something isn't adding up - but what about a SPV node?
Also, it'd be interesting to know if any SPV clients out there would even notice if they were given two transactions, ostensibly from the same block, whose merkle paths back to the block header were of different lengths.
So we have at least 4 levels of hardforks:
Level I hardfork: a hardfork that is completely transparent to SPV nodes, such as the BIP50 bug fix, increasing MAX_BLOCK_SIZE, increasing block reward (too bad!!!)
Level II hardfork: a hardfork that adds new functions while all existing functions are still supported, such as SIGHASH_WITHINPUTVALUE (https://bitcointalksearch.org/topic/sighashwithinputvalue-super-lightweight-hw-wallets-and-offline-data-181734) . Old SPV nodes can still function as usual, just not supporting the new function.
Level III hardfork: a hardfork that will partially break SPV nodes, such as fixing the OP_CHECKMULTISIG bug. SPV nodes can still receive bitcoin from bug-fixed OP_CHECKMULTISIG but cannot send with it properly
Level IV hardfork: a hardfork that will completely break SPV nodes, usually something fundamentally change block or transaction format, such as increasing coin divisibility, 64bit block timestamp.
However, this pretty depends on how an SPV node exactly works. With the examples here I assume that SPV will only 1) make sure blocks have adequate PoW; 2) find the chain with highest PoW; 3) look for related transaction outputs in the chain. It would not check the validity of the signature (otherwise SIGHASH_WITHINPUTVALUE signatures of bug-fixed OP_CHECKMULTISIG would look invalid).
Please feel free to add more levels to the list (both softfork and hardfork).