Note: This patch solves a similar problem as D49364. The difference is that this change addresses the problem in Thumb2 while D49364 is for Thumb1.
LLVM fails with an assertion error or generates incorrect code (if assertions are disabled) when a register of the hGPR class needs to be spilled in Thumb2.
Example:
$ cat test.c void constraint_h(void) { int i; asm volatile("@ %0" : : "h" (i) : "r12"); } $ clang -target arm-none-eabi -march=armv7-m -c test.c Unsupported addressing mode! UNREACHABLE executed at /work/llvm/lib/Target/ARM/Thumb2InstrInfo.cpp:630! [...]
The code was compiled at -O0 and so Fast Register Allocator is used. The allocator ends up calling Thumb2InstrInfo::storeRegToStackSlot() to store r12 (hGPR) in a stack slot but the method does not know how to do it. The request then gets deferred to ARMBaseInstrInfo::storeRegToStackSlot() which incorrectly generates ARM instruction STRi12 for the store. If assertions are enabled, this gets caught later in rewriteT2FrameIndex() because the instruction uses ARMII::AddrMode_i12 and the rewrite function does not know how to handle it.
The patch generalizes code in Thumb2InstrInfo::storeRegToStackSlot() and loadRegToStackSlot() to allow the GPR class or any of its sub-classes (including hGPR) to be stored/loaded by ARM::t2STRi12/ARM::t2LDRi12.