This is an archive of the discontinued LLVM Phabricator instance.

[ARM] Fix large stack alignment codegen bug for ARM and Thumb2 targets
ClosedPublic

Authored by kristof.beyls on Jan 5 2015, 7:52 AM.

Details

Summary

This patch partially fixes PR13007 (ARM CodeGen fails with large
stack alignment): for ARM and Thumb2 targets, but not for Thumb1,
as it seems stack alignment for Thumb1 targets hasn't been
supported at all.

Producing an aligned stack pointer is done by zero-ing out the lower
bits of the stack pointer. The BIC instruction was used for this.
However, the immediate field of the BIC instruction only allows to
encode an immediate that can zero out up to a maximum of the 8 lower
bits. When a larger alignment is requested, a BIC instruction cannot
be used; llvm was silently producing incorrect code in this case.

This patch fixes code generation for large stack aligments by using
the BFC instruction instead, when the BFC instruction is available.
When not, it uses 2 instructions: a right shift, followed by a left
shift to zero out the lower bits.

The lowering of ARM::Int_eh_sjlj_dispatchsetup still has code
that unconditionally uses BIC to realign the stack pointer, so it
very likely has the same problem. However, I haven't been able to
produce a test case for that. Does anyone understand sjlj exception
handling well enough to produce a test case triggering the bug on
the FIXME I've added in ARMExpandPseudoInsts.cpp?

Please review!

Thanks,

Kristof

Diff Detail

Event Timeline

kristof.beyls retitled this revision from to [ARM] Fix large stack alignment codegen bug for ARM and Thumb2 targets.
kristof.beyls updated this object.
kristof.beyls edited the test plan for this revision. (Show Details)
kristof.beyls added a reviewer: t.p.northover.
kristof.beyls set the repository for this revision to rL LLVM.
kristof.beyls added a subscriber: Unknown Object (MLST).
jmolloy requested changes to this revision.Jan 7 2015, 2:50 AM
jmolloy added a reviewer: jmolloy.
jmolloy added a subscriber: jmolloy.

Hi Kristof,

Thanks for working on this. Comments inline.

Cheers,

James

lib/Target/ARM/ARMExpandPseudoInsts.cpp
890

I'd turn this FIXME into an assert. Then, you may end up with some buildbot providing you with a test case!

Either way, it's a silent fault so let's fail hard.

lib/Target/ARM/ARMFrameLowering.cpp
214

Doc comments should use three slashes (///)

225

Might be worth mentioning in the doc comment whether Alignment is expected to be M or N in:

M = 1 << N.

226

Coding style: MustBeSingleInstruction.

228

CanUseBFC

231

... && "Thumb1 alignment not supported!") or something

252

Where's the guarantee that we can't trigger this assertion in normal operation? If we can't use BFC, and AlignMask is > 255? Is this expected to happen?

If not, please add a "&& "Reason!"" to the assert.

1149–1154

Please write comments in full sentences: "We must set the parameter..."

This revision now requires changes to proceed.Jan 7 2015, 2:50 AM
kristof.beyls edited edge metadata.
kristof.beyls removed rL LLVM as the repository for this revision.

Thanks James, I've updated the patch taking into account your review comments.
The only comment I didn't make a change for is commenting whether Alignment is a log2 value or not, as I feel that that documentation would be overkill - it isn't a log2 value and it should be clear from the context it isn't.

One other coding-style issue.

lib/Target/ARM/ARMFrameLowering.cpp
231

Coding style: should be NrBitsToZero

kristof.beyls edited edge metadata.

Thanks for noticing Charlie - now fixed in updated patch.

jmolloy accepted this revision.Jan 8 2015, 2:09 AM
jmolloy edited edge metadata.

Hi Kristof,

LGTM now.

Cheers,

James

This revision is now accepted and ready to land.Jan 8 2015, 2:09 AM