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 slp-widen-mult-s16.c
4 ; opt -correlated-propagation -mem2reg -instcombine -loop-simplify -indvars -instnamer slp-widen-mult-s16.s > slp-widen-mult-s16.ll
6 ; ModuleID = 'slp-widen-mult-s16.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 @X = global [64 x i16] [i16 0, 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 17, i16 18, i16 19, i16 20, i16 21, i16 22, i16 23, i16 24, i16 25, i16 26, i16 27, i16 28, i16 29, i16 30, i16 31, i16 32, i16 33, i16 34, i16 35, i16 36, i16 37, i16 38, i16 39, i16 40, i16 41, i16 42, i16 43, i16 44, i16 45, i16 46, i16 47, i16 48, i16 49, i16 50, i16 51, i16 52, i16 53, i16 54, i16 55, i16 56, i16 57, i16 58, i16 59, i16 60, i16 61, i16 62, i16 63], align 16
11 @Y = global [64 x i16] [i16 64, i16 63, i16 62, i16 61, i16 60, i16 59, i16 58, i16 57, i16 56, i16 55, i16 54, i16 53, i16 52, i16 51, i16 50, i16 49, i16 48, i16 47, i16 46, i16 45, i16 44, i16 43, i16 42, i16 41, i16 40, i16 39, i16 38, i16 37, i16 36, i16 35, i16 34, i16 33, i16 32, i16 31, i16 30, i16 29, i16 28, i16 27, i16 26, i16 25, i16 24, i16 23, i16 22, i16 21, i16 20, i16 19, i16 18, i16 17, i16 16, i16 15, i16 14, i16 13, i16 12, i16 11, i16 10, i16 9, i16 8, i16 7, i16 6, i16 5, i16 4, i16 3, i16 2, i16 1], align 16
12 @result = common global [64 x i32] zeroinitializer, align 16
14 define i32 @foo1(i32 %len) nounwind uwtable noinline {
18 for.cond: ; preds = %for.inc, %entry
19 %tmp = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
20 %mul = mul i32 %tmp, 2
21 %add1 = add i32 %mul, 1
22 %div = sdiv i32 %len, 2
23 %cmp = icmp slt i32 %tmp, %div
24 br i1 %cmp, label %for.body, label %for.end
26 for.body: ; preds = %for.cond
27 %idxprom = sext i32 %mul to i64
28 %arrayidx = getelementptr inbounds [64 x i16]* @X, i64 0, i64 %idxprom
29 %tmp3 = load i16* %arrayidx, align 4
30 %conv = sext i16 %tmp3 to i32
31 %idxprom6 = sext i32 %mul to i64
32 %arrayidx7 = getelementptr inbounds [64 x i16]* @Y, i64 0, i64 %idxprom6
33 %tmp8 = load i16* %arrayidx7, align 4
34 %conv9 = sext i16 %tmp8 to i32
35 %mul10 = mul nsw i32 %conv, %conv9
36 %idxprom13 = sext i32 %mul to i64
37 %arrayidx14 = getelementptr inbounds [64 x i32]* @result, i64 0, i64 %idxprom13
38 store i32 %mul10, i32* %arrayidx14, align 8
39 %idxprom17 = sext i32 %add1 to i64
40 %arrayidx18 = getelementptr inbounds [64 x i16]* @X, i64 0, i64 %idxprom17
41 %tmp19 = load i16* %arrayidx18, align 2
42 %conv20 = sext i16 %tmp19 to i32
43 %idxprom24 = sext i32 %add1 to i64
44 %arrayidx25 = getelementptr inbounds [64 x i16]* @Y, i64 0, i64 %idxprom24
45 %tmp26 = load i16* %arrayidx25, align 2
46 %conv27 = sext i16 %tmp26 to i32
47 %mul28 = mul nsw i32 %conv20, %conv27
48 %idxprom32 = sext i32 %add1 to i64
49 %arrayidx33 = getelementptr inbounds [64 x i32]* @result, i64 0, i64 %idxprom32
50 store i32 %mul28, i32* %arrayidx33, align 4
53 for.inc: ; preds = %for.body
54 %inc = add nsw i32 %tmp, 1
57 for.end: ; preds = %for.cond
61 define i32 @main() nounwind uwtable {
63 call void @check_vect()
64 %call = call i32 @foo1(i32 64)
67 for.cond: ; preds = %for.inc, %entry
68 %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ]
69 %arrayidx9 = getelementptr [64 x i16]* @Y, i64 0, i64 %indvar
70 %arrayidx5 = getelementptr [64 x i16]* @X, i64 0, i64 %indvar
71 %arrayidx = getelementptr [64 x i32]* @result, i64 0, i64 %indvar
72 %i.0 = trunc i64 %indvar to i32
73 %cmp = icmp slt i32 %i.0, 64
74 br i1 %cmp, label %for.body, label %for.end
76 for.body: ; preds = %for.cond
77 %tmp2 = load i32* %arrayidx, align 4
78 %tmp6 = load i16* %arrayidx5, align 2
79 %conv = sext i16 %tmp6 to i32
80 %tmp10 = load i16* %arrayidx9, align 2
81 %conv11 = sext i16 %tmp10 to i32
82 %mul = mul nsw i32 %conv, %conv11
83 %cmp12 = icmp eq i32 %tmp2, %mul
84 br i1 %cmp12, label %if.end, label %if.then
86 if.then: ; preds = %for.body
87 call void @abort() noreturn nounwind
90 if.end: ; preds = %for.body
93 for.inc: ; preds = %if.end
94 %indvar.next = add i64 %indvar, 1
97 for.end: ; preds = %for.cond
101 define internal void @check_vect() nounwind uwtable noinline {
103 %a = alloca i32, align 4
104 %b = alloca i32, align 4
105 %c = alloca i32, align 4
106 %d = alloca i32, align 4
107 %call = call void (i32)* (i32, void (i32)*)* @signal(i32 4, void (i32)* @sig_ill_handler) nounwind
108 %call1 = call i32 @__get_cpuid(i32 1, i32* %a, i32* %b, i32* %c, i32* %d)
109 %tobool = icmp eq i32 %call1, 0
110 br i1 %tobool, label %if.then, label %lor.lhs.false
112 lor.lhs.false: ; preds = %entry
113 %tmp4 = load i32* %d, align 4
114 %and6 = and i32 %tmp4, 67108864
115 %cmp = icmp eq i32 %and6, 0
116 br i1 %cmp, label %if.then, label %if.end
118 if.then: ; preds = %entry, %lor.lhs.false
119 call void @exit(i32 0) noreturn nounwind
122 if.end: ; preds = %lor.lhs.false
123 %call7 = call void (i32)* (i32, void (i32)*)* @signal(i32 4, void (i32)* null) nounwind
127 declare void @abort() noreturn
129 declare void (i32)* @signal(i32, void (i32)*) nounwind
131 define internal void @sig_ill_handler(i32 %sig) nounwind uwtable {
133 call void @exit(i32 0) noreturn nounwind
136 return: ; No predecessors!
140 define internal i32 @__get_cpuid(i32 %__level, i32* %__eax, i32* %__ebx, i32* %__ecx, i32* %__edx) nounwind uwtable inlinehint {
142 %and = and i32 %__level, -2147483648
143 %call = call i32 @__get_cpuid_max(i32 %and, i32* null)
144 %cmp = icmp ult i32 %call, %__level
145 br i1 %cmp, label %if.then, label %if.end
147 if.then: ; preds = %entry
150 if.end: ; preds = %entry
151 %tmp = call { i32, i32, i32, i32 } asm "cpuid\0A\09", "={ax},={bx},={cx},={dx},0,~{dirflag},~{fpsr},~{flags}"(i32 %__level) nounwind, !srcloc !0
152 %asmresult = extractvalue { i32, i32, i32, i32 } %tmp, 0
153 %asmresult8 = extractvalue { i32, i32, i32, i32 } %tmp, 1
154 %asmresult9 = extractvalue { i32, i32, i32, i32 } %tmp, 2
155 %asmresult10 = extractvalue { i32, i32, i32, i32 } %tmp, 3
156 store i32 %asmresult, i32* %__eax, align 4
157 store i32 %asmresult8, i32* %__ebx, align 4
158 store i32 %asmresult9, i32* %__ecx, align 4
159 store i32 %asmresult10, i32* %__edx, align 4
162 return: ; preds = %if.end, %if.then
163 %retval.0 = phi i32 [ 0, %if.then ], [ 1, %if.end ]
167 declare void @exit(i32) noreturn
169 define internal i32 @__get_cpuid_max(i32 %__ext, i32* %__sig) nounwind uwtable inlinehint {
171 %tmp = call { i32, i32, i32, i32 } asm "cpuid\0A\09", "={ax},={bx},={cx},={dx},0,~{dirflag},~{fpsr},~{flags}"(i32 %__ext) nounwind, !srcloc !1
172 %asmresult = extractvalue { i32, i32, i32, i32 } %tmp, 0
173 %tobool = icmp eq i32* %__sig, null
174 br i1 %tobool, label %if.end, label %if.then
176 if.then: ; preds = %entry
177 %asmresult1 = extractvalue { i32, i32, i32, i32 } %tmp, 1
178 store i32 %asmresult1, i32* %__sig, align 4
181 if.end: ; preds = %entry, %if.then
185 !0 = metadata !{i32 -2147343026, i32 -2147343018}
186 !1 = metadata !{i32 -2147343149, i32 -2147343141}