Skip to content

[LoopInterchange][DependenceAnalysis] Miscompilation on loops with anti-dependencies #116144

Closed
@mshockwave

Description

@mshockwave

Consider this simple function:

void anti(int *A, int x, unsigned N, unsigned M) {
  for (unsigned m = 0; m < M; ++m)
    for (unsigned i = 0U; i < N - 1; ++i) {
      A[i] = A[i + 1] + x;
    }
}

LoopInterchange currently kicks in on this loop and turns it into:

void anti(int *A, int x, unsigned N, unsigned M) {
  for (unsigned i = 0U; i < N - 1; ++i)
    for (unsigned m = 0; m < M; ++m) {
      A[i] = A[i + 1] + x;
    }
}

Which is apparently wrong.

To further illustrate the problem, one can run the function with this main function:

int main(int argc, char **argv) {
  int A[5] = {1, 2, 3, 4, 5};
  anti(A, argc + 2, 5, 3);

  for (unsigned i = 0U; i < 5; ++i) {
    printf(" %d", A[i]);
  }
  printf("\n");

  return 0;
}

The -O0 program (w/ argc = 1) prints out " 13 14 11 8 5" while the incorrectly interchanged program prints " 5 6 7 8 5", hence the miscompile.


The culprit of this problem comes from DependenceAnalysis, which provides a direction vector (between A[i] & A[i + 1]) of "[S <]" in this case, but I think it really should yield "[S >]" because we have an anti-dependency here. LoopInterchange should be able to stop doing any optimization when it sees "[S >]" as it violates the legality.

CC @sjoerdmeijer @Meinersbur @bmahjour

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions