1 ; RUN: opt %loadPolly %defaultOpts -polly-codegen -enable-polly-vector -dce -S %s | FileCheck %s
2 ; Obtained from C source as:
3 ; clang -S -emit-llvm -O0 vect-double-reduc-3.c
4 ; opt -correlated-propagation -mem2reg -instcombine -loop-simplify -indvars -instnamer vect-double-reduc-3.s > vect-double-reduc-3.ll
6 ; ModuleID = 'vect-double-reduc-3.s'
7 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
8 target triple = "x86_64-unknown-linux-gnu"
10 @check_max = global [32 x i32] [i32 62, i32 63, i32 64, i32 65, i32 66, i32 67, i32 68, i32 69, i32 70, i32 71, i32 72, i32 73, i32 74, i32 75, i32 76, i32 77, i32 78, i32 79, i32 80, i32 81, i32 82, i32 83, i32 84, i32 85, i32 86, i32 87, i32 88, i32 89, i32 90, i32 91, i32 92, i32 93], align 16
11 @check_min = global [32 x i32] [i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31], align 16
12 @in = common global [64 x [32 x i32]] zeroinitializer, align 16
13 @out_max = common global [32 x i32] zeroinitializer, align 16
14 @out_min = common global [32 x i32] zeroinitializer, align 16
15 @coeff = common global [32 x [32 x i32]] zeroinitializer, align 16
17 define void @foo(i32 %x, i32 %y) nounwind uwtable noinline {
21 for.cond: ; preds = %for.inc67, %entry
22 %indvar1 = phi i64 [ %indvar.next2, %for.inc67 ], [ 0, %entry ]
23 %arrayidx66 = getelementptr [32 x i32]* @out_min, i64 0, i64 %indvar1
24 %arrayidx62 = getelementptr [32 x i32]* @out_max, i64 0, i64 %indvar1
25 %exitcond9 = icmp ne i64 %indvar1, 32
26 br i1 %exitcond9, label %for.body, label %for.end70
28 for.body: ; preds = %for.cond
31 for.cond3: ; preds = %for.inc55, %for.body
32 %indvar3 = phi i64 [ %indvar.next4, %for.inc55 ], [ 0, %for.body ]
33 %min.0 = phi i32 [ %y, %for.body ], [ %min.1.lcssa, %for.inc55 ]
34 %max.0 = phi i32 [ %x, %for.body ], [ %max.1.lcssa, %for.inc55 ]
35 %exitcond6 = icmp ne i64 %indvar3, 32
36 br i1 %exitcond6, label %for.body6, label %for.end58
38 for.body6: ; preds = %for.cond3
41 for.cond7: ; preds = %for.inc, %for.body6
42 %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %for.body6 ]
43 %min.1 = phi i32 [ %min.0, %for.body6 ], [ %cond53, %for.inc ]
44 %max.1 = phi i32 [ %max.0, %for.body6 ], [ %cond, %for.inc ]
45 %tmp = add i64 %indvar1, %indvar
46 %arrayidx16 = getelementptr [64 x [32 x i32]]* @in, i64 0, i64 %tmp, i64 %indvar3
47 %exitcond = icmp ne i64 %indvar, 32
48 br i1 %exitcond, label %for.body10, label %for.end
50 for.body10: ; preds = %for.cond7
51 %tmp17 = load i32* %arrayidx16, align 4
52 %cmp18 = icmp slt i32 %max.1, %tmp17
53 br i1 %cmp18, label %cond.true, label %cond.false
55 cond.true: ; preds = %for.body10
56 %tmp27 = load i32* %arrayidx16, align 4
59 cond.false: ; preds = %for.body10
62 cond.end: ; preds = %cond.false, %cond.true
63 %cond = phi i32 [ %tmp27, %cond.true ], [ %max.1, %cond.false ]
64 %tmp38 = load i32* %arrayidx16, align 4
65 %cmp39 = icmp sgt i32 %min.1, %tmp38
66 br i1 %cmp39, label %cond.true40, label %cond.false50
68 cond.true40: ; preds = %cond.end
69 %tmp49 = load i32* %arrayidx16, align 4
72 cond.false50: ; preds = %cond.end
75 cond.end52: ; preds = %cond.false50, %cond.true40
76 %cond53 = phi i32 [ %tmp49, %cond.true40 ], [ %min.1, %cond.false50 ]
79 for.inc: ; preds = %cond.end52
80 %indvar.next = add i64 %indvar, 1
83 for.end: ; preds = %for.cond7
84 %max.1.lcssa = phi i32 [ %max.1, %for.cond7 ]
85 %min.1.lcssa = phi i32 [ %min.1, %for.cond7 ]
88 for.inc55: ; preds = %for.end
89 %indvar.next4 = add i64 %indvar3, 1
92 for.end58: ; preds = %for.cond3
93 %max.0.lcssa = phi i32 [ %max.0, %for.cond3 ]
94 %min.0.lcssa = phi i32 [ %min.0, %for.cond3 ]
95 store i32 %max.0.lcssa, i32* %arrayidx62, align 4
96 store i32 %min.0.lcssa, i32* %arrayidx66, align 4
99 for.inc67: ; preds = %for.end58
100 %indvar.next2 = add i64 %indvar1, 1
103 for.end70: ; preds = %for.cond
107 define i32 @main() nounwind uwtable {
109 call void @check_vect()
112 for.cond: ; preds = %for.inc28, %entry
113 %indvar5 = phi i64 [ %indvar.next6, %for.inc28 ], [ 0, %entry ]
114 %exitcond15 = icmp ne i64 %indvar5, 32
115 br i1 %exitcond15, label %for.body, label %for.end31
117 for.body: ; preds = %for.cond
120 for.cond1: ; preds = %for.inc, %for.body
121 %indvar3 = phi i64 [ %indvar.next4, %for.inc ], [ 0, %for.body ]
122 %tmp16 = add i64 %indvar5, %indvar3
123 %add = trunc i64 %tmp16 to i32
124 %arrayidx10 = getelementptr [64 x [32 x i32]]* @in, i64 0, i64 %indvar3, i64 %indvar5
125 %exitcond = icmp ne i64 %indvar3, 64
126 br i1 %exitcond, label %for.body4, label %for.end
128 for.body4: ; preds = %for.cond1
129 store i32 %add, i32* %arrayidx10, align 4
132 for.inc: ; preds = %for.body4
133 %indvar.next4 = add i64 %indvar3, 1
136 for.end: ; preds = %for.cond1
139 for.cond12: ; preds = %for.inc24, %for.end
140 %indvar9 = phi i64 [ %indvar.next10, %for.inc24 ], [ 0, %for.end ]
141 %arrayidx23 = getelementptr [32 x [32 x i32]]* @coeff, i64 0, i64 %indvar9, i64 %indvar5
142 %tmp12 = add i64 %indvar9, 2
143 %add17 = trunc i64 %tmp12 to i32
144 %exitcond11 = icmp ne i64 %indvar9, 32
145 br i1 %exitcond11, label %for.body15, label %for.end27
147 for.body15: ; preds = %for.cond12
148 store i32 %add17, i32* %arrayidx23, align 4
151 for.inc24: ; preds = %for.body15
152 %indvar.next10 = add i64 %indvar9, 1
155 for.end27: ; preds = %for.cond12
158 for.inc28: ; preds = %for.end27
159 %indvar.next6 = add i64 %indvar5, 1
162 for.end31: ; preds = %for.cond
163 call void @foo(i32 0, i32 0)
166 for.cond32: ; preds = %for.inc50, %for.end31
167 %indvar1 = phi i64 [ %indvar.next2, %for.inc50 ], [ 0, %for.end31 ]
168 %arrayidx47 = getelementptr [32 x i32]* @out_min, i64 0, i64 %indvar1
169 %arrayidx42 = getelementptr [32 x i32]* @check_max, i64 0, i64 %indvar1
170 %arrayidx38 = getelementptr [32 x i32]* @out_max, i64 0, i64 %indvar1
171 %k.0 = trunc i64 %indvar1 to i32
172 %cmp34 = icmp slt i32 %k.0, 32
173 br i1 %cmp34, label %for.body35, label %for.end53
175 for.body35: ; preds = %for.cond32
176 %tmp39 = load i32* %arrayidx38, align 4
177 %tmp43 = load i32* %arrayidx42, align 4
178 %cmp44 = icmp eq i32 %tmp39, %tmp43
179 br i1 %cmp44, label %lor.lhs.false, label %if.then
181 lor.lhs.false: ; preds = %for.body35
182 %tmp48 = load i32* %arrayidx47, align 4
183 %cmp49 = icmp eq i32 %tmp48, 0
184 br i1 %cmp49, label %if.end, label %if.then
186 if.then: ; preds = %lor.lhs.false, %for.body35
187 call void @abort() noreturn nounwind
190 if.end: ; preds = %lor.lhs.false
193 for.inc50: ; preds = %if.end
194 %indvar.next2 = add i64 %indvar1, 1
197 for.end53: ; preds = %for.cond32
198 call void @foo(i32 100, i32 45)
201 for.cond54: ; preds = %for.inc75, %for.end53
202 %indvar = phi i64 [ %indvar.next, %for.inc75 ], [ 0, %for.end53 ]
203 %arrayidx70 = getelementptr [32 x i32]* @out_max, i64 0, i64 %indvar
204 %arrayidx64 = getelementptr [32 x i32]* @check_min, i64 0, i64 %indvar
205 %arrayidx60 = getelementptr [32 x i32]* @out_min, i64 0, i64 %indvar
206 %k.1 = trunc i64 %indvar to i32
207 %cmp56 = icmp slt i32 %k.1, 32
208 br i1 %cmp56, label %for.body57, label %for.end78
210 for.body57: ; preds = %for.cond54
211 %tmp61 = load i32* %arrayidx60, align 4
212 %tmp65 = load i32* %arrayidx64, align 4
213 %cmp66 = icmp eq i32 %tmp61, %tmp65
214 br i1 %cmp66, label %lor.lhs.false67, label %if.then73
216 lor.lhs.false67: ; preds = %for.body57
217 %tmp71 = load i32* %arrayidx70, align 4
218 %cmp72 = icmp eq i32 %tmp71, 100
219 br i1 %cmp72, label %if.end74, label %if.then73
221 if.then73: ; preds = %lor.lhs.false67, %for.body57
222 call void @abort() noreturn nounwind
225 if.end74: ; preds = %lor.lhs.false67
228 for.inc75: ; preds = %if.end74
229 %indvar.next = add i64 %indvar, 1
232 for.end78: ; preds = %for.cond54
236 define internal void @check_vect() nounwind uwtable noinline {
238 %a = alloca i32, align 4
239 %b = alloca i32, align 4
240 %c = alloca i32, align 4
241 %d = alloca i32, align 4
242 %call = call void (i32)* (i32, void (i32)*)* @signal(i32 4, void (i32)* @sig_ill_handler) nounwind
243 %call1 = call i32 @__get_cpuid(i32 1, i32* %a, i32* %b, i32* %c, i32* %d)
244 %tobool = icmp eq i32 %call1, 0
245 br i1 %tobool, label %if.then, label %lor.lhs.false
247 lor.lhs.false: ; preds = %entry
248 %tmp4 = load i32* %d, align 4
249 %and6 = and i32 %tmp4, 67108864
250 %cmp = icmp eq i32 %and6, 0
251 br i1 %cmp, label %if.then, label %if.end
253 if.then: ; preds = %entry, %lor.lhs.false
254 call void @exit(i32 0) noreturn nounwind
257 if.end: ; preds = %lor.lhs.false
258 %call7 = call void (i32)* (i32, void (i32)*)* @signal(i32 4, void (i32)* null) nounwind
262 declare void @abort() noreturn
264 declare void (i32)* @signal(i32, void (i32)*) nounwind
266 define internal void @sig_ill_handler(i32 %sig) nounwind uwtable {
268 call void @exit(i32 0) noreturn nounwind
271 return: ; No predecessors!
275 define internal i32 @__get_cpuid(i32 %__level, i32* %__eax, i32* %__ebx, i32* %__ecx, i32* %__edx) nounwind uwtable inlinehint {
277 %and = and i32 %__level, -2147483648
278 %call = call i32 @__get_cpuid_max(i32 %and, i32* null)
279 %cmp = icmp ult i32 %call, %__level
280 br i1 %cmp, label %if.then, label %if.end
282 if.then: ; preds = %entry
285 if.end: ; preds = %entry
286 %tmp = call { i32, i32, i32, i32 } asm "cpuid\0A\09", "={ax},={bx},={cx},={dx},0,~{dirflag},~{fpsr},~{flags}"(i32 %__level) nounwind, !srcloc !0
287 %asmresult = extractvalue { i32, i32, i32, i32 } %tmp, 0
288 %asmresult8 = extractvalue { i32, i32, i32, i32 } %tmp, 1
289 %asmresult9 = extractvalue { i32, i32, i32, i32 } %tmp, 2
290 %asmresult10 = extractvalue { i32, i32, i32, i32 } %tmp, 3
291 store i32 %asmresult, i32* %__eax, align 4
292 store i32 %asmresult8, i32* %__ebx, align 4
293 store i32 %asmresult9, i32* %__ecx, align 4
294 store i32 %asmresult10, i32* %__edx, align 4
297 return: ; preds = %if.end, %if.then
298 %retval.0 = phi i32 [ 0, %if.then ], [ 1, %if.end ]
302 declare void @exit(i32) noreturn
304 define internal i32 @__get_cpuid_max(i32 %__ext, i32* %__sig) nounwind uwtable inlinehint {
306 %tmp = call { i32, i32, i32, i32 } asm "cpuid\0A\09", "={ax},={bx},={cx},={dx},0,~{dirflag},~{fpsr},~{flags}"(i32 %__ext) nounwind, !srcloc !1
307 %asmresult = extractvalue { i32, i32, i32, i32 } %tmp, 0
308 %tobool = icmp eq i32* %__sig, null
309 br i1 %tobool, label %if.end, label %if.then
311 if.then: ; preds = %entry
312 %asmresult1 = extractvalue { i32, i32, i32, i32 } %tmp, 1
313 store i32 %asmresult1, i32* %__sig, align 4
316 if.end: ; preds = %entry, %if.then
320 !0 = metadata !{i32 -2147342812, i32 -2147342804}
321 !1 = metadata !{i32 -2147342935, i32 -2147342927}