This is an archive of the discontinued LLVM Phabricator instance.

[IndVars] avoid crash in LFTR when assuming an add recurrence
ClosedPublic

Authored by spatel on Apr 26 2021, 5:55 AM.

Details

Summary

The test is a crasher reduced from:
https://llvm.org/PR49993

I don't know IndVars / SCEV well enough to say if this fix is sufficient. Also, I didn't see an obvious recursion limit to explain why we need 10 urem instructions to trigger, but removing any of those avoids the bug.

Diff Detail

Event Timeline

spatel created this revision.Apr 26 2021, 5:55 AM
spatel requested review of this revision.Apr 26 2021, 5:55 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 26 2021, 5:55 AM
lebedev.ri accepted this revision.Apr 26 2021, 6:03 AM

Avoiding assert sounds reasonable to me.

This revision is now accepted and ready to land.Apr 26 2021, 6:03 AM

This patch looks suspiciously like it's fixing a symptom not the cause. The test case in this review does not reproduce for me. However, the original reduced case from the mentioned bug does.

Glancing at the SCEV for the original test before the transform shows that both the phi and the add *are* AddRecExprs. I'd suggest printing the SCEVs at the point of crash to see what might have changed or to better understand how we can match a loop counter - which the example does appear to be - and yet end up with the increment not being an addrec.

Your patch seems like a workaround. I suspect we'll see other problems if the expected pre-conditions to the LFTR method are not met.

To be clear, I'm not opposing a workaround if this is breaking something badly, I just want to make sure we don't stop at the workaround if there's a deeper issue here.

This is what the SCEV looks like: https://gist.github.com/nikic/28415b7c83f1d7599dc6ac1b04da88b3

I believe this is hitting the hasHugeExpression() limit, and thus not folding the +1 into the AddRec. So I think this doesn't indicate a problem from the SCEV side.

However, I think it would be better to bail out in this case in isLoopCounter() already. As written, I think this code is subtly wrong because it will not drop nowrap flags if it's not an AddRec -- we should be dropping them though, as we just don't have any information in this case.

This patch looks suspiciously like it's fixing a symptom not the cause. The test case in this review does not reproduce for me. However, the original reduced case from the mentioned bug does.

Note: I don't disagree with any of the comments and/or reworking this patch, but I'd like to make sure we are seeing the same thing. When you tested locally, did you include a data layout? Without that, I suspect we bail out early without trying any transforms.
The regression test file that I am adding to has:
target datalayout = "n8:16:32:64"

We need the n32 at least to get into trouble in my testing.

spatel updated this revision to Diff 340661.Apr 26 2021, 3:00 PM

Patch updated:
Check for an add recurrence sooner, so we bail out faster.
Also added an assert before the plain cast, so we have a slightly better diagnostic if there's still some other way to get into linearFunctionTestReplace() without an add recurrence.

LGTM to the new version. Please leave out the assert, I really don't think it adds anything, and it's definitely not idiomatic.