1 ; RUN: opt -loop-accesses -analyze -enable-new-pm=0 < %s | FileCheck %s
2 ; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output < %s 2>&1 | FileCheck %s
4 %s1 = type { [32000 x double], [32000 x double], [32000 x double] }
6 define i32 @load_with_pointer_phi_no_runtime_checks(%s1* %data) {
7 ; CHECK-LABEL: load_with_pointer_phi_no_runtime_checks
8 ; CHECK-NEXT: loop.header:
9 ; CHECK-NEXT: Report: cannot identify array bounds
14 loop.header: ; preds = %loop.latch, %entry
15 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
16 %iv.next = add nuw nsw i64 %iv, 1
17 %cmp5 = icmp ult i64 %iv, 15999
18 %arrayidx = getelementptr inbounds %s1, %s1 * %data, i64 0, i32 0, i64 %iv
19 br i1 %cmp5, label %if.then, label %if.else
21 if.then: ; preds = %loop.header
22 %gep.1 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 1, i64 %iv
25 if.else: ; preds = %loop.header
26 %gep.2 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 2, i64 %iv
29 loop.latch: ; preds = %if.else, %if.then
30 %gep.2.sink = phi double* [ %gep.2, %if.else ], [ %gep.1, %if.then ]
31 %v8 = load double, double* %gep.2.sink, align 8
32 %mul16 = fmul double 3.0, %v8
33 store double %mul16, double* %arrayidx, align 8
34 %exitcond.not = icmp eq i64 %iv.next, 32000
35 br i1 %exitcond.not, label %exit, label %loop.header
37 exit: ; preds = %loop.latch
41 define i32 @store_with_pointer_phi_no_runtime_checks(%s1* %data) {
42 ; CHECK-LABEL: 'store_with_pointer_phi_no_runtime_checks'
43 ; CHECK-NEXT: loop.header:
44 ; CHECK-NEXT: Report: cannot identify array bounds
49 loop.header: ; preds = %loop.latch, %entry
50 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
51 %iv.next = add nuw nsw i64 %iv, 1
52 %cmp5 = icmp ult i64 %iv, 15999
53 %arrayidx = getelementptr inbounds %s1, %s1 * %data, i64 0, i32 0, i64 %iv
54 br i1 %cmp5, label %if.then, label %if.else
56 if.then: ; preds = %loop.header
57 %gep.1 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 1, i64 %iv
60 if.else: ; preds = %loop.header
61 %gep.2 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 2, i64 %iv
64 loop.latch: ; preds = %if.else, %if.then
65 %gep.2.sink = phi double* [ %gep.2, %if.else ], [ %gep.1, %if.then ]
66 %v8 = load double, double* %arrayidx, align 8
67 %mul16 = fmul double 3.0, %v8
68 store double %mul16, double* %gep.2.sink, align 8
69 %exitcond.not = icmp eq i64 %iv.next, 32000
70 br i1 %exitcond.not, label %exit, label %loop.header
72 exit: ; preds = %loop.latch
76 define i32 @store_with_pointer_phi_runtime_checks(double* %A, double* %B, double* %C) {
77 ; CHECK-LABEL: 'store_with_pointer_phi_runtime_checks'
78 ; CHECK-NEXT: loop.header:
79 ; CHECK-NEXT: Report: cannot identify array bounds
84 loop.header: ; preds = %loop.latch, %entry
85 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
86 %iv.next = add nuw nsw i64 %iv, 1
87 %cmp5 = icmp ult i64 %iv, 15999
88 %arrayidx = getelementptr inbounds double, double* %A, i64 %iv
89 br i1 %cmp5, label %if.then, label %if.else
91 if.then: ; preds = %loop.header
92 %gep.1 = getelementptr inbounds double, double* %B, i64 %iv
95 if.else: ; preds = %loop.header
96 %gep.2 = getelementptr inbounds double, double* %C, i64 %iv
99 loop.latch: ; preds = %if.else, %if.then
100 %gep.2.sink = phi double* [ %gep.2, %if.else ], [ %gep.1, %if.then ]
101 %v8 = load double, double* %arrayidx, align 8
102 %mul16 = fmul double 3.0, %v8
103 store double %mul16, double* %gep.2.sink, align 8
104 %exitcond.not = icmp eq i64 %iv.next, 32000
105 br i1 %exitcond.not, label %exit, label %loop.header
107 exit: ; preds = %loop.latch
111 define i32 @load_with_pointer_phi_outside_loop(double* %A, double* %B, double* %C, i1 %c.0, i1 %c.1) {
112 ; CHECK-LABEL: 'load_with_pointer_phi_outside_loop'
113 ; CHECK-NEXT: loop.header:
114 ; CHECK-NEXT: Report: unsafe dependent memory operations in loop
115 ; CHECK-NEXT: Dependences:
116 ; CHECK-NEXT: Unknown:
117 ; CHECK-NEXT: %v8 = load double, double* %ptr, align 8 ->
118 ; CHECK-NEXT: store double %mul16, double* %arrayidx, align 8
121 br i1 %c.0, label %if.then, label %if.else
127 %ptr.select = select i1 %c.1, double* %C, double* %B
131 %ptr = phi double* [ %A, %if.then ], [ %ptr.select, %if.else ]
132 br label %loop.header
134 loop.header: ; preds = %loop.latch, %entry
135 %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop.header ]
136 %iv.next = add nuw nsw i64 %iv, 1
137 %arrayidx = getelementptr inbounds double, double* %A, i64 %iv
138 %v8 = load double, double* %ptr, align 8
139 %mul16 = fmul double 3.0, %v8
140 store double %mul16, double* %arrayidx, align 8
141 %exitcond.not = icmp eq i64 %iv.next, 32000
142 br i1 %exitcond.not, label %exit, label %loop.header
144 exit: ; preds = %loop.latch
148 define i32 @store_with_pointer_phi_outside_loop(double* %A, double* %B, double* %C, i1 %c.0, i1 %c.1) {
149 ; CHECK-LABEL: 'store_with_pointer_phi_outside_loop'
150 ; CHECK-NEXT: loop.header:
151 ; CHECK-NEXT: Report: unsafe dependent memory operations in loop.
152 ; CHECK-NEXT: Dependences:
153 ; CHECK-NEXT: Unknown:
154 ; CHECK-NEXT: %v8 = load double, double* %arrayidx, align 8 ->
155 ; CHECK-NEXT: store double %mul16, double* %ptr, align 8
158 br i1 %c.0, label %if.then, label %if.else
164 %ptr.select = select i1 %c.1, double* %C, double* %B
168 %ptr = phi double* [ %A, %if.then ], [ %ptr.select, %if.else ]
169 br label %loop.header
171 loop.header: ; preds = %loop.latch, %entry
172 %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop.header ]
173 %iv.next = add nuw nsw i64 %iv, 1
174 %arrayidx = getelementptr inbounds double, double* %A, i64 %iv
175 %v8 = load double, double* %arrayidx, align 8
176 %mul16 = fmul double 3.0, %v8
177 store double %mul16, double* %ptr, align 8
178 %exitcond.not = icmp eq i64 %iv.next, 32000
179 br i1 %exitcond.not, label %exit, label %loop.header
181 exit: ; preds = %loop.latch