This is an archive of the discontinued LLVM Phabricator instance.

[SCEV][IndVars][WIP] Check outer loop invariant when cononicalize comparision
AbandonedPublic

Authored by StephenFan on Feb 27 2023, 4:19 AM.

Details

Summary

Before this patch, In SimplifyICmpOperands, the comparision would be cononicalized and the NUW
flag would be added if the loop is finite. The reason is as the comments
says, "since the loop is finite, the bound cannot include the corresponding
boundary (otherwise it would loop forever)." But the NUW flag that be added
also assumes the SCEV that this flag attaches is also NUW in outer loops.
It makes some transformations like IndVars eliminating comparisions
that shouldn' t been eliminated.

Fixes: https://github.com/llvm/llvm-project/issues/60944

I am new to ScalarEvolution. So I am not sure if it is a right fix.

Diff Detail

Event Timeline

StephenFan created this revision.Feb 27 2023, 4:19 AM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 27 2023, 4:19 AM
StephenFan requested review of this revision.Feb 27 2023, 4:19 AM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 27 2023, 4:19 AM
nikic requested changes to this revision.Feb 27 2023, 5:51 AM

It would be easier to say with a reduced test case, but this is very likely not the right fix. SCEV nowrap flags must hold unconditionally (i.e., on any well-defined execution, nowrap flags must hold at any point where the SCEV expression is defined). In this context, we only know that the expression does not wrap at that particular use. We should not be setting the flag in this case.

Though I think we should just revert D118090 entirely. It also has a number of regressions reported on the review, and together with this issue, I think it's best to revert.

llvm/test/Transforms/IndVarSimplify/pr60944.ll
1

Please reduce the test case.

This revision now requires changes to proceed.Feb 27 2023, 5:51 AM

If it’s possible to not revert that would be preferable as @jdoefert @vchuravy I and others have many applications that would have significant slow down if reverted.

From my analysis of the testcase, we called "getAddExpr(SCEV::FlagNUW)" while analyzing the first loop, and that broke the analysis of the second loop. The actual simplification isn't relevant.

From my analysis of the testcase, we called "getAddExpr(SCEV::FlagNUW)" while analyzing the first loop, and that broke the analysis of the second loop. The actual simplification isn't relevant.

Sorry, I don't know what you mean by "The actual simplification isn't relevant". Would you mind explaining a little more?

nikic added a comment.Mar 1 2023, 12:10 AM

If it’s possible to not revert that would be preferable as @jdoefert @vchuravy I and others have many applications that would have significant slow down if reverted.

The change also caused significant slowdowns for multiple other people, which were never addressed (e.g. https://github.com/llvm/llvm-project/issues/54191). Combined with this issue, that's enough for a revert for me.

From my analysis of the testcase, we called "getAddExpr(SCEV::FlagNUW)" while analyzing the first loop, and that broke the analysis of the second loop. The actual simplification isn't relevant.

Sorry, I don't know what you mean by "The actual simplification isn't relevant". Would you mind explaining a little more?

The getAddExpr() with NUW flag sets this flag globally, for all uses of this add. The icmp simplification itself doesn't make a difference, just the side effect that the (not globally correct) nuw flag is set.

If we don't want to revert the patch, the right fix would be to not set the NUW flag in the ControllingFiniteLoop case.

! In D144861#4160179, @efriedma wrote:
From my analysis of the testcase, we called "getAddExpr(SCEV::FlagNUW)" while analyzing the first loop, and that broke the analysis of the second loop. The actual simplification isn't relevant.

Sorry, I don't know what you mean by "The actual simplification isn't relevant". Would you mind explaining a little more?

The getAddExpr() with NUW flag sets this flag globally, for all uses of this add. The icmp simplification itself doesn't make a difference, just the side effect that the (not globally correct) nuw flag is set.

Thanks for your explanation!

nikic added a comment.Mar 7 2023, 8:26 AM

I've posted https://reviews.llvm.org/D145510 as an alternative patch, which hopefully resolves all the issues with the current implementation.

StephenFan abandoned this revision.Mar 8 2023, 12:55 AM

I've posted https://reviews.llvm.org/D145510 as an alternative patch, which hopefully resolves all the issues with the current implementation.

Thanks!