The thing that I find hardest to get used to on ARM is watching compilers generate four or five or six register-based instructions to implement an addressing mode that could have been executed in a single instruction on x86. It really breaks my mental model of how C/C++ translates into machine code.
With modern compilers, the mental model of what code translates to is long dead. Operations are reordered and statically scheduled, code can be inlined, outlined, eliminated, or duplicated. Vectorization is a whole other can of worms that can appear in often surprising ways. Mix in security extensions like pointer authentication, branch target identification, or even pure software things like stack cookies and now you're getting code you never even wrote inserted everywhere.
The best approach is always just to verify the disassembly.
I don't really have any problems with mental models for the code I'm going to see on x64 (which does incorporate models of instruction scheduling, multiple issue, elimination (pretty easy), and vectorization, &c).
Maybe it will come with more time on ARM; but three years in, it's still not there.