This is an archive of the discontinued LLVM Phabricator instance.

[DependenceAnalysis] Fix for PR21585: collectUpperBound triggers asserts
ClosedPublic

Authored by philip.pfaffe on May 2 2015, 6:08 AM.

Details

Summary

collectUpperBound hits an assertion when the back edge count is wider then the desired type.

If that happens, truncate the backedge count.

Diff Detail

Event Timeline

philip.pfaffe retitled this revision from to [DependenceAnalysis] Fix for PR21585: collectUpperBound triggers asserts.
philip.pfaffe updated this object.
philip.pfaffe edited the test plan for this revision. (Show Details)
philip.pfaffe added reviewers: spop, hfinkel, jingyue.
philip.pfaffe set the repository for this revision to rL LLVM.
philip.pfaffe added a subscriber: Unknown Object (MLST).
jingyue edited edge metadata.May 5 2015, 10:24 AM

LGTM. But I would like Sebastian to confirm this fix doesn't create other issues.

hfinkel added inline comments.May 5 2015, 3:47 PM
lib/Analysis/DependenceAnalysis.cpp
969

I don't understand this; the answer, then, is not actually the upper bound. Why not return some unknown?

LGTM. Btw, here's another test case that exposes the bug, and is fixed by this patch.

; RUN:  opt < %s -analyze -basicaa -da > /dev/null

; Test for a bug, which caused an assert in ScalarEvolution because
; the Dependence Analyzer attempted to zero extend a type to a smaller
; type.

; void t(unsigned int *a, unsigned int n) {
;   for (unsigned int i = 0; i != n; i++) {
;     a[(unsigned short)i] = g;
;  }}

@g = common global i32 0, align 4

define void @t(i32* %a, i32 %n) nounwind {
entry:
  %cmp1 = icmp eq i32 %n, 0
  br i1 %cmp1, label %for.end, label %for.body

for.body:
  %i.02 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
  %0 = load i32, i32* @g, align 4
  %idxprom = and i32 %i.02, 65535
  %arrayidx = getelementptr inbounds i32, i32* %a, i32 %idxprom
  store i32 %0, i32* %arrayidx, align 4
  %inc = add i32 %i.02, 1
  %cmp = icmp eq i32 %inc, %n
  br i1 %cmp, label %for.end, label %for.body

for.end:
  ret void
}
philip.pfaffe edited edge metadata.
philip.pfaffe removed rL LLVM as the repository for this revision.

I agree with hfinkel. Blindly truncating the upper bound leads to wrong dependence results if the subscripts wrap (due to a trip count that is larger than the subscript's type).

I updated the patch to catch this early and treat the wrapping subscripts accordingly, namely by recognizing them as NonLinear. Moreover, I added Brendon's code snippet to the test, as well as two more testcases that produce wrong dependence info when wrapping subscripts are treated as Linear.

I'm open for discussion on whether truncating the upper bound is the most beautiful thing to do here (as apposed to, e.g., zero extending where ever this function is used), or whether it may still lead to wrong results in any other way.

Another test case for strided wrapping.

hfinkel accepted this revision.May 14 2015, 1:18 PM
hfinkel edited edge metadata.

LGTM too (aside from some minor issues below)

lib/Analysis/DependenceAnalysis.cpp
837

Don't need {} here.

863

Don't need {} here.

969

Please add a comment here explaining that cases without nowrap flags should have been rejected earlier.

This revision is now accepted and ready to land.May 14 2015, 1:18 PM
philip.pfaffe edited edge metadata.

Addressed hfinkel's comments. (Plus rebase)