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-reduc-9.c
4 ; opt -correlated-propagation -mem2reg -instcombine -loop-simplify -indvars -instnamer vect-reduc-9.s > vect-reduc-9.ll
6 ; ModuleID = 'vect-reduc-9.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 @main.A = internal constant [32 x i16] [i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15, i16 16, i16 28672, i16 28928, i16 29184, i16 29440, i16 29696, i16 29952, i16 30208, i16 30464, i16 32760, i16 32761, i16 32762, i16 32763, i16 32764, i16 32765, i16 32766, i16 32767], align 16
11 @main.B = internal constant [32 x i16] [i16 28672, i16 28928, i16 29184, i16 29440, i16 29696, i16 29952, i16 30208, i16 30464, i16 32760, i16 32761, i16 32762, i16 32763, i16 32764, i16 32765, i16 32766, i16 32767, i16 -32768, i16 -32767, i16 -32766, i16 -32765, i16 -32764, i16 -32763, i16 -32762, i16 -32761, i16 -32760, i16 -32759, i16 -32758, i16 -32757, i16 -32756, i16 -32755, i16 -32754, i16 -32753], align 16
12 @main.C = internal constant [32 x i16] [i16 -1, i16 -2, i16 -3, i16 -4, i16 -5, i16 -6, i16 -7, i16 -8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15, i16 16, i16 -32768, i16 -32767, i16 -32766, i16 -32765, i16 -32764, i16 -32763, i16 -32762, i16 -32761, i16 28672, i16 28928, i16 29184, i16 29440, i16 29696, i16 29952, i16 30208, i16 30464], align 16
14 define void @testmax(i16* %c, i16 zeroext %init, i16 zeroext %result) nounwind uwtable noinline {
16 %lc = alloca [32 x i16], align 16
17 %tmp = bitcast [32 x i16]* %lc to i8*
18 %tmp1 = bitcast i16* %c to i8*
19 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp, i8* %tmp1, i64 64, i32 1, i1 false)
22 for.cond: ; preds = %for.inc, %entry
23 %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ]
24 %accum.0 = phi i16 [ %init, %entry ], [ %cond.in, %for.inc ]
25 %arrayidx = getelementptr [32 x i16]* %lc, i64 0, i64 %indvar
26 %exitcond = icmp ne i64 %indvar, 32
27 br i1 %exitcond, label %for.body, label %for.end
29 for.body: ; preds = %for.cond
30 %tmp6 = load i16* %arrayidx, align 2
31 %cmp8 = icmp ult i16 %accum.0, %tmp6
32 br i1 %cmp8, label %cond.true, label %cond.false
34 cond.true: ; preds = %for.body
35 %tmp13 = load i16* %arrayidx, align 2
38 cond.false: ; preds = %for.body
41 cond.end: ; preds = %cond.false, %cond.true
42 %cond.in = phi i16 [ %tmp13, %cond.true ], [ %accum.0, %cond.false ]
45 for.inc: ; preds = %cond.end
46 %indvar.next = add i64 %indvar, 1
49 for.end: ; preds = %for.cond
50 %accum.0.lcssa = phi i16 [ %accum.0, %for.cond ]
51 %cmp23 = icmp eq i16 %accum.0.lcssa, %result
52 br i1 %cmp23, label %if.end, label %if.then
54 if.then: ; preds = %for.end
55 call void @abort() noreturn nounwind
58 if.end: ; preds = %for.end
62 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
64 declare void @abort() noreturn
66 define void @testmin(i16* %c, i16 zeroext %init, i16 zeroext %result) nounwind uwtable noinline {
68 %lc = alloca [32 x i16], align 16
69 %tmp = bitcast [32 x i16]* %lc to i8*
70 %tmp1 = bitcast i16* %c to i8*
71 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp, i8* %tmp1, i64 64, i32 1, i1 false)
74 for.cond: ; preds = %for.inc, %entry
75 %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ]
76 %accum.0 = phi i16 [ %init, %entry ], [ %cond.in, %for.inc ]
77 %arrayidx = getelementptr [32 x i16]* %lc, i64 0, i64 %indvar
78 %exitcond = icmp ne i64 %indvar, 32
79 br i1 %exitcond, label %for.body, label %for.end
81 for.body: ; preds = %for.cond
82 %tmp6 = load i16* %arrayidx, align 2
83 %cmp8 = icmp ugt i16 %accum.0, %tmp6
84 br i1 %cmp8, label %cond.true, label %cond.false
86 cond.true: ; preds = %for.body
87 %tmp13 = load i16* %arrayidx, align 2
90 cond.false: ; preds = %for.body
93 cond.end: ; preds = %cond.false, %cond.true
94 %cond.in = phi i16 [ %tmp13, %cond.true ], [ %accum.0, %cond.false ]
97 for.inc: ; preds = %cond.end
98 %indvar.next = add i64 %indvar, 1
101 for.end: ; preds = %for.cond
102 %accum.0.lcssa = phi i16 [ %accum.0, %for.cond ]
103 %cmp23 = icmp eq i16 %accum.0.lcssa, %result
104 br i1 %cmp23, label %if.end, label %if.then
106 if.then: ; preds = %for.end
107 call void @abort() noreturn nounwind
110 if.end: ; preds = %for.end
114 define i32 @main() nounwind uwtable {
116 call void @check_vect()
117 call void @testmin(i16* getelementptr inbounds ([32 x i16]* @main.A, i64 0, i64 0), i16 zeroext 10, i16 zeroext 1)
118 call void @testmin(i16* getelementptr inbounds ([32 x i16]* @main.B, i64 0, i64 0), i16 zeroext 32767, i16 zeroext 28672)
119 call void @testmin(i16* getelementptr inbounds ([32 x i16]* @main.C, i64 0, i64 0), i16 zeroext 32767, i16 zeroext 9)
120 call void @testmax(i16* getelementptr inbounds ([32 x i16]* @main.A, i64 0, i64 0), i16 zeroext 0, i16 zeroext 32767)
121 call void @testmax(i16* getelementptr inbounds ([32 x i16]* @main.B, i64 0, i64 0), i16 zeroext 0, i16 zeroext -32753)
122 call void @testmax(i16* getelementptr inbounds ([32 x i16]* @main.C, i64 0, i64 0), i16 zeroext 0, i16 zeroext -1)
126 define internal void @check_vect() nounwind uwtable noinline {
128 %a = alloca i32, align 4
129 %b = alloca i32, align 4
130 %c = alloca i32, align 4
131 %d = alloca i32, align 4
132 %call = call void (i32)* (i32, void (i32)*)* @signal(i32 4, void (i32)* @sig_ill_handler) nounwind
133 %call1 = call i32 @__get_cpuid(i32 1, i32* %a, i32* %b, i32* %c, i32* %d)
134 %tobool = icmp eq i32 %call1, 0
135 br i1 %tobool, label %if.then, label %lor.lhs.false
137 lor.lhs.false: ; preds = %entry
138 %tmp4 = load i32* %d, align 4
139 %and6 = and i32 %tmp4, 67108864
140 %cmp = icmp eq i32 %and6, 0
141 br i1 %cmp, label %if.then, label %if.end
143 if.then: ; preds = %entry, %lor.lhs.false
144 call void @exit(i32 0) noreturn nounwind
147 if.end: ; preds = %lor.lhs.false
148 %call7 = call void (i32)* (i32, void (i32)*)* @signal(i32 4, void (i32)* null) nounwind
152 declare void (i32)* @signal(i32, void (i32)*) nounwind
154 define internal void @sig_ill_handler(i32 %sig) nounwind uwtable {
156 call void @exit(i32 0) noreturn nounwind
159 return: ; No predecessors!
163 define internal i32 @__get_cpuid(i32 %__level, i32* %__eax, i32* %__ebx, i32* %__ecx, i32* %__edx) nounwind uwtable inlinehint {
165 %and = and i32 %__level, -2147483648
166 %call = call i32 @__get_cpuid_max(i32 %and, i32* null)
167 %cmp = icmp ult i32 %call, %__level
168 br i1 %cmp, label %if.then, label %if.end
170 if.then: ; preds = %entry
173 if.end: ; preds = %entry
174 %tmp = call { i32, i32, i32, i32 } asm "cpuid\0A\09", "={ax},={bx},={cx},={dx},0,~{dirflag},~{fpsr},~{flags}"(i32 %__level) nounwind, !srcloc !0
175 %asmresult = extractvalue { i32, i32, i32, i32 } %tmp, 0
176 %asmresult8 = extractvalue { i32, i32, i32, i32 } %tmp, 1
177 %asmresult9 = extractvalue { i32, i32, i32, i32 } %tmp, 2
178 %asmresult10 = extractvalue { i32, i32, i32, i32 } %tmp, 3
179 store i32 %asmresult, i32* %__eax, align 4
180 store i32 %asmresult8, i32* %__ebx, align 4
181 store i32 %asmresult9, i32* %__ecx, align 4
182 store i32 %asmresult10, i32* %__edx, align 4
185 return: ; preds = %if.end, %if.then
186 %retval.0 = phi i32 [ 0, %if.then ], [ 1, %if.end ]
190 declare void @exit(i32) noreturn
192 define internal i32 @__get_cpuid_max(i32 %__ext, i32* %__sig) nounwind uwtable inlinehint {
194 %tmp = call { i32, i32, i32, i32 } asm "cpuid\0A\09", "={ax},={bx},={cx},={dx},0,~{dirflag},~{fpsr},~{flags}"(i32 %__ext) nounwind, !srcloc !1
195 %asmresult = extractvalue { i32, i32, i32, i32 } %tmp, 0
196 %tobool = icmp eq i32* %__sig, null
197 br i1 %tobool, label %if.end, label %if.then
199 if.then: ; preds = %entry
200 %asmresult1 = extractvalue { i32, i32, i32, i32 } %tmp, 1
201 store i32 %asmresult1, i32* %__sig, align 4
204 if.end: ; preds = %entry, %if.then
208 !0 = metadata !{i32 -2147344511, i32 -2147344503}
209 !1 = metadata !{i32 -2147344634, i32 -2147344626}