Before this bug was fixed, the newly added testcase would fail with the message:
LLVM ERROR: Not supported instr: <MCInst XXX <MCOperand Reg:1> <MCOperand Imm:15> <MCOperand Reg:53>> where XXX is the OpCode of either the STDWSPQRr instruction or the STDSPQRr instruction.
The issue was that the ISel lowering pass would lower many stack slot stores to these
instructions, but the frame pointer elimination code (that is designed to rewrite these two
instructions to real instructions) was only designed to run for STDWSPQRr/STDSPQRr instructions
that appeared in the basic blocks that contained the FrameSetup/FrameDestroy instructions.
The bug was fixed by modifying the code so that it unconditionally runs on STDWSPQRr/STDSPQRr
instructions and always expands them with the relevant STDWPtrQRr or STDPtrQRr instructions.
The bug is fixed by making the TargetInstrInfo::{isFrameInstr(), getFrameSize()} methods
virtual, and overriding them in the AVR backend. The LLVM middle end now
treats STDWSPQRr/STDSPQRr instructions as zero-sized frame instructions
so that they get the same treatment and are rewritten during call frame
pseudo elimination process, which is the one time we have enough
information to correctly rewrite STDWSPQRr/STDSPQRr operations to the stack
pointer.
This bug was originally discovered due to the Rust compiler_builtins library. Its 0.1.37 release
contained a 128-bit software division/remainder routine that exercised this buggy branch in the code.
If fixStackStores() is now being called for each STDWSPQRr and STDSPQRr, does the loop inside fixStackStores() still make sense?