underlying-objects-2.ll 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. ; RUN: opt -basicaa -loop-accesses -analyze < %s | FileCheck %s
  2. ; This loop:
  3. ;
  4. ; int **A;
  5. ; for (i)
  6. ; for (j) {
  7. ; A[i][j] = A[i-1][j] * B[j]
  8. ; B[j+1] = 2 // backward dep between this and the previous
  9. ; }
  10. ;
  11. ; is transformed by Load-PRE to stash away A[i] for the next iteration of the
  12. ; outer loop:
  13. ;
  14. ; Curr = A[0]; // Prev_0
  15. ; for (i: 1..N) {
  16. ; Prev = Curr; // Prev = PHI (Prev_0, Curr)
  17. ; Curr = A[i];
  18. ; for (j: 0..N) {
  19. ; Curr[j] = Prev[j] * B[j]
  20. ; B[j+1] = 2 // backward dep between this and the previous
  21. ; }
  22. ; }
  23. ;
  24. ; Since A[i] and A[i-1] are likely to be independent, getUnderlyingObjects
  25. ; should not assume that Curr and Prev share the same underlying object.
  26. ;
  27. ; If it did we would try to dependence-analyze Curr and Prev and the analysis
  28. ; would fail with non-constant distance.
  29. ;
  30. ; To illustrate one of the negative consequences of this, if the loop has a
  31. ; backward dependence we won't detect this but instead fully fall back on
  32. ; memchecks (that is what LAA does after encountering a case of non-constant
  33. ; distance).
  34. target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
  35. target triple = "x86_64-apple-macosx10.10.0"
  36. ; CHECK: for_j.body:
  37. ; CHECK-NEXT: Report: unsafe dependent memory operations in loop
  38. ; CHECK-NEXT: Interesting Dependences:
  39. ; CHECK-NEXT: Backward:
  40. ; CHECK-NEXT: %loadB = load i8, i8* %gepB, align 1 ->
  41. ; CHECK-NEXT: store i8 2, i8* %gepB_plus_one, align 1
  42. define void @f(i8** noalias %A, i8* noalias %B, i64 %N) {
  43. for_i.preheader:
  44. %prev_0 = load i8*, i8** %A, align 8
  45. br label %for_i.body
  46. for_i.body:
  47. %i = phi i64 [1, %for_i.preheader], [%i.1, %for_j.end]
  48. %prev = phi i8* [%prev_0, %for_i.preheader], [%curr, %for_j.end]
  49. %gep = getelementptr inbounds i8*, i8** %A, i64 %i
  50. %curr = load i8*, i8** %gep, align 8
  51. br label %for_j.preheader
  52. for_j.preheader:
  53. br label %for_j.body
  54. for_j.body:
  55. %j = phi i64 [0, %for_j.preheader], [%j.1, %for_j.body]
  56. %gepPrev = getelementptr inbounds i8, i8* %prev, i64 %j
  57. %gepCurr = getelementptr inbounds i8, i8* %curr, i64 %j
  58. %gepB = getelementptr inbounds i8, i8* %B, i64 %j
  59. %loadPrev = load i8, i8* %gepPrev, align 1
  60. %loadB = load i8, i8* %gepB, align 1
  61. %mul = mul i8 %loadPrev, %loadB
  62. store i8 %mul, i8* %gepCurr, align 1
  63. %gepB_plus_one = getelementptr inbounds i8, i8* %gepB, i64 1
  64. store i8 2, i8* %gepB_plus_one, align 1
  65. %j.1 = add nuw i64 %j, 1
  66. %exitcondj = icmp eq i64 %j.1, %N
  67. br i1 %exitcondj, label %for_j.end, label %for_j.body
  68. for_j.end:
  69. %i.1 = add nuw i64 %i, 1
  70. %exitcond = icmp eq i64 %i.1, %N
  71. br i1 %exitcond, label %for_i.end, label %for_i.body
  72. for_i.end:
  73. ret void
  74. }