This is an archive of the discontinued LLVM Phabricator instance.

[Thumb1] Re-write emitThumbRegPlusImmediate
ClosedPublic

Authored by olista01 on Nov 11 2014, 2:02 AM.

Details

Reviewers
t.p.northover
Summary

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.

Diff Detail

Event Timeline

olista01 updated this revision to Diff 16031.Nov 11 2014, 2:02 AM
olista01 retitled this revision from to [Thumb1] Re-write emitThumbRegPlusImmediate.
olista01 updated this object.
olista01 edited the test plan for this revision. (Show Details)
olista01 added a reviewer: t.p.northover.
olista01 set the repository for this revision to rL LLVM.
olista01 added a subscriber: Unknown Object (MLST).
t.p.northover edited edge metadata.Nov 11 2014, 2:46 PM

Hi Oliver,

I'm not sure how many comments I've got really, I suspect I've picked up on the same issue repeatedly in many cases. But still...

lib/Target/ARM/Thumb1RegisterInfo.cpp
146–147

Why not just fix the implementation of RoundUpToAlignment? Clang seems quite capable of optimising "/Align * Align" when Align is a power of 2, and it looks like the function gets inlined at all of its callsites.

228–259

isMul4 will be unused in a release build, I think, causing a warning.

242–245

This doesn't seem to line up with what actually gets implemented. In particular, I think we're in deep trouble if the RangeAfterCopy actually does get rounded up.

248

I think this overflows if RequiredExtraInstrs = UINT_MAX and there's a copy instruction.

272–273

I don't think this works with an unaligned copy but an aligned extra. That case doesn't seem to exist anyway, but perhaps it should more clear if that's intentional (comments, in the assert, ...).

olista01 added inline comments.Nov 13 2014, 5:40 AM
lib/Target/ARM/Thumb1RegisterInfo.cpp
242–245

I'm not sure I follow. This should round RequiredExtraInstrs up to the lowest integer number of instructions that could be used, and the loop then handles as much of the immediate as possible with each instruction, so these should match up. Can you give an example where this doesn't work?

olista01 updated this revision to Diff 16152.Nov 13 2014, 5:43 AM
olista01 edited edge metadata.
  • Use existing RoundUpToAlignment
  • Remove isMul4, as it is unused in release builds
  • Assert on a case we could handle, but currently don't (and don't need to)
  • Don't fall back to the const pool when we don't have an extra instruction but also don't need one (I think this case is currently unused)

Hi Oliver,

Thanks for updating the patch. To explain my previous comment a bit more:

lib/Target/ARM/Thumb1RegisterInfo.cpp
242–245

I think it falls into the limited alignment handling comments

If RangeAfterCopy has been rounded up here, then that means "(Bytes - CopyRange) % ExtraRange != 0". But "Bytes - CopyRange" is precisely what we'll have to emit with the extra instructions (Copy greedily takes as many bytes as possible). This is impossible.

I don't believe the case actually happens, because when ExtraRange != 1, we only ever emit a MOV so CopyRange == 0. But that means the clause is untested and untestable, of course: another reason to remove it.

olista01 added inline comments.Nov 14 2014, 9:18 AM
lib/Target/ARM/Thumb1RegisterInfo.cpp
242–245

I think that the assertion on line 230 (second version of the patch) should catch this case, but I'll add one closer to here to be sure.

olista01 updated this revision to Diff 16220.Nov 14 2014, 9:20 AM

Add an extra assertion to catch the case where RangeAfterCopy is not aligned, but CopyOpc requires an aligned immediate.

t.p.northover accepted this revision.Nov 14 2014, 3:27 PM
t.p.northover edited edge metadata.

Ah, sorry, turns out I was misreading just what alignment we were rounding up to. No wonder you were confused.

I think this looks reasonable. Fingers crossed we haven't missed anything; frame lowering is a nightmare.

Tim.

This revision is now accepted and ready to land.Nov 14 2014, 3:27 PM
olista01 closed this revision.Nov 17 2014, 3:18 AM

Thanks, committed revision 222125.