If you use a deterministic nonsense value, the compiler can turn the result of decrypt(nonsense) into a constant at compile time, and just directly output the constant to the volatile variable, without actually ever calling decrypt again at runtime. So it can turn this:
decrypt(real);
nonsense = <whatever>;
volatile junk = hash(decrypt(nonsense));
Into this: decrypt(real);
volatile junk = <the appropriate constant value>;
But even if you nonsense is non-deterministic (although I question where you are getting the entropy - if you're using a syscall / random / etc your performance has potentially just gone out the window), the compiler is well within its rights to optimize the second junk decrypt of the nonsense input differently than the first (real) decrypt - in such a way that it does not overwrite everything left behind by the first decryption.(Same with encryption)