Suppose an old contract is called now that contains an opcode that was invalid then but has some meaning now. What happens when this opcode is executed during a recent transaction: Will execution fail or will the opcode be executed according to the current semantics? In other words: Are contracts executed with the semantics valid at the time of deployment or with the semantics valid at the time of contract invocation?
Execution of the opcode will change even in old contracts. An example of this is revert. Solidity added support for require and revert style errors prior to the Byzantium fork, but when the opcode was activated before the hardfork it just worked as an error. The same deployed contracts after the fork used the opcode to revert without eating all the gas.