This is an archive of the discontinued LLVM Phabricator instance.

[Polly][ScopDetect] Reject loop with multiple exit blocks.
ClosedPublic

Authored by Meinersbur on Apr 13 2018, 5:43 PM.

Details

Summary

The current statement domain derivation algorithm does not (always) consider that different exit blocks of a loop can have different conditions to be reached.

From the code

  for (int i = n; ; i-=2) {
    if (i <= 0) goto even;
    if (i <= 1) goto odd;
    A[i] = i;
  }
even:
  A[0] = 42;
  return;
odd:
  A[1] = 21;
  return;

Polly currently derives the following domains:

Stmt_even_critedge
    Domain :=
        [n] -> { Stmt_even_critedge[] };
Stmt_odd
    Domain :=
        [n] -> { Stmt_odd[] : (1 + n) mod 2 = 0 and n > 0 };

while the domain for the odd case is correct, Stmt_even is assumed to be executed unconditionally, which is obviously wrong. While projecting out the loop dimension in adjustDomainDimensions, it does not consider that there are other exit condition that have matched before.

I don't know a how to fix this without changing a lot of code. Therefore I suggest to disable multiple loop exits to fix the miscompile of test-suite's uuencode.

The odd condition is transformed by LLVM to %cmp1 = icmp eq i64 %indvars.iv, 1 such that the project_out in adjustDomainDimensions indeed only matches for odd n (using this condition only, we'd have an infinite loop otherwise).

The even condition manifests as %cmp = icmp slt i64 %indvars.iv, 3. Because buildDomainsWithBranchConstraints does not consider other exit conditions, it has to assume that the induction variable will eventually be lower than 3 and taking this exit.

IMHO we need to reuse the algorithm that determines the number of iterations (addLoopBoundsToHeaderDomain) to determine which exit condition applies first. It has to happen in buildDomainsWithBranchConstraints because the result will need to propagate to successor BBs. Currently addLoopBoundsToHeaderDomain just look for union of all backedge conditions (which means leaving not the loop here). The patch in [[ llvm.org/PR35465 | PR35465 ]] changes it to look for exit conditions instead. This is required because there might be other exit conditions that do not alternatively go back to the loop header.

Diff Detail

Repository
rL LLVM

Event Timeline

Meinersbur created this revision.Apr 13 2018, 5:43 PM

Can we reduce the imapct of this by treating all exits which are outside the scop as equivalent?

Can we reduce the imapct of this by treating all exits which are outside the scop as equivalent?

Polly does not support SCoPs with multiple exits (i.e. must be SESE-region to be detected as SCoP).

I thought we had some support for it, somehow? Nevermind, I guess I got it confused with the ErrorBlock thing.

A BasicBlock that, for instance, terminates with a ret or unreachable, Polly cannot recognize as a SCoP even if that block would be considered as an error-block, because RegionInfo does not create a Region for it since it doesn't know about error blocks.

A BasicBlock that, for instance, terminates with a ret or unreachable, Polly cannot recognize as a SCoP even if that block would be considered as an error-block, because RegionInfo does not create a Region for it since it doesn't know about error blocks.

It works for ret blocks with -polly-detect-full-functions.

It works for ret blocks with -polly-detect-full-functions.

The codegen side of this has not been implemented.

grosser accepted this revision.Apr 24 2018, 10:59 PM

LGTM, I am looking into how to clean up the domain generation. Should address this as well. For now disabling is the right approach.

But, can you commit a cleaner test case. This one looks very polluted.

This revision is now accepted and ready to land.Apr 24 2018, 10:59 PM

But, can you commit a cleaner test case. This one looks very polluted.

It is because the debug information is left in, like in the other tests that check the -pass-remarks-missed output. I can craft a smaller one, but it won't check the remark's line location.

Michael

OK, then it's fine.

This revision was automatically updated to reflect the committed changes.