Hi folks, I'm looking for a bit of a historic context for a fun GCC behavior we stumbled across. For... reasons we build some of our binaries using an older version of GCC (8.3.1, yes, we'll be upgrading soon, and no, this message is not about helping with an ancient version :-) )
We noticed that this version of GCC compiling on aarch64 will happily use FP registers to temporarily store/load pointers, so there'd be "fmov d9, x1" to store a pointer, and then later when it's used as a parameter to a function call we'll see "fmov x1, d9" etc. We noticed this while investigating some crashes that seemed to always occur in functions called with parameters loaded through this mechanism, on certain specific models of aarch64 CPUs. On the face of it, this doesn't seem a _too_ terrible idea – one'd think that a FP register should preserve the bit pattern so as long as the only operations are stores and loads, what's the harm, right? Hey, more free registers! Except, on some silicon, it's unfortunately strongly correlated with crashes further down the callee chain. Further proving the theory is that after we did some judicious application of __attribute__((target("general-regs-only"))) to offending functions to discourage the compiler from the practice, the crashes were gone. Unfortunately, it sometimes required contorting the code to move any implied uses of FP out of the way (heck, an inlined std::map constructor requires FP operations 'cause of its load factor!) I also noticed that a more modern version of GCC (e.g. 12.x) does not seem to emit such code anymore (thus also eliminating the problem.) Curiously, I couldn't wrangle a good enough Google search term to find anything about what brought about the change – a discussion, a blog post, anything. I wanted to know if the practice of stashing pointers in FP registers indeed proved to be dangerous and was thus deliberately abandoned, or is it maybe just a byproduct of some other change. If someone knows more about this, I'd be very curious to hear about it. It'd be great to know that this was an explicitly eliminated behavior so we can rest assured that by using a newer version of GCC we will not get bitten by it again. Thanks, Attila.