Preserving lifetime markers isn't as important as allowing promotion, so just drop the lifetime markers if necessary.
This also fixes an assertion failure where other parts of SROA assumed that lifetime markers never block promotion.
Differential D24854
[SROA] Drop lifetime.start/end intrinsics when they block promotion. efriedma on Sep 22 2016, 5:54 PM. Authored by
Details Preserving lifetime markers isn't as important as allowing promotion, so just drop the lifetime markers if necessary. This also fixes an assertion failure where other parts of SROA assumed that lifetime markers never block promotion.
Diff Detail
Event TimelineComment Actions This patch solve the problem I have in the "out of tree" backend I work with. Many thanks! Comment Actions I applied this patch to our codebase and it seems to fix the assertion failure we were seeing in our smaller test cases, thanks! Comment Actions I understand that this fixes an assertion, but it does so by refusing to promote in a case where we can in fact promote. As an alternative, have you looked at teaching the rewrite logic to "fix" (potentially be stripping) the lifetime markers during rewrite to allow the promotion cases? Comment Actions Awesome, I'm glad this was so easy. Tiny nit picks below.
Comment Actions The asan checks make the patch a bit more complicated. Hopefully what I'm doing here makes sense.
Comment Actions I was debugging a testcase reduced from a PS4 title when I realized Eli already provided a fix %myclass = type { [16 x i32] } declare void @llvm.lifetime.start(i64, i8* nocapture) define void @patatino() { %gb = alloca [2 x %myclass*] %tmp = bitcast [2 x %myclass*]* %gb to i8* call void @llvm.lifetime.start(i64 16, i8* %tmp) %tmp1 = getelementptr [2 x %myclass*], [2 x %myclass*]* %gb, i64 0, i64 0 store %myclass* undef, %myclass** %tmp1 %tmp3 = bitcast %myclass** %tmp1 to <4 x i64>* %tmp4 = load <4 x i64>, <4 x i64>* %tmp3 ret void }
Comment Actions In case following the thread is confusing: the suggested approach here may cause false *negatives* for ASan + O2 + stack-use-after-scope. But anything Eli does here otherwise will regress ASan + O2 performance dramatically and fix an unknown number of current false negatives. So I suspect the ASan folks will want to pursue changes here to reduce false negatives in a separate change where you can both avoid the optimization regressions and control enabling these checks to not suddenly expose large numbers of new failures to a check that is already deployed. Comment Actions If this patch can wait a couple of days I can investigate performance regression and amount of exposed false negatives. Comment Actions I would rather go ahead. The false negatives added will be small and rare compared to those we already have IMO. And I think the risk of performance regressions and other things is really quite high. Plus, it would need a great deal more testing than we currently have, mostly around cases which ASan should catch. This patch isn't really about ASan, so it seems better to unblock it and come back and do a comprehensive job with ASan in mind later. Comment Actions I've rerun all out tests with the patch tonight and I see no new reports. Comment Actions If I'm following the conversation correctly, I guess this means I should go ahead and commit https://reviews.llvm.org/D24854?id=73682 (the previous version of the patch)? Comment Actions Yes. I would just remove the bool variable as I indicated in the comment on that revision. LGTM, go ahead and land the patch, and sorry for the back and forth, it wasn't clear to me how fast this would explode into a mess with my original ASan comment. =[ |
This (and the bit below) seems like a really good change, and I can see why you might need to make it in order to make progress. But I think you'll need to split this out into a separate patch.
First, this needs its own test case. It can be pretty boring and just check that asan functions keep lifetime markers and avoid promoting.
But more importantly, this may have really significant knock-on effects for ASan. I just don't know. We should ask the ASan folks to test this and see what it does to things like the performance of ASan-instrumented code. My fear is that it may block *so much* promotion to registers that we actually make ASan unusably slow.
It may be necessary to instead do something much more fancy for ASan: we should instead always promote to a register but synthesize the necessary checks for ASan's use-after-scope directly without relying on memory. If this is something you're interested in playing with, I'm happy to chat with you and the ASan folks about how this might work. Otherwise, I'd suggest sending them this patch as a WIP and they can follow up when it gets to the top of their priorities.
See below for my suggestion on how to make progress in the interim though.