This is an archive of the discontinued LLVM Phabricator instance.

remove inalloca parameters in globalopt and simplify argpromotion
ClosedPublic

Authored by inglorion on Apr 29 2019, 4:56 PM.

Details

Summary

Inalloca parameters require special handling in some optimizations.
This change causes globalopt to strip the inalloca attribute from
function parameters when it is safe to do so, removes the special
handling for inallocas from argpromotion, and replaces it with a
simple check that causes argpromotion to skip functions that receive
inallocas (for when the pass is invoked on code that didn't run
through globalopt first). This also avoids a case where argpromotion
would incorrectly try to pass an inalloca in a register.

Fixes PR41658.

Diff Detail

Repository
rL LLVM

Event Timeline

inglorion created this revision.Apr 29 2019, 4:56 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 29 2019, 4:56 PM
Herald added a subscriber: hiraditya. · View Herald Transcript

Eli, I saw after I wrote this that you suggested a slightly different approach on the bug (skip argpromote for functions with inallocas). If you'd rather have me do that instead of the change here, I'd be happy to. I just figured I'd put up the one I had already written for consideration.

Special-casing x86_thiscall seems too narrow; there are other x86 calling conventions that place arguments in registers, so I'm not confident this covers all the cases we care about. Scanning for an inalloca argument should comprehensively cover all the relevant cases.

Alternatively, we could change the x86 calling convention code to make the result valid (if an argument is marked inalloca, force it into memory even if it's in an unexpected position in the argument list).

inglorion retitled this revision from [argpromotion] reserve first argument of x86_thiscallcc functions to Skip functions with inallocas in argpromotion.
inglorion edited the summary of this revision. (Show Details)
inglorion removed a subscriber: efriedma.

Updated in response to @efriedma's comments. We now don't run
argpromotion on functions with inallocas. I've deleted some code
(mostly comments) that refers to them, and modified the test
which previously checked that we do perform the optimization in some
cases to instead check that we don't perform the optimization in
the case I found to be unsafe.

rnk added a comment.Apr 30 2019, 11:53 AM

Now that I see we already had an optimization for inalloca, I'm hesitant to lose it. I think there's a simple fix, though. We can just remove inalloca in any situation where we could do argument promotion.

Hoisting the dynamic alloca to the entry block and stripping the inalloca marker off of it are also nice improvements, but they aren't necessary for correctness.

llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
152 ↗(On Diff #197383)

I think the simplest fix that preserves the existing optimization would be to strip off inalloca from the parameter and argument attributes. I think it's just a matter of pulling off inalloca here, and on the call site.

255–257 ↗(On Diff #197383)

This is where you would remove inalloca from the call site attribute list.

Optionally, if inalloca was present and you are removing it, you could check if the value passed into the call site is a pointer to a dynamic alloca marked inalloca, and if so turn it into a static alloca by stripping the inalloca marker and hoisting it to the entry block. That's not necessary for correctness, though.

Yeah, I kind of wanted to do the least intrusive thing that would fix the problem I observed and then think about the larger picture. But given that we're thinking about removing the inalloca attribute, the way I would like to do that is remove it in globalopt and then we can perform further optimizations (in globalopt and here) predicated on no inalloca being present. That takes care of half the FIXME for inalloca in globalopt, so after that it becomes really tempting to do follow-up with the other half and hoist the alloca to the entry block.

rnk added a comment.Apr 30 2019, 2:40 PM

Yeah, I kind of wanted to do the least intrusive thing that would fix the problem I observed and then think about the larger picture. But given that we're thinking about removing the inalloca attribute, the way I would like to do that is remove it in globalopt and then we can perform further optimizations (in globalopt and here) predicated on no inalloca being present. That takes care of half the FIXME for inalloca in globalopt, so after that it becomes really tempting to do follow-up with the other half and hoist the alloca to the entry block.

I approve of this plan to do the removal in globalopt and make the later passes more conservative around inalloca. :)

llvm/test/Transforms/ArgumentPromotion/inalloca.ll
1–2 ↗(On Diff #197383)

I would say, keep this test case as is, but once you've improved globalopt, test that the combination of globalopt + argpromotion + sroa is able to do this transform successfully. It's a bit of an integration test, but we need a few of those than we have today anyway.

inglorion updated this revision to Diff 197629.May 1 2019, 1:32 PM
inglorion retitled this revision from Skip functions with inallocas in argpromotion to remove inalloca parameters in globalopt and simplify argpromotion.
inglorion edited the summary of this revision. (Show Details)
inglorion edited reviewers, added: efriedma; removed: eli.friedman.
inglorion removed a subscriber: hiraditya.

Remove inallocas in globalopt and simplify argpromotion by just
bailing on inallocas.

Tests verify that the optimizations we previously performed are still
performed when both globalopt and argpromotion run.

inglorion updated this revision to Diff 197635.May 1 2019, 2:00 PM

Correcting earlier upload to preserve original inalloca.ll tests and
add new tests in a separate file.

rnk accepted this revision.May 1 2019, 2:12 PM

lgtm, thanks for the improvement and simplification.

This revision is now accepted and ready to land.May 1 2019, 2:12 PM
This revision was automatically updated to reflect the committed changes.