1; RUN: opt -basic-aa -loop-accesses -analyze -enable-new-pm=0 < %s | FileCheck %s
2; RUN: opt -passes='require<aa>,require<scalar-evolution>,require<aa>,loop(print-access-info)' -aa-pipeline='basic-aa' -disable-output < %s  2>&1 | FileCheck %s
3
4target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
5target triple = "x86_64-apple-macosx10.10.0"
6
7; TODO: Loop iteration counts are only required if we generate memory
8;       runtime checks. Missing iteration counts should not prevent
9;       analysis, if no runtime checks are required.
10
11; No memory checks are required, because base pointers do not alias and we have
12; a forward dependence for %a.
13define void @safe_forward_dependence(i16* noalias %a,
14                                     i16* noalias %b) {
15; CHECK-LABEL: safe_forward_dependence
16; CHECK:       for.body:
17; CHECK-NEXT:     Report: could not determine number of loop iterations
18;
19entry:
20  br label %for.body
21
22for.body:                                         ; preds = %for.body, %entry
23  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
24
25  %iv.next = add nuw nsw i64 %iv, 1
26
27  %arrayidxA_plus_2 = getelementptr inbounds i16, i16* %a, i64 %iv.next
28  %loadA_plus_2 = load i16, i16* %arrayidxA_plus_2, align 2
29
30  %arrayidxB = getelementptr inbounds i16, i16* %b, i64 %iv
31  %loadB = load i16, i16* %arrayidxB, align 2
32
33
34  %mul = mul i16 %loadB, %loadA_plus_2
35
36  %arrayidxA = getelementptr inbounds i16, i16* %a, i64 %iv
37  store i16 %mul, i16* %arrayidxA, align 2
38
39  %exitcond = icmp eq i16 %loadB, 20
40  br i1 %exitcond, label %for.end, label %for.body
41
42for.end:                                          ; preds = %for.body
43  ret void
44}
45
46
47
48
49define void @unsafe_backwards_dependence(i16* noalias %a,
50                                         i16* noalias %b) {
51; CHECK-LABEL: unsafe_backwards_dependence
52; CHECK:       for.body:
53; CHECK-NEXT:     Report: could not determine number of loop iterations
54;
55entry:
56  br label %for.body
57
58for.body:                                         ; preds = %for.body, %entry
59  %iv = phi i64 [ 1, %entry ], [ %iv.next, %for.body ]
60
61  %idx = add nuw nsw i64 %iv, -1
62  %iv.next = add nuw nsw i64 %iv, 1
63
64  %arrayidxA_plus_2 = getelementptr inbounds i16, i16* %a, i64 %idx
65  %loadA_plus_2 = load i16, i16* %arrayidxA_plus_2, align 2
66
67  %arrayidxB = getelementptr inbounds i16, i16* %b, i64 %iv
68  %loadB = load i16, i16* %arrayidxB, align 2
69
70
71  %mul = mul i16 %loadB, %loadA_plus_2
72
73  %arrayidxA = getelementptr inbounds i16, i16* %a, i64 %iv
74  store i16 %mul, i16* %arrayidxA, align 2
75
76  %exitcond = icmp eq i16 %loadB, 20
77  br i1 %exitcond, label %for.end, label %for.body
78
79for.end:                                          ; preds = %for.body
80  ret void
81}
82
83
84define void @ptr_may_alias(i16* %a, i16* %b) {
85; CHECK-LABEL: ptr_may_alias
86; CHECK:       for.body:
87; CHECK-NEXT:     Report: could not determine number of loop iterations
88;
89entry:
90  br label %for.body
91
92for.body:                                         ; preds = %for.body, %entry
93  %iv = phi i64 [ 1, %entry ], [ %iv.next, %for.body ]
94
95  %idx = add nuw nsw i64 %iv, -1
96  %iv.next = add nuw nsw i64 %iv, 1
97
98  %arrayidxA = getelementptr inbounds i16, i16* %a, i64 %iv
99  %loadA = load i16, i16* %arrayidxA, align 2
100
101  %arrayidxB = getelementptr inbounds i16, i16* %b, i64 %iv
102  %loadB = load i16, i16* %arrayidxB, align 2
103
104  %mul = mul i16 %loadB, %loadA
105
106  store i16 %mul, i16* %arrayidxA, align 2
107
108  %exitcond = icmp eq i16 %loadB, 20
109  br i1 %exitcond, label %for.end, label %for.body
110
111for.end:                                          ; preds = %for.body
112  ret void
113}
114