The proper fix is to model CC as explicit register(s). Then you can fix the scheduler and register allocator,
i.e. any machine instruction level module that insert move, load, store ops, to insert instructions at the
right spot to avoid clobbering the CC registers. Not only is it useful for this bug, it also makes it easier to
implement a pass that optimize away cmp / test, etc.
Perhaps it's ok to just add instruction properties that tells us whether a instruction sets / reads CC. It's
hard to say.
FWIW, I think that it is about time we start modelling CC's correctly. This would require, at the minimum,
adding a new physreg to represent the CC, then marking each instruction that sets it as clobbering it.
It's better to model each flag individually e.g. N, Z, C, V, Q, the GE bits (collectively) etc. That way you can correctly model instructions that set N and Z but leave C and V unaffected. This allows you to move a MOV in between a CMP and a BCS, or between an ADDS and an ADC.
Lower thumbv4t & thumbv5 lo->lo copies through a push-pop sequence
On pre-v6 hardware, 'MOV lo, lo' gives undefined results, so such copies need to
be avoided. This patch trades simplicity for implementation time at the expense
of performance... As they say: correctness first, then performance.
See http://lists.cs.uiuc.edu/pipermail/llvmdev/2014-August/075998.html for a few
ideas on how to make this better.
AsmParser also doesn't permit MOV lo, lo (or CPY, as it used to be known), so you can't use it in embedded asm, but MC does permit it, so using clang to assemble a .s file with --target=thumbv4t-none-eabi gives no error but should. That's less of a problem though.