This is an archive of the discontinued LLVM Phabricator instance.

[SCEV] Removed an unnecessary assertion in SCEV.
ClosedPublic

Authored by Yangguang on Mar 31 2022, 10:20 AM.

Details

Summary

The assertion in computeExitLimitFromCondFromBinOp() is meant to check that when the the exit condition is in select form, we would always return a backedge taken count of zero (BECount->isZero()) if the exit limit for the first operand is zero (EL0.ExactNotTaken->isZero()).

If the exit condition is in AND/OR form, it is okay to return BECount as Umin(EL0.ExactNotTaken, EL1.ExactNotTaken) since AND/OR is poison-safe. This is not the case if the the exit condition is in select form.

So the correct assertion is the following

assert(isa<BinaryOperator>(ExitCond) || !EL0.ExactNotTaken->isZero() ||
             BECount->isZero());

which means if ExitCond is in AND/OR form, nothing needs to be checked further. Otherwise (it is in select form), and we will need to return a backedge taken count of zero if the exit limit for the first operand is zero.

With the current assert, if if ExitCond is in select form, the condition in the assert always returns true due to !isa<BinaryOperator>(ExitCond) and the check for !EL0.ExactNotTaken->isZero() || BECount->isZero()) is never triggerred, which is not what the assert meant to be.

Dropping the first check so the assertion cover ExitCond in both AND/OR form and select form.


As suggested in the comment I removed the whole assertion since the select form is handled in ScalarEvolution::getSequentialMinMaxExpr.

Diff Detail

Event Timeline

Yangguang created this revision.Mar 31 2022, 10:20 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 31 2022, 10:20 AM
Herald added a subscriber: hiraditya. · View Herald Transcript
Yangguang requested review of this revision.Mar 31 2022, 10:20 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 31 2022, 10:20 AM
Yangguang edited the summary of this revision. (Show Details)Mar 31 2022, 10:23 AM
Yangguang edited the summary of this revision. (Show Details)Mar 31 2022, 11:12 AM
Yangguang added reviewers: aqjune, lebedev.ri.
congzhe edited the summary of this revision. (Show Details)Mar 31 2022, 11:33 AM

Test?

I can't create a test that fails the original assertion. When the ExitCond is NOT a BinaryOperator (which means it's in select form/short-circuit form), the original assert will always pass and we won't need to do the next two checks. But according to the comment above the assertion and the original design for the assertion, we should be checking the next two conditions when the ExitCond is in select form. I updated the summary, please refer for more info.

Test?

I can't create a test that fails the original assertion. When the ExitCond is NOT a BinaryOperator (which means it's in select form/short-circuit form), the original assert will always pass and we won't need to do the next two checks. But according to the comment above the assertion and the original design for the assertion, we should be checking the next two conditions when the ExitCond is in select form. I updated the summary, please refer for more info.

I mean the test on which the unfixed assertion fires.
Though, i suspect that the assertion is still wrong, and the fix should be to just drop the !isa<BinaryOperator>(ExitCond) || part.

Yangguang updated this revision to Diff 419849.Apr 1 2022, 1:38 PM
Yangguang edited the summary of this revision. (Show Details)

Test?

I can't create a test that fails the original assertion. When the ExitCond is NOT a BinaryOperator (which means it's in select form/short-circuit form), the original assert will always pass and we won't need to do the next two checks. But according to the comment above the assertion and the original design for the assertion, we should be checking the next two conditions when the ExitCond is in select form. I updated the summary, please refer for more info.

I mean the test on which the unfixed assertion fires.
Though, i suspect that the assertion is still wrong, and the fix should be to just drop the !isa<BinaryOperator>(ExitCond) || part.

Fixed as suggested and changed the comment accordingly. Please check if it make sense.

This seems correct to me, but any chance for a test?

This seems correct to me, but any chance for a test?

Whenever EL0.ExactNotTaken==0, getUMinFromMismatchedTypes() will always return 0 for BECount. I don't see a way to generate a test case that fires the assertion.
But since ExitCond in AND/OR form is now also covered by the assertion, do you think it's helpful to have a test case in which ExitCond is in AND/OR form and won't fire the assertion when EL0.ExactNotTaken==0? (Note: we already have similar test case for ExitCond in select form under llvm\test\Analysis\ScalarEvolution\exit-count-select.ll.)

This seems correct to me, but any chance for a test?

Whenever EL0.ExactNotTaken==0, getUMinFromMismatchedTypes() will always return 0 for BECount. I don't see a way to generate a test case that fires the assertion.
But since ExitCond in AND/OR form is now also covered by the assertion, do you think it's helpful to have a test case in which ExitCond is in AND/OR form and won't fire the assertion when EL0.ExactNotTaken==0? (Note: we already have similar test case for ExitCond in select form under llvm\test\Analysis\ScalarEvolution\exit-count-select.ll.)

@lebedev.ri What do you think of the idea of adding test case for AND/OR form that is also covered by the assertion after change?

@aqjune Could you help review this patch? The original assertion is wrong because it won't fire when ExitCond is in select form, the exit limit for the first operand is zero, and the backedge taken count is NOT zero. This patch fix the assertion and make it cover the case for AND/OR form as well.

@nikic @mkazantsev @reames Could you please help review the patch. Any feedback would be appreciated.

nikic added a comment.May 2 2022, 1:47 PM

I think you can just delete the whole assertion. The invariant it checks is no longer relevant now that we have umin_seq nodes.

Hi, sorry for my delay. The old assertion seems problematic.

+1 for totally removing the assertion as well, because in the select case the Sequential flag must be set, calling ScalarEvolution::getSequentialMinMaxExpr at last. The assert condition was for dealing with select form however.
Also, the condition (3) even seems to be removed now; originally it was introduced here: D93882, but now gone.

reames accepted this revision.May 3 2022, 12:53 PM

LGTM, the simplified assert looks correct to me. Removing complexity which is no longer needed is always good.

This revision is now accepted and ready to land.May 3 2022, 12:53 PM
Yangguang updated this revision to Diff 426809.May 3 2022, 12:54 PM
Yangguang retitled this revision from [SCEV] Fix a bug that caused an invalid assertion. to [SCEV] Remove an invalid assertion in SCEV..
Yangguang edited the summary of this revision. (Show Details)

Removed the whole assertion as suggested.

LGTM, the simplified assert looks correct to me. Removing complexity which is no longer needed is always good.

Sorry, I just deleted the whole assertion as suggested by the reviews. Just right after you accepted the patch. Could you please double check if the correct version is accepted?

nikic accepted this revision.May 3 2022, 1:03 PM

LG

nikic added a comment.May 3 2022, 1:04 PM

Though for the title, I'd suggest invalid -> unnecessary. The assertion itself is fine, there's just no reason to check it here.

reames added a comment.May 3 2022, 1:09 PM

My LGTM specifically applied to the prior version of the patch. I do see value in the assert, and would prefer that version I don't feel strongly about this, so feel free to land on nikic's LG.

Yangguang retitled this revision from [SCEV] Remove an invalid assertion in SCEV. to [SCEV] Removed an unnecessary assertion in SCEV..May 3 2022, 1:17 PM

Though for the title, I'd suggest invalid -> unnecessary. The assertion itself is fine, there's just no reason to check it here.

Thanks! Fixed as suggested.

My LGTM specifically applied to the prior version of the patch. I do see value in the assert, and would prefer that version I don't feel strongly about this, so feel free to land on nikic's LG.

Thanks for the feedback!

This revision was landed with ongoing or failed builds.May 3 2022, 2:26 PM
This revision was automatically updated to reflect the committed changes.