1; RUN: opt -loop-vectorize -force-vector-width=2 -S %s | FileCheck %s
2
3%s1 = type { [32000 x double], [32000 x double], [32000 x double] }
4
5define i32 @load_with_pointer_phi_no_runtime_checks(%s1* %data) {
6; CHECK-LABEL: @load_with_pointer_phi_no_runtime_checks
7; CHECK-NOT: vector.body
8;
9entry:
10  br label %loop.header
11
12loop.header:                                        ; preds = %loop.latch, %entry
13  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
14  %iv.next = add nuw nsw i64 %iv, 1
15  %cmp5 = icmp ult i64 %iv, 15999
16  %arrayidx = getelementptr inbounds %s1, %s1 * %data, i64 0, i32 0, i64 %iv
17  br i1 %cmp5, label %if.then, label %if.else
18
19if.then:                                          ; preds = %loop.header
20  %gep.1 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 1, i64 %iv
21  br label %loop.latch
22
23if.else:                                          ; preds = %loop.header
24  %gep.2 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 2, i64 %iv
25  br label %loop.latch
26
27loop.latch:                                          ; preds = %if.else, %if.then
28  %gep.2.sink = phi double* [ %gep.2, %if.else ], [ %gep.1, %if.then ]
29  %v8 = load double, double* %gep.2.sink, align 8
30  %mul16 = fmul double 3.0, %v8
31  store double %mul16, double* %arrayidx, align 8
32  %exitcond.not = icmp eq i64 %iv.next, 32000
33  br i1 %exitcond.not, label %exit, label %loop.header
34
35exit:                                             ; preds = %loop.latch
36  ret i32 10
37}
38
39define i32 @store_with_pointer_phi_no_runtime_checks(%s1* %data) {
40; CHECK-LABEL: @store_with_pointer_phi_no_runtime_checks
41; CHECK-NOT: vector.body
42;
43entry:
44  br label %loop.header
45
46loop.header:                                        ; preds = %loop.latch, %entry
47  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
48  %iv.next = add nuw nsw i64 %iv, 1
49  %cmp5 = icmp ult i64 %iv, 15999
50  %arrayidx = getelementptr inbounds %s1, %s1 * %data, i64 0, i32 0, i64 %iv
51  br i1 %cmp5, label %if.then, label %if.else
52
53if.then:                                          ; preds = %loop.header
54  %gep.1 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 1, i64 %iv
55  br label %loop.latch
56
57if.else:                                          ; preds = %loop.header
58  %gep.2 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 2, i64 %iv
59  br label %loop.latch
60
61loop.latch:                                          ; preds = %if.else, %if.then
62  %gep.2.sink = phi double* [ %gep.2, %if.else ], [ %gep.1, %if.then ]
63  %v8 = load double, double* %arrayidx, align 8
64  %mul16 = fmul double 3.0, %v8
65  store double %mul16, double* %gep.2.sink, align 8
66  %exitcond.not = icmp eq i64 %iv.next, 32000
67  br i1 %exitcond.not, label %exit, label %loop.header
68
69exit:                                             ; preds = %loop.latch
70  ret i32 10
71}
72
73define i32 @store_with_pointer_phi_runtime_checks(double* %A, double* %B, double* %C) {
74; CHECK-LABEL: @store_with_pointer_phi_runtime_checks
75; CHECK-NOT: vector.body
76;
77entry:
78  br label %loop.header
79
80loop.header:                                        ; preds = %loop.latch, %entry
81  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
82  %iv.next = add nuw nsw i64 %iv, 1
83  %cmp5 = icmp ult i64 %iv, 15999
84  %arrayidx = getelementptr inbounds double, double* %A, i64 %iv
85  br i1 %cmp5, label %if.then, label %if.else
86
87if.then:                                          ; preds = %loop.header
88  %gep.1 = getelementptr inbounds double, double* %B, i64 %iv
89  br label %loop.latch
90
91if.else:                                          ; preds = %loop.header
92  %gep.2 = getelementptr inbounds double, double* %C, i64 %iv
93  br label %loop.latch
94
95loop.latch:                                          ; preds = %if.else, %if.then
96  %gep.2.sink = phi double* [ %gep.2, %if.else ], [ %gep.1, %if.then ]
97  %v8 = load double, double* %arrayidx, align 8
98  %mul16 = fmul double 3.0, %v8
99  store double %mul16, double* %gep.2.sink, align 8
100  %exitcond.not = icmp eq i64 %iv.next, 32000
101  br i1 %exitcond.not, label %exit, label %loop.header
102
103exit:                                             ; preds = %loop.latch
104  ret i32 10
105}
106
107define i32 @load_with_pointer_phi_outside_loop(double* %A, double* %B, double* %C, i1 %c.0, i1 %c.1) {
108; CHECK-LABEL: @load_with_pointer_phi_outside_loop
109; CHECK-NOT: vector.body
110;
111entry:
112  br i1 %c.0, label %if.then, label %if.else
113
114if.then:
115  br label %loop.ph
116
117if.else:
118  %ptr.select = select i1 %c.1, double* %C, double* %B
119  br label %loop.ph
120
121loop.ph:
122  %ptr = phi double* [ %A, %if.then ], [ %ptr.select, %if.else ]
123  br label %loop.header
124
125loop.header:                                        ; preds = %loop.latch, %entry
126  %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop.header ]
127  %iv.next = add nuw nsw i64 %iv, 1
128  %arrayidx = getelementptr inbounds double, double* %A, i64 %iv
129  %v8 = load double, double* %ptr, align 8
130  %mul16 = fmul double 3.0, %v8
131  store double %mul16, double* %arrayidx, align 8
132  %exitcond.not = icmp eq i64 %iv.next, 32000
133  br i1 %exitcond.not, label %exit, label %loop.header
134
135exit:                                             ; preds = %loop.latch
136  ret i32 10
137}
138
139define i32 @store_with_pointer_phi_outside_loop(double* %A, double* %B, double* %C, i1 %c.0, i1 %c.1) {
140; CHECK-LABEL: @store_with_pointer_phi_outside_loop
141; CHECK-NOT: vector.body
142;
143entry:
144  br i1 %c.0, label %if.then, label %if.else
145
146if.then:
147  br label %loop.ph
148
149if.else:
150  %ptr.select = select i1 %c.1, double* %C, double* %B
151  br label %loop.ph
152
153loop.ph:
154  %ptr = phi double* [ %A, %if.then ], [ %ptr.select, %if.else ]
155  br label %loop.header
156
157loop.header:                                        ; preds = %loop.latch, %entry
158  %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop.header ]
159  %iv.next = add nuw nsw i64 %iv, 1
160  %arrayidx = getelementptr inbounds double, double* %A, i64 %iv
161  %v8 = load double, double* %arrayidx, align 8
162  %mul16 = fmul double 3.0, %v8
163  store double %mul16, double* %ptr, align 8
164  %exitcond.not = icmp eq i64 %iv.next, 32000
165  br i1 %exitcond.not, label %exit, label %loop.header
166
167exit:                                             ; preds = %loop.latch
168  ret i32 10
169}
170