[Thumb1] Re-write emitThumbRegPlusImmediate

This was motivated by a bug which caused code like this to be
miscompiled:
  declare void @take_ptr(i8*)
  define void @test() {
    %addr1.32 = alloca i8
    %addr2.32 = alloca i32, i32 1028
    call void @take_ptr(i8* %addr1)
    ret void
  }

This was emitting the following assembly to get the value of %addr1:
  add r0, sp, #1020
  add r0, r0, #8
However, "add r0, r0, #8" is not a valid Thumb1 instruction, and this
could not be assembled. The generated object file contained this,
resulting in r0 holding SP+8 rather tha SP+1028:
  add r0, sp, #1020
  add r0, sp, #8

This function looked like it could have caused miscompilations for
other combinations of registers and offsets (though I don't think it is
currently called with these), and the heuristic it used did not match
the emitted code in all cases.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222125 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Oliver Stannard
2014-11-17 11:18:10 +00:00
parent a18e46cbc9
commit 8f832fce3b
4 changed files with 213 additions and 160 deletions

View File

@@ -595,10 +595,10 @@ inline uint64_t PowerOf2Floor(uint64_t A) {
/// RoundUpToAlignment(5, 8) = 8
/// RoundUpToAlignment(17, 8) = 24
/// RoundUpToAlignment(~0LL, 8) = 0
/// RoundUpToAlignment(321, 255) = 510
/// \endcode
inline uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align) {
assert(isPowerOf2_64(Align) && "Alignment must be power of 2!");
return (Value + Align - 1) & ~uint64_t(Align - 1);
return (Value + Align - 1) / Align * Align;
}
/// Returns the offset to the next integer (mod 2**64) that is greater than